Make a 2 column responsive breakpoint from rows of 3 columns - css

I have two rows containing tree columns each. On a Responsive breakpoint, I'd like to switch to tree lines of two columns.
Due to the initial structure, this does not seem possible (I can only make 1 colum rows, or tree column rows, bot not two column rows).
No JS please...
How is this usually solved? DEMO HERE
CSS
.col {
float: left;
width: 33.33%;
background: red;
text-align: center;
}
#media (max-width:500px) {
.col {
width: 50%;
}
}
HTML
<div class="row" style="overflow:auto;">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
<div class="row" style="overflow:auto;">
<div class="col">4</div>
<div class="col">5</div>
<div class="col">6</div>
</div>

Try this code
.contain {
display: flex;
flex-wrap: wrap;
}
.col {
flex: 1;
min-width: 33%;
}
#media (max-width:500px) {
.col {
min-width: 50%;
}
}
<div class="contain">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
<div class="col">5</div>
<div class="col">6</div>
</div>

Related

How can I make a responsive css grid (display: grid) that has three equal boxes on the top row and then the rest of the rows are two equal size boxes?

I want to make a responsive css grid that looks like this:
box | box | box
b o x | b o x
b o x | b o x
and then when the screen size gets small enough, all of the columns collapse into a single column with each box on its own row.
Is this possible?
Edit:
For anyone who has this issue, changing the number of columns via media query from 6 to 1 was not working. However, I had the idea to make all of the items span 6 columns at the break point and that worked perfectly. This is an addition to the answer given by lawrence-witt and paulie-d.
By using a SIX column grid
.item {
height: 3em;
border: 2px solid green;
}
.container {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-gap: 4px;
width: 90%;
margin: 1em auto;
}
.item:nth-child(1),
.item:nth-child(2),
.item:nth-child(3) {
grid-column: span 2
}
.item:nth-child(4),
.item:nth-child(5) {
grid-column: span 3;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
After that it's just a matter of adding a media query to collapse the grid to a single column at the appropriate breakpoint,
Here is one way to do it using the nth-child feature. To make the grid responsive you simply add a media query that changes the styling of cells and grid at a certain screen width.
.grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
}
.cell {
border: 1px solid black;
grid-column: span 3;
}
.cell:nth-child(1),
.cell:nth-child(2),
.cell:nth-child(3){
grid-column: span 2;
}
<div class="grid">
<div class="cell">One</div>
<div class="cell">Two</div>
<div class="cell">Three</div>
<div class="cell">Four</div>
<div class="cell">Five</div>
<div class="cell">Six</div>
<div class="cell">Seven</div>
</div>
By using CSS flex layout and CSS media query you can achieve your need. See the below code, if the screen size reduced to 600px then it will change to single column layout.
.container {
display: flex;
width: 100%;
justify-content: space-between;
flex-direction: row;
margin-bottom: 10px;
}
.three-box-row > div {
width: 33%;
height: 50px;
}
.two-box-row > div {
width: 49%;
height: 50px;
}
#media only screen and (max-width: 600px) {
.container {
flex-direction: column;
}
.container > div {
width: 100%;
}
}
<body>
<div class="three-box-row container">
<div style="background-color: red;">Box 1</div>
<div style="background-color: green;">Box 2</div>
<div style="background-color: blue;">Box 3</div>
</div>
<div class="two-box-row container">
<div style="background-color: red;">Box 1</div>
<div style="background-color: green;">Box 2</div>
</div>
<div class="two-box-row container">
<div style="background-color: green;">Box 1</div>
<div style="background-color: blue;">Box 2</div>
</div>
</body>

Change div order on foundation/bootstrap part of row

