I have a layout consisting of a single ordered list containing a bunch of items.
All items have consistent width and height - except the first item - which is (3x) wider and (2x) taller. It looks like this:
ol {
padding:0;
margin:0;
min-width: 488px;
}
li {
list-style: none;
width: 150px;
padding-bottom: 16.66%;
border: 5px solid tomato;
display: inline-block;
}
li:first-child {
float:left;
width: 478px;
border-color: green;
padding-bottom: 34.25%;
margin: 0 4px 4px 0;
}
<ol>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
Currently, i'm using floats and inline-blocks to achieve the layout, but i'd like to use flexbox because of some extra features which flexbox offers.
I have made a couple of attempts, but with no success -
Attempt #1 - Codepen
ol {
/* ... */
display: flex;
flex-wrap: wrap;
}
Attempt #2 - Codepen
Use a float before the list to secure space for the first large list item
Then set display absolute on the first list item.
In both attempts, the red boxes in the first line stretch to fill the height of the first item.
Is this possible?
(If not, then I would be interested in a CSS grid workaround)
Why choose flexbox? In a perfect world of browser support, the reason you'd choose to use flexbox is because you want to lay a collection of items out in one direction or another. As you lay out your items you want to control the dimensions of the items in that one dimension, or control the spacing between items.
For 3 items per row, add on the flex items: flex-basis: 33.333333% You can also use the flex 's shorthand like the following: flex: 0 0 33.333333% => which also means flex-basis: 33.333333% .
So it's pretty clear that flexbox can't produce a layout like this. So I'll answer this part of the question:
If not, then I would be interested in a CSS grid workaround
With the CSS Grid Layout Module this is surprisingly easy to produce:
Basically the relevant code boils down to this:
ul {
display: grid; /* (1) */
grid-template-columns: 120px 120px repeat(auto-fill, 120px); /* (2) */
grid-template-rows: repeat(auto-fill, 150px); /* (3) */
grid-gap: 1rem; /* (4) */
justify-content: space-between; /* (5) */
}
li:first-child {
grid-column: 1 / 4; /* (6) */
grid-row: 1 / 3; /* (7) */
}
1) Make the container element a grid container
2) Set the grid with at least 3 columns of width 120px. (The auto-fill
value is used for responsive layouts).
3) Set the grid with 150px high rows.
4) Set gaps/gutters for the grid rows and columns - here, since want a 'space-between' layout - the gap will actually be a minimum gap because it will grow as necessary.
5) Similar to flexbox.
6) occupy the first three columns
7) occupy the first two rows
body {
margin: 0;
}
ul {
display: grid;
grid-template-columns: 120px 120px repeat(auto-fill, 120px);
grid-template-rows: repeat(auto-fill, 150px);
grid-gap: 1rem;
justify-content: space-between;
/* boring properties: */
list-style: none;
width: 90vw;
height: 90vh;
margin: 4vh auto;
border: 5px solid green;
padding: 0;
overflow: auto;
}
li {
background: tomato;
min-height: 150px;
}
li:first-child {
grid-column: 1 / 4;
grid-row: 1 / 3;
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
<li>14</li>
<li>15</li>
<li>16</li>
<li>17</li>
<li>18</li>
<li>19</li>
<li>20</li>
</ul>
Currently supported by Chrome (Blink) and Firefox, with partial support from IE and Edge (See this post by Rachel Andrew)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With