This question already has an answer here:
Change div order with CSS depending on device-width
(1 answer)
Closed 4 years ago.
I have three columns; left, middle and right and they are in a div that is 100% width of the screen. How in a media query, when the screen size is reduced, can I get the middle column to stay on the top, the left column to go underneath and then the right column to go underneath that? I've attached a CodePen as well as displaying the HTML and CSS below: https://codepen.io/Macast/pen/jZworE . Any help will be greatly appreciated! I have no idea how to go about this.
This is what I'm looking for:
HTML:
<body>
<div class="columnContainer">
<div class="leftColumn" style="background-color:#aaa;">
<h2>Left Column</h2>
</div>
<div class="middleColumn" style="background-color:#bbb;">
<h2>Middle Column</h2>
</div>
<div class="rightColumn" style="background-color:#ccc;">
<h2>Right Column</h2>
</div>
</div>
</body>
</html>
CSS:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.columnContainer {
width: 100%;
}
.leftColumn {
float: left;
width: 33.33%;
padding: 10px;
height: 200px;
text-align: center;
}
.middleColumn {
float: left;
width: 33.33%;
padding: 10px;
height: 200px;
text-align: center;
}
.rightColumn {
float: left;
width: 33.33%;
padding: 10px;
height: 200px;
text-align: center;
}
.columnContainer:after {
content: "";
display: table;
clear: both;
}
/* Media Query */
#media (min-width: 320px) and (max-width: 480px) {
/* Column Stacking Here */
}
You can use flex + order;
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.columnContainer {
width: 100%;
display: flex;
}
.leftColumn {
width: 33.33%;
padding: 10px;
height: 200px;
margin: 0 auto;
text-align: center;
}
.middleColumn {
width: 33.33%;
padding: 10px;
height: 200px;
margin: 0 auto;
text-align: center;
}
.rightColumn {
width: 33.33%;
padding: 10px;
height: 200px;
margin: 0 auto;
text-align: center;
}
/* Media Query */
#media (min-width: 320px) and (max-width: 480px) {
/* Column Stacking Here */
.columnContainer {
flex-direction: column;
}
.leftColumn {
order: 2;
}
.middleColumn {
order: 1;
}
.rightColumn {
order: 3;
}
}
<body>
<div class="columnContainer">
<div class="leftColumn" style="background-color:#aaa;">
<h2>Left Column</h2>
</div>
<div class="middleColumn" style="background-color:#bbb;">
<h2>Middle Column</h2>
</div>
<div class="rightColumn" style="background-color:#ccc;">
<h2>Right Column</h2>
</div>
</div>
</body>
</html>
/* Media Query */
#media (max-width: 480px) {
.leftColumn, .middleColumn, .rightColumn {
float: left;
width: 100%;
padding: 10px;
height: 200px;
text-align: center;
}
}
Related
I have an example of a simple grid in which when the screen size is less than 767 pixels, all blocks stretch to fill the screen.
Section 2 moves to the very bottom when this size (767 pixels) is reached. And I have something like this: Section 1, footer, section 2. Is it possible to somehow make section 2 at the very top? (section 2, section 1, footer)
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
width: 100%;
padding: 0 0px;
margin: 0 auto;
}
.leftcolumn {
float: left;
width: 65%;
}
.rightcolumn {
float: left;
width: 35%;
padding-left: 20px;
}
.row:after {
content: "";
display: table;
margin-top: 20px;
}
.footer {
padding: 20px;
text-align: center;
background: rgba(221, 221, 221, 0.3);
margin-top: 20px;
}
#media screen and (max-width: 767px) {
.leftcolumn, .rightcolumn {
width: 100%;
padding: 0;
}
}
<div class="wrapper">
<div class="row">
<div class="leftcolumn">
1 section
<div class="footer">
footer
</div>
</div>
<div class="rightcolumn">
2 section
</div>
</div>
</div>
Here is what I have now:
Here is what I want to get:
I did these changes in your code:
Use grid instead float. Then set grid-column and grid-row for grid items. Then change these for screen size smaller than 768px.
Note also I changed your HTML for this purpose:
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
width: 100%;
padding: 0 0px;
margin: 0 auto;
}
.row {
display: grid;
grid-template-columns: 65% 35%;
}
.rightcolumn {
grid-column: 2 / 3;
padding-left: 20px;
}
.row:after {
content: "";
display: table;
margin-top: 20px;
}
.footer {
grid-row: 2 / 3;
padding: 20px;
text-align: center;
background: rgba(221, 221, 221, 0.3);
margin-top: 20px;
}
#media screen and (max-width: 767px) {
.row {
grid-template-columns: 100%;
}
.rightcolumn {
grid-row: 1 / 2;
grid-column: 1 / 2;
padding-left: 0;
}
.footer{
grid-row: 3 / 4;
}
}
<div class="wrapper">
<div class="row">
<div class="leftcolumn">
1 section
</div>
<div class="footer">
footer
</div>
<div class="rightcolumn">
2 section
</div>
</div>
</div>
You can simply do it by using flexbox and a little bit of change in your html code.
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
width: 100%;
border: 2px solid blue;
padding: 0 0px;
margin: 0 auto;
}
.left {
width: 65%;
}
.rightcolumn {
width: 35%;
padding-left: 20px;
}
.row {
display: flex;
justify-content: space-between;
}
.footer {
padding: 20px;
width: 100%;
text-align: center;
background: rgba(221, 221, 221, 0.3);
margin-top: 20px;
}
#media screen and (max-width: 767px) {
.row {
flex-direction: column;
}
.left,
.rightcolumn {
width: 100%;
padding: 0;
}
.left {
order: 2;
}
.rightcolumn {
order: 1;
}
}
<div class="wrapper">
<div class="row">
<div class="left">
<div class="leftcolumn">
1 section
</div>
<div class="footer">
footer
</div>
</div>
<div class="rightcolumn">
2 section
</div>
</div>
</div>
You can set the width of .footer div according to your preference above 767 pixels, I have set it 100%;
How would I make it so the image resizes properly when viewed on smaller screens. Right now, the image is over the container when viewed on smaller screens. There are also small gaps between the top/left of the container and the image. Would I have to resize the image in the media query or expand the width of my container in the media query?
.container {
width: 88%;
margin: 50px auto;
margin-top: 0px;
}
.heading {
text-align: center;
font-size: 30px;
margin-bottom: 50px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-around;
flex-flow: wrap;
}
.card {
width: 30%;
background: #fff;
border: 1px solid #ccc;
margin-bottom: 50px;
}
.image {
width: fit-content;
height: fit-content;
}
.card-body {
padding: 30px 10px;
text-align: left;
font-size: 18px;
}
.card-body .btn {
display: block;
color: #fff;
text-align: center;
background: black;
margin-top: 30px;
text-decoration: none;
padding: 10px 5px;
}
#media screen and (max-width: 1000px) {
.card {
width: 40%;
}
.heading {
text-align: auto;
}
.card-header {
margin: auto;
}
.image {
width: fit-content;
height: fit-content;
}
}
#media screen and (max-width: 620px) {
.container {
width: 100%;
}
.heading {
padding: 20px;
font-size: 20px;
text-align: auto;
}
.card {
width: 80%;
}
.image {
width: fit-content;
height: fit-content;
}
}
<div class="container">
<div class="heading">
<h1>Latest Posts</h1>
</div>
<div class="row">
<div class="card">
<div class="image">
<img src="https://via.placeholder.com/1920x1080.jpg">
</div>
<div class="card-body">
<p>
Text Here
</p>
Read more
</div>
</div>
I typically put width: 100%; on images in my projects and height: auto this way the image will be more responsive and scale up and down. You can reduce the width for the smaller media query if you want an even smaller image (width: 85%; for example) or I would probably personally end up reducing the width of the container to get the desired result.
1st: Remove your CSS for the class .image
2nd: Add this CSS line to the base-css (not within the media queries):
img {
object-fit: contain;
width: 100%;
}
What will that do?
object-fit: contain will keep the image aspect ratio while width: 100% will cause the image to fit exactly the given space. The height is set automatically according to the width while it maintain the image aspect ratio as mentioned above.
.container {
width: 88%;
margin: 50px auto;
margin-top: 0px;
}
.heading {
text-align: center;
font-size: 30px;
margin-bottom: 50px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-around;
flex-flow: wrap;
}
.card {
width: 30%;
background: #fff;
border: 1px solid #ccc;
margin-bottom: 50px;
}
.image {
width: fit-content;
height: fit-content;
}
.card-body {
padding: 30px 10px;
text-align: left;
font-size: 18px;
}
.card-body .btn {
display: block;
color: #fff;
text-align: center;
background: black;
margin-top: 30px;
text-decoration: none;
padding: 10px 5px;
}
img {
object-fit: contain;
width: 100%;
}
#media screen and (max-width: 1000px) {
.card {
width: 40%;
}
.heading {
text-align: auto;
}
.card-header {
margin: auto;
}
}
#media screen and (max-width: 620px) {
.container {
width: 100%;
}
.heading {
padding: 20px;
font-size: 20px;
text-align: auto;
}
.card {
width: 80%;
}
}
<div class="container">
<div class="heading">
<h1>Latest Posts</h1>
</div>
<div class="row">
<div class="card">
<div class="image">
<img src="https://via.placeholder.com/1920x1080.jpg">
</div>
<div class="card-body">
<p>
Text Here
</p>
Read more
</div>
</div>
I want to center the divs how I currently have them, but the issue is that when there are two divs they are not aligning with the rectangle above. I know that they would align with justify-content:space between, but that would prevent a div from being centered when it is the only one in the row. Is it possible what I want to do?
.wrapper {
max-width: 1000px;
margin: 0 auto
}
.title {
width: 100%;
height: 100px;
background: green;
margin-bottom: 30px;
}
.outer {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.col {
/* flex-grow, flex-shrink, flex-basis*/
flex: 0 0 31%;
margin: 0 1% 2% 1%;
height: 300px;
}
.col1 {
background-color: red;
}
.col2 {
background-color: blue
}
.col3 {
background: black;
}
#media only screen and (max-width: 960px) {
.col {
flex: 0 0 48%;
}
}
#media only screen and (max-width: 480px) {
.col {
flex: 0 0 100%;
}
}
<div class="wrapper">
<div class="title">
</div>
<div class="outer">
<div class="col col1">
</div>
<div class="col col2">
</div>
<div class="col col3">
</div>
</div>
</div>
You can set a margin-left: auto to the .col1 and margin-right: auto to the .col2to push the divs respectively.
.wrapper {
max-width: 1000px;
margin: 0 auto
}
.title {
width: 100%;
height: 100px;
background: green;
margin-bottom: 30px;
}
.outer {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.col {
/* flex-grow, flex-shrink, flex-basis*/
flex: 0 0 31%;
margin: 1% 0 2% 0;
height: 300px;
}
.col1 {
background-color: red;
margin-right: auto;
}
.col2 {
background-color: blue;
margin-left: auto;
}
.col3 {
background: black;
}
#media only screen and (max-width: 960px) {
.col {
flex: 0 0 48%;
}
}
#media only screen and (max-width: 480px) {
.col {
flex: 0 0 100%;
}
}
<div class="wrapper">
<div class="title">
</div>
<div class="outer">
<div class="col col1">
</div>
<div class="col col2">
</div>
<div class="col col3">
</div>
</div>
</div>
How to divide a webpage into four equal parts using flex box? Something like this website- www.rileyjshaw.com
The columns should be able to stack upon one another on smaller view ports.
Edit/ Update:
So far I've tried this-
Should I change the line height? How can I achieve distinct blocks?
/* Grid */
.column {
flex-basis: 100%;
width: 50%;
height: 50%;
line-height: 200px;
}
#media screen and (min-width: 800px) {
.row {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.column {
flex: 1;
}
._25 {
flex: 2.5;
}
._5 {
flex: 5;
}
}
/* Style */
body {
font-family: 'Lato', sans-serif;
font-size: 1.3em;
color: #ccc;
background: #000;
/*margin-bottom: 70px;*/
}
.column {
/* padding: 15px;
border: 1px solid #666;
margin: 5px 0;*/
background: #343436;
}
main {
max-width: 1200px;
margin: 0 auto;
}
h1,
h2 {
text-align: center;
}
<div class="row">
<div class="column">
50%
</div>
<div class="column">
50%
</div>
</div>
<div class="row">
<div class="column">
50%
</div>
<div class="column">
50%
</div>
</div>
You can simplify the code and gain the wanted output. Here I removed the row's and used a container. The main benefit with this structure is that you can alter the order of the column's if you find that necessary.
I also choose to use flex-basis instead of flex-grow to make them stay 50% wide no matter their content size.
On wider screens, using the media query, set the column's 50% wide and the container to display: flex; flex-wrap: wrap;.
On narrower screens, and being block elements, they stack on top of each other by default
html, body {
height: 100%;
margin: 0;
}
.container {
height: 100%;
}
.column {
height: 25%;
}
#media screen and (min-width: 600px) {
.container {
display: flex;
flex-wrap: wrap;
}
.column {
flex-basis: 50%;
height: 50%;
}
}
/* general styles */
body {
font-family: 'Lato', sans-serif;
font-size: 1.3em;
color: #ccc;
background: #000;
/*margin-bottom: 70px;*/
}
.column {
padding: 15px;
/*border: 1px solid #666;*/
box-sizing: border-box;
}
.column:nth-child(1) {
background: #5c9;
}
.column:nth-child(2) {
background: #fb0;
}
.column:nth-child(3) {
background: #39f;
}
.column:nth-child(4) {
background: #f33;
}
main {
max-width: 1200px;
margin: 0 auto;
}
h1,
h2 {
text-align: center;
}
<div class="container">
<div class="column">
50%
</div>
<div class="column">
50%
</div>
<div class="column">
50%
</div>
<div class="column">
50%
</div>
</div>
If you still need the original markup structure, here is a sample with that too
html, body {
height: 100%;
margin: 0;
}
.row {
height: 50%;
}
.column {
height: 50%;
}
#media screen and (min-width: 600px) {
.row {
display: flex;
}
.column {
flex-basis: 50%;
height: 100%;
}
}
/* general styles */
body {
font-family: 'Lato', sans-serif;
font-size: 1.3em;
color: #ccc;
background: #000;
/*margin-bottom: 70px;*/
}
.column {
padding: 15px;
/*border: 1px solid #666;*/
box-sizing: border-box;
}
.row:nth-child(1) .column:nth-child(1) {
background: #5c9;
}
.row:nth-child(1) .column:nth-child(2) {
background: #fb0;
}
.row:nth-child(2) .column:nth-child(1) {
background: #39f;
}
.row:nth-child(2) .column:nth-child(2) {
background: #f33;
}
main {
max-width: 1200px;
margin: 0 auto;
}
h1,
h2 {
text-align: center;
}
<div class="row">
<div class="column">
50%
</div>
<div class="column">
50%
</div>
</div>
<div class="row">
<div class="column">
50%
</div>
<div class="column">
50%
</div>
</div>
Updated based on a comment
Centering the column's content can be done with i.e.:
Flexbox - https://jsfiddle.net/0ns6ofcp/
.column {
height: 25%;
display: flex; /* added */
justify-content: center; /* hor. center */
align-items: center; /* ver. center */
}
Transform - https://jsfiddle.net/0ns6ofcp/1/
<div class="column">
<div>50%</div>
</div>
.column {
position: relative; /* added property */
height: 25%;
}
.column > div { /* added rule */
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
Here is something you can start with:
/* Grid */
.column {
flex-basis: 100%;
height: 50vh;
}
.row {
display: flex;
}
.row:first-child .column:first-child {
background: red;
}
.row:first-child .column:last-child {
background: blue;
}
.row:last-child .column:first-child {
background: green;
}
.row:last-child .column:last-child {
background: black;
}
/* Style */
body {
font-family: 'Lato', sans-serif;
font-size: 1.3em;
color: #ccc;
background: #000;
}
.column {
background: #343436;
}
<div>
<div class="row">
<div class="column">
50%
</div>
<div class="column">
50%
</div>
</div>
<div class="row">
<div class="column">
50%
</div>
<div class="column">
50%
</div>
</div>
</div>
I currently have a widget looking how I want it to a large screen, but have problems when reducing it to something mobile friendly.
The widget has a title section which was two additional fields which need to be floated to right, and only take up as much width as there is text inside of them. I need the title-text on the left to take up the rest of the remaining space.
this is what it looks like
my HTML looks something like this:
<div class="widget">
<div class="section-title">
<div class="title-info">
<div class="info-2">Info 2</div>
<div class="info-1">Info 1</div>
</div>
<div class="title-text">Title</div>
</div>
</div>
CSS looks like this:
.section-title {
height: 100%;
font-size: 1.3em;
color: white;
}
.section-title .title-text {
background-color: #3261AD;
padding: 20px;
}
.section-title .title-info {
display: inline-block;
float: right;
}
.section-title .info-1{
background-color: #264D8C;
padding: 20px;
display: inline-block;
float: right;
}
.section-title .info-2{
background-color: #5BB75B;
padding: 20px;
display: inline-block;
float: right;
}
#media (max-width: 420px) {
.section-title .title-text {
/* ??? */
display: block;
width: 100%;
float: left;
}
.section-title .title-info {
/* ??? */
display: block;
width: 100%;
}
}
The problem occurs when I try to reduce the screen width. I'd like the title-info to collapse beneath the title-text, but can't switch the divs around because then the divs don't float to the right in the order that I want. Is there a way of it look like the image below without sacrificing how it looks on full width or creating a separate markup for mobile?
How I want it to look on mobile
https://jsfiddle.net/cpc4c3kt/
.section-title {
height: 100%;
font-size: 1.3em;
color: white;
}
.section-title .title-text {
background-color: #3261AD;
padding: 20px;
}
.section-title .title-info {
display: inline-block;
float: right;
}
.section-title .info-1 {
background-color: #264D8C;
padding: 20px;
display: inline-block;
float: right;
}
.section-title .info-2 {
background-color: #5BB75B;
padding: 20px;
display: inline-block;
float: right;
}
#media (max-width: 420px) {
.section-title .title-text {
/* ??? */
display: block;
width: 80%;
padding:20px 10%;
float: left;
transform: translateY(-100%);
}
.section-title .title-info {
/* ??? */
display: block;
width: 100%;
transform: translateY(100%);
}
.section-title .title-info>div {
display: inline-block;
float: right;
width: 40%;
padding: 5%;
}
}
<div class="widget">
<div class="section-title">
<div class="title-info">
<div class="info-2">Info 2</div>
<div class="info-1">Info 1</div>
</div>
<div class="title-text">Title</div>
</div>
</div>
Try using Flexbox Grid Layout. Flexbox Layout Module is inbuilt in CSS3 so you don't have to import any CSS. I find it easier to use in positioning complex element layouts.
.section-title {
display: inline-flex;
justify-content: flex-start;
flex-flow: row nowrap;
font-size: 1.3em;
color: white;
width: 100%;
}
.title-text {
flex-basis: 70%;
background: #3261AD;
order: 1;
padding: 20px;
}
.title-info {
flex-basis: 30%;
order: 2;
display: inline-flex;
flex-flow: row nowrap;
}
.info-1 {
background: #264D8C;
order: 1;
flex-basis: 50%;
padding: 20px;
}
.info-2 {
background: #5BB75B;
order: 2;
flex-basis: 50%;
padding: 20px;
}
#media all and (max-width: 420px) {
.section-title {
flex-wrap: wrap;
}
.title-info {
flex-wrap: nowrap;
flex-basis: 100%;
}
.title-text {
flex-basis: 100%;
}
.info-1 {
flex-basis: 50%;
}
.info-2 {
flex-basis: 50%;
}
}
<div class="widget">
<div class="section-title">
<div class="title-info">
<div class="info-2">Info 2</div>
<div class="info-1">Info 1</div>
</div>
<div class="title-text">Title</div>
</div>
</div>
https://jsfiddle.net/yz93799v/