I have a design where I have 3 divs.
On desktop mode - 2 divs are in the same row, and on mobile mode each of them is a full row, but the order needs to change.
For example this is my HTML (using foundation CSS):
<div class="row">
<div class="mobile-first small-12 large-8 columns">FIRST</div>
<div class="mobile-last small-12 large-4 columns">LAST</div>
</div>
<div class="row">
<div class="mobile-middle large-12 small-12">MIDDLE</div>
</div>
What needs to happen when I am on mobile screen is that the "LAST" div will go last, even though it is part of the first row.
Is it possible without duplicating the HTML, using JS or using strange float that will act strange on some devices?
This is the fiddle I've made:
Fiddle
You can wrap mobile-first and mobile-middle divs into an additional column. Then apply negative margin-right to the mobile-middle div on the wide screen.
Please check the result:
1) Bootstrap
https://jsfiddle.net/glebkema/ss8zbf6z/
#import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');
.container {
margin: 0 auto;
max-width: 500px;
}
[class|="mobile"] {
height: 100px;
}
.mobile-first { background-color: blue; }
.mobile-last { background-color: red; }
.mobile-middle { background-color: green; }
#media (min-width: 992px) {
.mobile-middle {
margin-right: -33.33333333% !important;
width: 150% !important;
}
}
<div class="container">
<div class="row">
<div class="col-md-8">
<div class="row">
<div class="mobile-first col-xs-12">FIRST</div>
<div class="mobile-middle col-xs-12">MIDDLE</div>
</div>
</div>
<div class="mobile-last col-md-4">LAST</div>
</div>
</div>
2) Foundation
https://jsfiddle.net/glebkema/sbzgwf8t/
.container {
margin: 0 auto;
max-width: 500px;
}
[class|="mobile"] {
height: 100px;
}
.mobile-first { background-color: blue; }
.mobile-last { background-color: red; }
.mobile-middle { background-color: green; }
#media screen and (min-width: 64em) {
.mobile-middle {
margin-right: -33.33333% !important;
width: 150% !important;
}
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.2.3/foundation.css">
<div class="container">
<div class="row">
<div class="small-12 large-8 columns">
<div class="row">
<div class="mobile-first small-12 columns">FIRST</div>
</div>
<div class="row">
<div class="mobile-middle small-12 columns">MIDDLE</div>
</div>
</div>
<div class="mobile-last small-12 large-4 columns">LAST</div>
</div>
</div>
As per #moped suggest. I can use same row div for all the colums.
The solution is simple if they are all in the same div, I can use display: flex.
#media only screen and (max-width: 768px) {
.row {
display: flex;
flex-direction: column;
}
.mobile-first{
order: 1;
}
.mobile-last{
order: 3;
}
.mobile-middle{
order: 2;
}
updated fiddle

Can 2 columns of nested divs be merged into a single column and then re-ordered using CSS?

