Can I achieve this layout with flexbox with the below document structure?
I want the big <img> on the left with two smaller images on the right and wrapping.
This is what I did, with display: flex on gallery-container and flex-wrap.
.container {
height: 100%;
}
.container .gallery-container {
background-color: #f6f6f6;
display: flex;
flex-wrap: wrap;
width: 300px;
align-items: flex-start;
}
.container .gallery-container .gallery-big-image {
display: block;
width: 200px;
height: 200px;
background: lavender;
}
.container .gallery-container .gallery-small-img {
display: block;
width: 100px;
height: 100px;
background-color: purple;
}
<div class="container">
<div class="gallery-container">
<div class="gallery-big-image">big</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
</div>
</div>
(codepen)
The layout is clunky and inefficient with flexbox, for reasons explained here: CSS-only masonry layout
However, the layout is relatively simple and easy with CSS Grid.
No changes to HTML.
.gallery-container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
grid-auto-rows: 100px;
width: 300px;
background-color: #f6f6f6;
}
.gallery-big-image {
grid-column: span 2;
grid-row: span 2;
background: lavender;
}
.gallery-small-img {
background-color: purple;
color: white;
}
<div class="container">
<div class="gallery-container">
<div class="gallery-big-image">big</div>
<div class="gallery-small-img">small 1</div>
<div class="gallery-small-img">small 2</div>
<div class="gallery-small-img">small 3</div>
<div class="gallery-small-img">small 4</div>
<div class="gallery-small-img">small 5</div>
<div class="gallery-small-img">small 6 (continues wrapping)</div>
<div class="gallery-small-img">small 7 (continues wrapping)</div>
</div>
</div>
How about using grid layout instead?
.container {
height: 100%;
}
.gallery-container {
background-color: #f6f6f6;
width: 300px;
height: 100px;
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
}
.gallery-img {
background: purple;
width: 100px;
height: 100px;
}
.gallery-img-large {
background: lavender;
width: 200px;
height: 200px;
grid-column-start: 0;
grid-column-end: span 2;
grid-row-start: 0;
grid-row-end: span 2;
}
<div class="container">
<div class="gallery-container">
<div class="gallery-img-large">big</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
</div>
</div>
Related
I am trying to create a table that looks like this
<div class="style" id="1"></div>
<div class="style" id="2"></div>
<div class="style" id="3"></div>
<div class="style" id="4"></div>
<div class="style" id="5"></div>
<div class="style" id="6"></div>
<div class="style" id="7"></div>
<div class="style" id="8"></div>
<div class="style" id="9"></div>
I am struggling with the css part
For positioning items like show in your image, you can use display: grid;. I made the grid to have 4 columns and 3 rows.
Lastly, one item is bigger than the others. You can change the space the item uses by adjusting the grid-column and grid-row:
* {
margin: 0;
padding: 0;
}
body {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3,1fr);
max-width: 400px;
}
div {
min-width: 100px;
min-height: 100px;
border: 1.5px solid black;
}
#one {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
#one,
#three,
#four,
#six,
#eight {
background-color: red;
}
#two,
#five,
#seven,
#nine {
background-color: blue;
}
<div id="one"></div>
<div id="two"></div>
<div id="three"></div>
<div id="four"></div>
<div id="five"></div>
<div id="six"></div>
<div id="seven"></div>
<div id="eight"></div>
<div id="nine"></div>
Not using the html you gave but this is a approach with display: flex . I did not optimize the styling so you can see what is happening.
* {
box-sizing: border-box;
}
.row-full {
display: flex;
flex-wrap: wrap;
width: 240px;
}
.row-half {
display: flex;
flex-wrap: wrap;
width: 120px;
}
.block-big {
width: 120px;
height: 120px;
border: 1px solid black;
}
.block {
width: 60px;
height: 60px;
border: 1px solid black;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
<div class="row-full">
<div class="block-big red"></div>
<div class="row-half">
<div class="block blue"></div>
<div class="block red"></div>
<div class="block red"></div>
<div class="block blue"></div>
</div>
</div>
<div class="row-full">
<div class="block red"></div>
<div class="block blue"></div>
<div class="block red"></div>
<div class="block blue"></div>
</div>
I would use css grid for this. css grid makes it able for you to make a more complex css layout. I made this quick example that shows how you can use it.
.grid{
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
width: 100vw;
height: 100vh;
background-color: red;
}
.style1{
grid-column: 1/3;
grid-row: 1/3;
background-color: blue;
}
.style2{
grid-column: 3/4;
grid-row: 1/2;
background-color: green;
}
.style3{
grid-column: 3/4;
grid-row: 2/3;
background-color: yellow;
}
.style4{
grid-column: 4/5;
grid-row: 1/3;
background-color: pink;
}
.style5{
grid-column: 1/4;
grid-row: 3/4;
background-color: orange;
}
.style6{
grid-column: 4/5;
grid-row: 3/4;
background-color: purple;
}
<div class="grid">
<div class="style1" id="1"></div>
<div class="style2" id="2"></div>
<div class="style3" id="3"></div>
<div class="style4" id="4"></div>
<div class="style5" id="5"></div>
<div class="style6" id="6"></div>
</div>
This is another answer :
html, body{
font-family: sans-serif;
}
#container{
display:grid;
grid-template-columns: repeat(4, 100px);
grid-template-rows: repeat(4, 100px);
}
#container div{
border:1px solid #000000;
}
#div1{
background-color: red;
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 3;
}
#div2{
background-color: blue;
}
#div3{
background-color: red;
}
#div4{
background-color: red;
}
#div5{
background-color: blue;
}
#div6{
background-color: red;
}
#div7{
background-color: blue;
}
#div8{
background-color: red;
}
#div9{
background-color: blue;
}
<div id="container">
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<div id="div4"></div>
<div id="div5"></div>
<div id="div6"></div>
<div id="div7"></div>
<div id="div8"></div>
<div id="div9"></div>
I am trying to create a flexbox grid which should look like that
The basic grid layout is pretty easy to create, but I have a very hard time adding the spacing between the elements. As you can see in the code snippet, the spacing in the second line is not working properly.
#flexContainer {
display: flex;
flex-direction: column;
gap: 16px;
height: 200px;
width: 600px;
}
.rowContainer {
display: flex;
flex-direction: row;
gap: 16px;
}
.thirdElement {
flex-grow: 1;
height: 40px;
background-color: red;
}
.twoThirdsElement {
flex-grow: 2;
height: 40px;
background-color: red;
}
<div id="flexContainer">
<div class="rowContainer">
<div class="thirdElement">
</div>
<div class="thirdElement">
</div>
<div class="thirdElement">
</div>
</div>
<div class="rowContainer">
<div class="twoThirdsElement">
</div>
<div class="thirdElement">
</div>
</div>
</div>
This looks to me like a three column grid with the fourth item spanning two colums.
Here's a simplified version. Obviously you'll want to style the items as you need them.
#flexContainer {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
height: 200px;
width: 600px;
}
#flexContainer>* {
background-color: red;
}
.twoThirdsElement {
grid-column: auto / span 2;
}
<div id="flexContainer">
<div>
</div>
<div>
</div>
<div>
</div>
<div class="twoThirdsElement">
</div>
<div>
</div>
</div>
Use CSS grid
#flexContainer {
display: flex;
flex-direction: column;
gap: 16px;
}
.rowContainer {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
}
.thirdElement {
height: 40px;
background-color: red;
}
.twoThirdsElement {
grid-column:span 2;
height: 40px;
background-color: red;
}
<div id="flexContainer">
<div class="rowContainer">
<div class="thirdElement">
</div>
<div class="thirdElement">
</div>
<div class="thirdElement">
</div>
</div>
<div class="rowContainer">
<div class="twoThirdsElement">
</div>
<div class="thirdElement">
</div>
</div>
</div>
You not need to <div class="rowContainer">. It fixes only with one flex property for #flexContainer.
#flexContainer {
display: flex;
flex-wrap: wrap;
height: calc(80px + (600px / 20)); /* (600px/20) == 5% of 600px. result = 80px + 5%(600px). it is for a gap between rows that is equal with gap: 5%; for columns.*/
align-content: space-between;
gap: 5%;
width: 600px;
}
.thirdElement {
flex-basis: 30%;
height: 40px;
background-color: red;
}
.twoThirdsElement {
flex-basis: 65%;
height: 40px;
background-color: red;
}
<div id="flexContainer">
<div class="thirdElement">
</div>
<div class="thirdElement">
</div>
<div class="thirdElement">
</div>
<div class="twoThirdsElement">
</div>
<div class="thirdElement">
</div>
</div>
I have a layout that is a sidebar and a grid both wrapped in a flexbox. I'd like to put a div underneath the grid so it can have prev/next buttons, like in this image, but I can't figure out how to do that. The grid resizes itself with the window so the grid can take as many rows as necessary and then the div should go below that, and be as wide as the grid.
This is what I have, but the div is on the right of the grid:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Boardgame Database</title>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
aside {
background-color: red;
flex: 1;
min-width: 250px;
}
.grid-container {
flex: 4;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.grid-item {
border: 1px solid black;
padding: 20px;
font-size: 24px;
text-align: center;
overflow: hidden;
}
#flex-container {
display: flex;
flex-direction: row;
min-height: 100vh;
}
</style>
</head>
<body>
<div id="flex-container">
<aside class="sidebar">
</aside>
<section class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
<div class="grid-item">10</div>
<div class="grid-item">11</div>
<div class="grid-item">12</div>
<div class="grid-item">13</div>
<div class="grid-item">14</div>
<div class="grid-item">15</div>
<div class="grid-item">16</div>
<div class="grid-item">17</div>
<div class="grid-item">18</div>
</section>
<div id="page-buttons">
prev
next
</div>
</div>
Checkout the following Code.
#main{
display :flex;
}
#sidebar{
width:70px;
height: 300px;
border: solid black 1px;
}
#grid-area{
width:200px;
height: 300px;
border: solid black 1px;
display: block;
}
#grid{
width:200px;
height: 250px;
border: solid black 1px;
display: block;
}
<div id="main">
<div id="sidebar"></div>
<div id="grid-area">
<div id="grid"></div>
<div id="button">next / prev</div>
</div>
</div>
You should use nested flex containers. Section and bottom div should be wrapped inside another flex container with flex direction to column.
So outer flex will make sidebar & inner flex container to be side by side.
Or just use a normal div container instead of flex.
here is another example only with grid keeping the pre/next button at the bottom of the viewport:
body {
margin: 0;
}
#grid-container {
display: grid;
height: 100vh;
grid-template-columns: minmax(250px, 1fr) 4fr;
grid-template-rows: 1fr auto;
}
aside {
background-color: red;
border: 1px solid;
margin: 0.25em;
grid-row: span 2;
grid-column: 1;
}
section,
#page-buttons {
grid-column: 2;
border: solid 1px;
margin: 0.25em;
}
section {
overflow: auto;
}
#page-buttons {
display: flex;
gap: 1em;
padding: 0.5em;
background: lightgray;
justify-content: center;
}
.grid-item {
border: 1px solid black;
padding: 20px;
font-size: 24px;
text-align: center;
overflow: hidden;
}
<div id="grid-container">
<aside class="sidebar">
</aside>
<section class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
<div class="grid-item">10</div>
<div class="grid-item">11</div>
<div class="grid-item">12</div>
<div class="grid-item">13</div>
<div class="grid-item">14</div>
<div class="grid-item">15</div>
<div class="grid-item">16</div>
<div class="grid-item">17</div>
<div class="grid-item">18</div>
</section>
<div id="page-buttons">
prev
next
</div>
</div>
I would like to make a responsive table layout with DIVs that has two columns and the second column is split into two equal rows so it looks like this.
You can use CSS Flex with flex: 1 and flex: 2
.container {
display: flex;
width: 100%;
height: 300px;
flex-wrap: wrap;
}
.column {
flex: 1;
display: flex;
flex-direction: column;
}
.button {
flex: 1;
color: white;
}
.button.rowspan {
flex: 2;
}
<div class="container">
<div class="column">
<div class="button rowspan" style="background: red;">
Column 1 - rowspan
</div>
</div>
<div class="column">
<div class="button" style="background: green">
Column 2
</div>
<div class="button" style="background: orange">
Column 3
</div>
</div>
</div>
Would be nice to see your attempt of doing it yourself. You can use CSS grid to build responsive layouts:
<html>
<div class="grid">
<div class="left">
</div>
<div class="right-up">
</div>
<div class= "right-down">
</div>
</div>
</html>
CSS:
.grid {
display: grid;
position: absolute;
top: 0;
left: 0;
grid-template-columns: 50vw 50vw;
grid-template-rows: 50vh 50vh;
grid-template-areas:
"left right-up"
"left right-down";
}
.left {
grid-area: left;
background-color: blue;
}
.right-up {
grid-area: right-up;
background-color: green;
}
.right-down{
grid-area: right-down;
background-color: red;
}
JSfiddle: JSfiddle link
I'm trying to create a layout for print content on sticker label.
So, I create div and use display:grid; to divide space as I want.
The item1, item2, and item3 should overlap each other and centered in the cell.
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 70mm; // Seems useless
align-items: center;
}
.cell {
border-style: dashed;
width: 100mm;
height: 70mm;
align-content: center;
}
.item1 {
z-index: 0;
width: 40mm;
height: 40mm;
background-color: red;
position: relative;
}
.item2 {
z-index: 1;
width: 20mm;
height: 20mm;
background-color: blue;
position: relative;
}
.item2 {
z-index: 2;
width: 10mm;
height: 10mm;
background-color: green;
position: relative;
}
<div class="grid">
<div class="cell">
<div class="item1"></div>
<div class="item2"></div>
<img class="item3" src="./src.png" />
</div>
<div class="cell">
<div class="item1"></div>
<img class="item2" src="./src.png" />
<div class="item3"></div>
</div>
<div class="cell">
<div class="item1"></div>
<img class="item2" src="./src.png" />
<div class="item3"></div>
</div>
</div>
I can't achieve the correct result: A grid with items centered horizontally AND vertically in each cell. The cell should have precise size (100mmx70mm), 2 cells per row since the page should be printed.
Is there any CSS wizard in the audience that can help me?
All you need is absolute positioning and translate transformations based on percentage.
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 70mm; // Seems useless
align-items: center;
}
.cell {
border-style: dashed;
width: 100mm;
height: 70mm;
align-content: center;
position: relative;
}
.cell>*{
position: absolute;
left:50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
}
.item1 {
z-index: 0;
width: 40mm;
height: 40mm;
background-color: red;
}
.item2 {
z-index: 1;
width: 20mm;
height: 20mm;
background-color: blue;
}
.item2 {
z-index: 2;
width: 10mm;
height: 10mm;
background-color: green;
}
<div class="grid">
<div class="cell">
<div class="item1"></div>
<div class="item2"></div>
<img class="item3" src="./src.png" />
</div>
<div class="cell">
<div class="item1"></div>
<img class="item2" src="./src.png" />
<div class="item3"></div>
</div>
<div class="cell">
<div class="item1"></div>
<img class="item2" src="./src.png" />
<div class="item3"></div>
</div>
</div>