CSS Flexbox and Grid: is the order's default value 0 or 1? - css

In Flexbox and Grid, we can change the order in which items are displayed, with among other things the order property. Everywhere, I'm reading that the default order value is 0, also on https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items.
But look at this example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Order demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
margin: 40px;
}
.wrapper {
width: 600px;
display: grid;
grid-template-columns: repeat(6, 100px);
grid-gap: 10px;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
order: 1;
}
.box:nth-child(even) {
background-color: #ccc;
color: #000;
}
.box2 {
order: 0;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="box box1">1</div>
<div class="box box2">2</div>
<div class="box box3">3</div>
<div class="box box4">4</div>
<div class="box box5">5</div>
<div class="box box6">6</div>
<div class="box box7">7</div>
<div class="box box8">8</div>
<div class="box box9">9</div>
<div class="box box10">10</div>
<div class="box box11">11</div>
<div class="box box12">12</div>
</div>
</body>
</html>
Here is the corresponding Pen, in which you can see the rendering: https://codepen.io/FrankConijn/pen/BaYxBzd.
Item nr. 2 is displayed first, while it has order: 0, which should have it displayed in the order in which it is placed in the code (2nd). That suggests that the specs are incorrect, and that the default value is 1. Am I right?

order does indeed have a default value of 0 (MDN formal definition & MDN 'Ordering Flex Items'), but in your example you've overridden this by giving each .box an explicit order: 1; here the order: 0 on .box2 is behaving correctly according to its property in appearing in the 1st position.
If you remove the order on your .box class and let them order by default (0) you'll see that the position of .box2 is placed as it should be: as the 2nd box:
body {
margin: 40px;
}
.wrapper {
width: 600px;
display: grid;
grid-template-columns: repeat(6, 100px);
grid-gap: 10px;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.box:nth-child(even) {
background-color: #ccc;
color: #000;
}
.box2 {
order: 0;
}
<body>
<div class="wrapper">
<div class="box box1">1</div>
<div class="box box2">2</div>
<div class="box box3">3</div>
<div class="box box4">4</div>
<div class="box box5">5</div>
<div class="box box6">6</div>
<div class="box box7">7</div>
<div class="box box8">8</div>
<div class="box box9">9</div>
<div class="box box10">10</div>
<div class="box box11">11</div>
<div class="box box12">12</div>
</div>
</body>

Related

CSS Grid auto-fit column automatically wraps

from the example I have three columns, when resized at a certain view-port it will wrap onto the next row, how can I target that individual div and make it fill the available width?
.boxes {
color: white;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.box {
background-color: blue;
padding: 10px;
}
<section class = "boxes">
<div class="box">
<p>Box 1</p>
</div>
<div class="box">
<p>Box 2</p>
</div>
<div class="box">
<p>Box 3</p>
</div>
</section>
Codepen:
CodePen
You need flexbox for this:
body {
color: white;
}
.boxes {
display: flex;
flex-wrap: wrap;
}
.box {
background-color: blue;
padding: 10px;
min-width: 250px;
box-sizing:border-box;
margin: 10px;
flex-grow: 1;
}
<section class="boxes">
<div class="box">
<p>Box 1</p>
</div>
<div class="box">
<p>Box 2</p>
</div>
<div class="box">
<p>Box 3</p>
</div>
</section>
Limit columns by max-width
you can stay with grid, but it look good only if you stay with 2 columns.
for more columns its more complicated and you can define what you want, to use grid or to use flex for convenient way.
html {
box-sizing: border-box;
}
body {
background-color: white;
color: white;
}
.boxes {
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
max-width: 700px;
margin: 0 auto;
text-align: center;
}
.box {
background-color: blue;
padding: 10px;
}
.box:last-child:nth-child(odd) {
grid-column: 1/3;
}
<!DOCTYPE html>
<html>
<head>
<title>Column Resize</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<section class="boxes">
<div class="box">
<p>Box 1</p>
</div>
<div class="box">
<p>Box 2</p>
</div>
<div class="box">
<p>Box 3</p>
</div>
</section>
</body>
</html>

Flexbox that wraps around a fixed container

I'm trying to create a form with a variable number of form fields that would expand horizontally. Each field would have a minimum width of 300 px, but would expand to fill the row if there is extra space. If there is not enough space for each field at 300px, then it would wrap to another row. Flexbox would be the perfect solution for this. However, I also want there to be a variable width container for submit & cancel buttons that is fixed on the right side of the first row. (See the attached illustration.)
How can I create this fixed, right-aligned container that Flexbox would flow around? Can this be done with Flexbox alone? Would CSS Grid (or a combination of Flexbox & Grid) be helpful here? Example code would be appreciated.
I think your best solution is to use float and inline-block. then you can adjust sizing considering media query
body>.container {
background-color: #FFFFFF;
margin: auto;
margin-top: 24px;
padding: 0px;
}
.container {
border: solid 1px #F00;
font-size:0;
}
.box {
box-sizing: border-box;
border: 1px solid #000;
text-align: center;
vertical-align: middle;
min-height: 36px;
width: calc(25% - 10px);
min-width: 200px;
display:inline-block;
margin: 5px;
font-size:initial;
}
.box.buttons {
float:right;
}
<link data-require="bootstrap-css#*" data-semver="4.0.0-alpha.4" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" />
<div class="container">
<div class="box buttons">
<button>Submit</button>
<button>Cancel</button>
</div>
<div class="box a">Box A</div>
<div class="box b">Box B</div>
<div class="box c">Box C</div>
<div class="box e">Box E</div>
<div class="box f">Box F</div>
</div>
After some experimentation, I found that this is possible with CSS Grid. Here is the basic layout:
HTML:
<div class="auto-fit">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C</div>
<div class="D">D</div>
<div class="E">E</div>
<div class="F">F</div>
<div class="G">G</div>
<div class="H">H</div>
<div class="I">I</div>
<div class="J">J</div>
<div class="K">K</div>
<div class="L">L</div>
<div class="M">M</div>
<div class="buttons"><button>Submit</button><button>Cancel</button></div>
</div>
CSS:
div.auto-fit {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px;
}
div.auto-fit > div {
background-color: #fff;
border-radius: 3px;
padding: 15px;
font-size: 14px;
}
div.buttons {
grid-column: -1/-2;
grid-row: 1/2;
}
Here is a jsfiddle that shows it in action: https://jsfiddle.net/lobo78/5ufqdm4y/22/

How can I limit the number of columns with a responsive CSS Grid? [duplicate]

I am using CSS Grid and have made the following layout in the codepen found here: https://codepen.io/alexg2195/pen/xLEeMd
My issue is that when using repeat(auto-fill, minmax(400px, 1fr)); I end up with a layout that goes beyond just two columns.
Is there a way to force two columns but still have the same min auto fill resize behaviors?
body {
margin: 40px;
}
.layout {
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr 100px;
grid-template-areas: "main btn" "main .";
}
.btn {
grid-area: btn;
background-color: #444;
color: #ddd;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.boxes {
grid-area: main;
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
<div class="layout">
<div class="boxes">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
<div class="box j">J</div>
<div class="box k">K</div>
<div class="box l">L</div>
<div class="box m">M</div>
</div>
<div class="btn">BTN</div>
</div>
Is there a way to force two columns but still have the same min auto fill resize behaviors?
Not with auto-fill / auto-fit.
These functions are built to fit the largest number of tracks without overflowing the container.
7.2.2.2. Repeat-to-fill: auto-fill and auto-fit
repetitions
When auto-fill is given as the repetition number, if the grid
container has a definite size or max size in the relevant axis, then
the number of repetitions is the largest possible positive integer
that does not cause the grid to overflow its grid container.
In order to "auto-fill" a maximum of two columns per row, you'll need to find another method.
Maybe flexbox?
revised demo
body {
margin: 40px;
}
.layout {
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr 100px;
grid-template-areas: "main btn" "main .";
}
.btn {
grid-area: btn;
background-color: #444;
color: #ddd;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.boxes {
grid-area: main;
display: flex;
flex-wrap: wrap;
}
.box {
flex: 1 0 40%;
margin: 5px;
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
div.box.n {
visibility: hidden; /* https://stackoverflow.com/q/42176419/3597276 */
height: 0;
}
<div class="layout">
<div class="boxes">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
<div class="box j">J</div>
<div class="box k">K</div>
<div class="box l">L</div>
<div class="box m">M</div>
<div class="box n">N</div>
</div>
<div class="btn">BTN</div>
</div>

Centre 3 columns within container but allow

I have a container that holds multiple divs, around 20. I want to put 3 divs on each line so it kind of looks something like this (with the divs just continuing to flow).
What's the best way to centre these columns without having them in some sort of parent div? I can center them if I used a div which held 3 columns each but with the system I'm using I cannot. Any ideas?
A simple example will be:
pure css you can use this one to control row:
.child:nth-child(3n+1) {
clear: both;
}
with width: calc((100% - 60px)/3); to get width dynamically.
.child {
background: white;
height: 40vh;
float: left;
margin: 0px 10px 10px 0px;
width: calc((100% - 60px)/3);
border: 5px solid black;
}
.child:nth-child(3n+1) {
clear: both;
}
.wrapper {
background: white;
border: 5px solid black;
display: inline-block;
width: calc(100% - 30px);
margin: 10px;
padding: 10px 0px 0px 10px;
}
<div class="wrapper">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
The 'best' way IMO is to use flexbox. You say with no parent div but it has to have some kind of parent container div.
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 400px;
margin: 0 auto;
padding: 25px;
border: 2px solid black;
}
.box {
display: block;
height: 160px;
width: 100px;
margin-bottom: 25px;
border: 2px solid black;
}
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>

How to use CSS to create a matrix of cells, and not use HTML tags at all

I wish to create a matrix of cells with the names of people. I want to create a 3 by 3 matrix of names. So far I just have one row of names, but I want to add another two rows. I know I can do this using the HTML "tr" and "td" tags, but is there a way I can do this purely using CSS?
<!DOCTYPE html>
<html>
<head>
<style>
body {background-color: lightgray}
div {
float:left;
width: 300px;
padding: 25px;
border: 25px solid navy;
margin: 25px;
}
</style>
</head>
<body>
<div>James</div><div>Richard</div><div>Kevin</div>
</body>
</html>
You can try using flexbox:
.flex {
font: 14px Arial;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.flex > div {
flex: 1 1 auto;
width: 33.3%;
box-sizing:border-box;
border:1px solid black;
text-align:center;
line-height:20px;
padding:5px;
}
<div class="flex">
<div>James</div>
<div>Richard</div>
<div>Kevin</div>
<div>James</div>
<div>Richard</div>
<div>Kevin</div>
</div>
Nice Link to Learn also check the support
CSS3 has columns property:
.divTable
{
-webkit-columns: 1px 3;
-moz-columns: 1px 3;
columns: 1px 3;
}
<div class='divTable'>
<div>James</div><div>Richard</div><div>Kevin</div>
<div>James</div><div>Richard</div><div>Kevin</div>
<div>James</div><div>Richard</div><div>Kevin</div>
</div>
It forms columns first and then rows (all Jameses will go to the first row). But it flexible with regards to the width.
You could keep using div elements and still achieve your 3x3 matrix by just wrapping every row with a div.
.row{
width: 390px;
}
.row div{
float:left;
width: 50px;
padding: 25px;
border: 5px solid black;
margin: 10px;
}
<div class="row">
<div>James</div>
<div>Richard</div>
<div>Kevin</div>
</div>
<div class="row">
<div>James</div>
<div>Richard</div>
<div>Kevin</div>
</div>
<div class="row">
<div>James</div>
<div>Richard</div>
<div>Kevin</div>
</div>
How about this:
<style>
.main div {
float:left;
margin:3px;
width:80px;
height:80px;
background-color:#ccc;
}
.main div:nth-child(3n+1) {
clear:left;
}
</style>
<div class="main">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
.Table
{
display: table;
}
.Title
{
display: table-caption;
text-align: center;
font-weight: bold;
font-size: larger;
}
.Heading
{
display: table-row;
font-weight: bold;
text-align: center;
}
.Row
{
display: table-row;
}
.Cell
{
display: table-cell;
border: solid;
border-width: thin;
padding-left: 5px;
padding-right: 5px;
}
<div class="Table">
<div class="Title">
<p>This is a Table</p>
</div>
<div class="Heading">
<div class="Cell">
<p>Heading 1</p>
</div>
<div class="Cell">
<p>Heading 2</p>
</div>
<div class="Cell">
<p>Heading 3</p>
</div>
</div>
<div class="Row">
<div class="Cell">
<p>Row 1 Column 1</p>
</div>
<div class="Cell">
<p>Row 1 Column 2</p>
</div>
<div class="Cell">
<p>Row 1 Column 3</p>
</div>
</div>
<div class="Row">
<div class="Cell">
<p>Row 2 Column 1</p>
</div>
<div class="Cell">
<p>Row 2 Column 2</p>
</div>
<div class="Cell">
<p>Row 2 Column 3</p>
</div>
</div>
</div>

Resources