So, I'm pretty certain it's not possible to do the following, but thought I'd ask anyway!
I've got 2 columns of content on my website design. Both have a wrapper div, floated, so they sit side by side. This looks fine on the desktop layout, and on the mobile (responsive) layout they currently both fill out to 100% width, and stack on top of each other.
What I'd really like to do is change the order of the nested divs inside each floated wrapper on the mobile layout so that, essentially, the two columns merge into one single column and the nested divs ordering changes as below:
DESKTOP
1 5
2 6
3 7
4 8
MOBILE
1
5
2
3
6
7
8
4
Hope this is clear enough! I know I can use flexboxes to change the order on the mobile layout, but as far as I can get is to change the order only within each individual wrapper div. Have also tried floating the nested divs in various ways on the desktop layout, but to no avail.
EDIT:
Apologies, I should have pasted my code, either:
<div id="container">
<div class="wrapper-left">
<div class="divInside div1">1</div>
<div class="divInside div2">2</div>
<div class="divInside div3">3</div>
<div class="divInside div4">4</div>
</div>
<div class="wrapper-right">
<div class="divInside div5">5</div>
<div class="divInside div6">6</div>
<div class="divInside div7">7</div>
<div class="divInside div8">8</div>
</div>
</div>
or
<div id="container">
<div class="wrapper">
<div class="divInside div1">1</div>
<div class="divInside div2">2</div>
<div class="divInside div3">3</div>
<div class="divInside div4">4</div>
<div class="divInside div5">5</div>
<div class="divInside div6">6</div>
<div class="divInside div7">7</div>
<div class="divInside div8">8</div>
</div>
</div>
Also here's an image to illustrate what I'm after. Sincere apologies, it's my first question here!
After the feedback on the comments, I change my answer using flexbox and order property as you point in your question that you have tried before. You do not need two wrappers to get it, instead.
html,body{
width: 100%;
height: 100%;
margin: 0;
}
#container{
width: 100%;
height: 100%;
}
.wrapper{
display: flex;
flex-wrap: wrap;
width: 100%;
height: 100%;
}
.red{
background-color: red;
}
.yellow{
background-color: yellow;
}
.divInside{
border: 1px solid;
height: 25%;
width: 50%;
flex-basis: 49%;
}
.div1{
order: 1;
}
.div2{
order: 3;
}
.div3{
order: 5;
}
.div4{
order: 7;
}
.div5{
order: 2;
}
.div6{
order: 4;
}
.div7{
order: 6;
}
.div8{
order: 8;
}
#media screen and (max-width: 400px){
.wrapper{
width: 100%;
}
.divInside{
flex-basis: 100%;
}
.div3{
order: 4;
}
.div4{
order: 8;
}
.div8{
order: 7;
}
}
<div id="container">
<div class="wrapper">
<div class="divInside div1">1</div>
<div class="divInside div2">2</div>
<div class="divInside div3">3</div>
<div class="divInside div4">4</div>
<div class="divInside div5">5</div>
<div class="divInside div6">6</div>
<div class="divInside div7">7</div>
<div class="divInside div8">8</div>
</div>
</div>
It would be simple to solve this if you set the HTML to a css table structure (display:table-row; and display:table-cell;) setting the desired values for the Desktop format.
Then, using media queries you just set these display properties on the desktop size, and when it goes to mobile size it will stack one on top of the other:
.main > div > div {
border: 1px solid silver;
}
#media (min-width: 400px) {
.main {
display: table;
width: 100%;
}
.main > div {
display: table-row;
}
.main > div > div {
display: table-cell;
}
}
<div class='main'>
<div>
<div>1</div>
<div>5</div>
</div>
<div>
<div>2</div>
<div>6</div>
</div>
<div>
<div>3</div>
<div>7</div>
</div>
<div>
<div>4</div>
<div>8</div>
</div>
</div>
Note: Firefox ONLY Solution
There is an experimental CSS display property of contents which will allow us to have our required structure but unbundle the respective wrappers as required.
I record it here for information purposes pending adoption by other browsers.
MDN Reference
These elements don't produce a specific box by themselves. They are replaced by their pseudo-box and their child boxes.
Codepen Demo
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
#container {
width: 100%;
height: 100%;
display: flex;
}
.wrapper {
width: 50%;
height: 100%;
display: flex;
flex-direction: column;
}
.red > .divInside {
background-color: red;
}
.yellow > .divInside {
background-color: yellow;
}
.divInside {
border: 1px solid;
height: 25%;
width: 100%;
order: 0;
}
.red .divInside:nth-child(1) {} .red .divInside:nth-child(2) {
order: 3;
}
.red .divInside:nth-child(3) {
order: 5
}
.red .divInside:nth-child(4) {
order: 8
}
.yellow .divInside:nth-child(1) {
order: 2;
}
.yellow .divInside:nth-child(2) {
order: 5
}
.yellow .divInside:nth-child(3) {
order: 6
}
.yellow .divInside:nth-child(4) {
order: 7
}
#media screen and (max-width: 760px) {
.wrapper {
display: contents;
}
#container {
flex-direction: column;
}
}
<div id="container">
<div class="wrapper red">
<div class="divInside">1</div>
<div class="divInside">2</div>
<div class="divInside">3</div>
<div class="divInside">4</div>
</div>
<div class="wrapper yellow">
<div class="divInside">5</div>
<div class="divInside">6</div>
<div class="divInside">7</div>
<div class="divInside">8</div>
</div>
</div>

Overlapping elements within a square grid

I’ve to implement a layout based on a square grid. As shown on the following image, some elements have to overlap responsive within this grid. (The squares are offset on the x-axis and overlap by one grid cell on the y-axis.)
http://i.stack.imgur.com/9bZ5G.jpg
Does anybody know how to achieve this effect? I'm using the framework Foundation 6. I’d prefer a solution without JavaScript. I can’t use the Foundation .#-push-# and .#pull-# classes because they would shift the elements inwards and the two squares have to be in separate rows.
I’ve set up a JSFiddle containing the two squares.
.square {
background: #f00;
position: relative;
}
.square:after {
content: "";
display: block;
padding-bottom: 100%;
}
.content {
position: absolute;
width: 100%;
height: 100%;
}
.dark {
background: #cbcbcb;
}
.light {
background: #dedede;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.2.0/foundation.css" rel="stylesheet"/>
<div class="row">
<div class="small-12 columns">
<div class="row">
<div class="small-8 columns end">
<div class="square dark">
<div class="content">test</div>
</div>
</div>
</div>
<div class="row">
<div class="small-6 small-offset-6 columns end">
<div class="square light">
<div class="content">test</div>
</div>
</div>
</div>
</div>
</div>
Many thanks in advance for your help.
I know this question is a little bit old, but for the benefit of all this is now very easily and cleanly possible with CSS Grid. Taking the image posted in the original question we define a container and two squares:
<div class="container">
<div class="content square1">Square 1</div>
<div class="content square2">Square 2</div>
</div>
Then in the CSS define the container as a CSS Grid with 6 columns and 6 rows. In the example below I have used the repeat() CSS Method to have the browser create 6 of the same sized columns and rows.
.container {
display: grid;
grid-column-template: repeat(6, 1fr);
grid-row-template: repeat(6, 30px);
width: 100%;
height: 600px;
}
Then for each item you set where the upper left hand corner will be located on that grid. You can use the long handed properties of grid-column-start, grid-column-end, grid-row-start, and grid-row-end, but I find it's easier to use the short hand properties as shown below:
.square1 {
grid-column: 1 / 5;
grid-row: 1 / 5;
background: #cbcbcb;
}
.square2 {
grid-column: 4 / 7;
grid-row: 4 / 7;
background: #dedede;
}
As far as the placement goes, you specify it based on the grid lines you're invisibly drawing in the container. Position 1 / 1 in this case is the upper left-most corner (or where 0,0 would be if you're talking about coordinates). CSS Grid is now widely supported and I believe there are some JS libraries out there that do create fall backs for this if you don't want to hard code your own with feature queries.
Here's the full block of code with the SO Code Snippet runner:
.container {
display: grid;
grid-column-template: repeat(6, 1fr);
grid-row-template: repeat(6, 30px);
width: 100%;
height: 600px;
}
.square1 {
grid-column: 1 / 5;
grid-row: 1 / 5;
background: #cbcbcb;
}
.square2 {
grid-column: 4 / 7;
grid-row: 4 / 7;
background: #dedede;
}
<div class="container">
<div class="content square1">Square 1</div>
<div class="content square2">Square 2</div>
</div>
It seems to work if you calculate the offset with percent and also mind the column spacing. I therefore adjustet the snippet and added another square with 4 colums:
.square {
background: #f00;
position: relative;
}
.square:after {
content: "";
display: block;
padding-bottom: 100%;
}
.content {
position: absolute;
width: 100%;
height: 100%;
}
.dark {
background: #cbcbcb;
}
.light {
background: #dedede;
}
/* NEW */
.small-6.columns.overlap-top > .square {
margin-top: calc(-33.3% + 1.33*0.625rem); // one third is 33.3% minus 1.33 times col spacing
}
.small-4.columns.overlap-top > .square {
margin-top: calc(-50% + 1*0.625rem); // one half is 50% minus 1 times col spacing
}
#media screen and (min-width: 40em) {
.small-6.columns.overlap-top > .square {
margin-top: calc(-33.3% + 1.33*0.9375rem);
}
.small-4.columns.overlap-top > .square {
margin-top: calc(-50% + 1*0.9375rem);
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.2.0/foundation.css" rel="stylesheet"/>
<div class="row">
<div class="small-12 columns">
<div class="row">
<div class="small-8 columns end">
<div class="square dark">
<div class="content">Square 1</div>
</div>
</div>
</div>
<div class="row">
<!-- New class overlap-top -->
<div class="small-6 small-offset-6 columns overlap-top end">
<div class="square light">
<div class="content">Square 2</div>
</div>
</div>
</div>
<!-- New square -->
<div class="row">
<div class="small-4 small-offset-4 columns overlap-top end">
<div class="square dark">
<div class="content">Square 3</div>
</div>
</div>
</div>
</div>
</div>
JSFiddle: https://jsfiddle.net/jwt0k1pw/1/
Hope this helps!

Switching from 3 columns to 2

I have a responsive layout set up for 3 columns. In each column is a product that we are trying to sell. Sometimes there could be 3 items, 2 items and 1 item. Currently when I remove 1 item it will display on 2/3 of the page and leave the 1/3 empty. How do I create it so that when there are 2 or 1 item being displayed for them to be centered and they would have a max-width of 640px?
/* -------- HTML ------------*/
<div class="item">Item1</div>
<div class="item">Item1</div>
<div class="item">Item1</div>
/* -------- CSS ------------*/
.item {
display: inline;
float: left;
width: 33.33%;
}
With flexbox, the container will fill 100% of the space based on how many items you have.
HTML
<div class="flex-row">
<div class="item">Item1</div>
<div class="item">Item2</div>
<div class="item">Item3</div>
</div>
<div class="flex-row">
<div class="item">Item1</div>
<div class="item">Item2</div>
</div>
<div class="flex-row">
<div class="item">Item1</div>
</div>
CSS
.flex-row {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.item {
flex: 1;
}
Here is an example
A flex box would better suit your need. Remove/add item to see how the columns adapt to your new content:
.container{
display: flex;
}
.item{
flex-grow: 1;
background-color: red;
border: 1px solid black;
}
<div class="container">
<div class="item">Item1</div>
<div class="item">Item2</div>
<div class="item">Item3</div>
</div>

Resources