I'm trying to arrange my containers with Flexbox (not Grid!) to look like this image
With the following HTML:
<div class="container">
<div class="sub-container">
<div class="top-sub-container">
<div class="box box-1">
<img src="yourChoice.png" />
<div class="box-text">
This is the text of the box 1
</div>
</div>
<div class="box box-2">
<img src="yourChoice.png" />
<div class="box-text">
This is the text of the box 2
</div>
</div>
</div>
<div class="box box-3">
<img src="yourChoice.png" />
<div class="box-text">
This is the text of the box 3
</div>
</div>
</div>
<div class="box box-4">
<img src="yourChoice.png" />
<div class="box-text">
This is the text of the box 4
</div>
</div>
</div>
And this CSS:
.container {
display: flex;
gap: 1rem;
height: 25rem;
width: 25rem;
padding: 1rem;
background: pink;
}
.top-sub-container {
flex: 1 1 auto;
display: flex;
gap: 1rem;
}
.sub-container {
flex: 1 1 auto;
display: flex;
gap: 1rem;
flex-direction: column;
}
.box {
display: flex;
flex: 1 1 auto;
flex-direction: column;
border: 1px solid black;
}
However I am getting stuck with my media queries and making this design responsive. Is it because I'm not using calc to evenly divide my flex items within the container? Or does calc have nothing to do with this problem?
If calc is irrelevant, how do I make this layout suitable for a media query with a max-width of 800px? When I test it out on different screen sizes using Dev Tools, there are large gaps.
I am trying to fix it by creating different media query outcomes, but now I'm wondering if there is a maximum amount of media queries I should be creating.
Your advice is gratefully appreciated.
You don't need to many containers, one parent div should be enough for the ".box" classed elements. With one parent, media queries would be much easier to control with different screen sizes.
I'm trying to make a 3 column grid where the 2nd column extends both Col-1 and Col-3 I've specifically made an image to show a better representation of what I'm trying to do.
I'm using bootstrap 5 and I've read their page on grid layout and offsets but I still yet to get my head around how to do this.
I keep getting stuck on how to extend the 2nd column through to the 3rd one.
I've done 0 CSS for this AT the current moment and there is nothing else in the code that interacts with the static content part of the page. So it is very easy to replicate.
My current code:
<!--Static Content-->
<div class="" id="static-content-container" style="background-color: yellow;">
<div class="row">
<div class="col-md-9">
<p>Column 1</p>
</div>
<div class="col-md">
<p>Column 2</p>
</div>
<div class="col-md-9">
<p>Column 3</p>
</div>
</div>
<!--/Static Content-->
If I missed something here for you to replicate the same as I have please let me know what you need and I'll happily provide that for you.
I think the only way to do this with flex would be to change your html structure and group columns one and three and use display: contents:
.row {
display: flex;
width: 100%;
}
.col-wrapper {
width: 50%;
display: flex;
flex-direction: column;
}
.col-2 {
flex-grow: 1;
background: green;
}
#media screen and (max-width:768px) {
.row {
flex-direction: column;
}
.col-wrapper {
display: contents;
width: 100%;
}
.col-1 {
order: 1;
}
.col-2 {
order: 2;
}
.col-3 {
order: 3;
}
}
<div class="row">
<div class="col-wrapper">
<div class="col col-1">col 1</div>
<div class="col col-3">col 3</div>
</div>
<div class="col-wrapper">
<div class="col col-2">col 2</div>
</div>
</div>
If you can't change the html structure, you're probably better off using css grid:
#media screen and (min-width: 768px) {
.wrapper {
display:grid;
grid-template-columns: repeat(2, 50%);
grid-gap:10px;
}
.col-2 {
background: green;
grid-row: 1 / 3;
grid-column: 2;
}
}
<div class="wrapper">
<div class="col-1">
col1
</div>
<div class="col-2">
col2
</div>
<div class="col-3">
col3
</div>
</div>
Trying to create a 2 column, 3 row flexbox container for a food menu. The product elements (which should be 2 per row) do not wrap when shrunk. I'm looking for a way to create a wrapping layout using flexbox. Also, what would be the best way to use Media Queries for the product title to be displayed when the layout is shrunk for mobile-size?
I'm attaching my jsfiddle code:
https://jsfiddle.net/5ksd34nf/#&togetherjs=Ix1LEBTca6
(keep in mind without the images, the design changes so I'm attaching photos)
The HTML is:
`
<section class="menu-page" id="Menu">
<div class="TitleWrapper">
<h1 class="title">Menu</h1>
</div>
<div class="menu-list">
<div class="product">
<div class="imgwrapper">
<img src="images/burger.jpg" alt="Burger" class="food-image">
</div>
<div class="text">
<div class="product-content">
<h3 class="name">Burgers</h3>
<h3 class="price">10 €</h3>
</div>
<div class="ptags">
<p class="allergens">Allergens:</p>
<p class="info">Milk, Gluten</p>
</div>
</div>
</div>
How can I space out the Price from the Name using flexbox?
Basically, you can do something like this:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
border: 1px solid gray;
width: 100%;
margin-bottom: 20px;
}
.flex-sub-item {
display: flex;
justify-content: space-between;
}
#media screen and (min-width: 400px) {
.flex-item {
width: calc((100% - 20px) / 2);
margin-right: 20px;
}
.flex-item:nth-child(2n) {
margin-right: 0;
}
}
<div class="flex-container">
<div class="flex-item">
<div class="flex-sub-item">
<div>Title</div>
<div>Price</div>
</div>
</div>
<div class="flex-item">
<div class="flex-sub-item">
<div>Title</div>
<div>Price</div>
</div>
</div>
</div>
so I have X divs and I want to put 2 divs in one row next to each other. If the screen size width is below n px there should be 1 div per row.
Currently I have this
#container {
display: flex;
}
.box {
width: 50px;
background: red;
}
#media(max-width: 300px) {
#container {
display: block;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2</div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
How can I limit the flex box to two divs per row?
Add 50% width on .box and flex-wrap:wrap on the container
Additionally, what you did by changing display: flex to block was not required. Just change the .box elements width to 100%
#container {
display: flex;
flex-wrap: wrap;
}
.box {
width: 50%;
background: red;
}
#media(max-width: 300px) {
.box {
width: 100%;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2</div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
Just add a property in your container class like
.container {
display: flex;
flex-wrap: wrap;
}
And in box class just specify the width of your box as 50% like
.box {
width: 50%;
background: red;
}
That should do the trick.
Flex will do a trick for you. flex-wrap: wrap for #container will make children wrap when necessary. .box with 50% and after breakpoint 100%.`
According to MDN:
The CSS flex-wrap property specifies whether flex items are forced into a single line or can be wrapped onto multiple lines. If wrapping is allowed, this property also enables you to control the direction in which lines are stacked.
If you are new to flexbox I recommend this guide.
Snippet
#container {
display: flex;
flex-wrap: wrap;
}
.box {
width: 50%;
background: red;
}
#media(max-width: 300px) {
.box {
width: 100%;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2 </div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
I'm working with a framework developed in-house which depends on a certain structure to our HTML. And one of the tricky things is that each row needs its own container with its own classes and data attributes.
So here's the problem. Without drastically changing the DOM, how can I make the flex box below render essentially like an HTML table would? Or is a table the only way? The solution will have to work in both IE11 and Chrome.
I'm trying to make it look like this...
Column A | Column B | Column C
1 | 2 | 3
section {
display: flex;
flex-wrap: wrap;
}
section .col {
flex: 1 1 auto;
}
section .line-break {
flex-basis: 100%;
width: 0px;
height: 0px;
overflow: hidden;
}
<html>
<head>
</head>
<body>
<section>
<header>
<div class="col">Column A</div>
<div class="col">Column B</div>
<div class="col">Column C</div>
</header>
<div class="line-break"></div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
</section>
</body>
</html>
header, .row {
display: flex; /* aligns all child elements (flex items) in a row */
}
.col {
flex: 1; /* distributes space on the line equally among items */
}
<section>
<header>
<div class="col">Column A</div>
<div class="col">Column B</div>
<div class="col">Column C</div>
</header>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
</section>
If the content you are going to present is of type tabular data, then a table is the proper way.
HTML 5.1 W3C Recommendation, 1 November 2016, 4.9 Tabular data
Given that you can't, or don't want to, alter the markup, this can be done using CSS Table, and with that easily swap between any display type such as flex, block, etc., or even float, using media query etc.
I also removed the <div class="line-break"></div> element, since you don't need, though if it is rendered by a component or similar, leaving it as is won't cause any problem.
Using CSS Table
section {
display: table;
width: 100%;
}
section > * {
display: table-row;
}
section .col {
display: table-cell;
}
<html>
<head>
</head>
<body>
<section>
<header>
<div class="col">Column A</div>
<div class="col">Column B</div>
<div class="col">Column C</div>
</header>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
</section>
</body>
</html>
If you still need, or have to, use Flexbox, this answer of mine mention the difference between CSS Table and Flexbox on two important features:
Can flexbox handle varying sizes of columns but consistent row height?
Updated, a sample showing some useful Flexbox stuff, with varying width's and span columns.
Using Flexbox
.tbl {
display: flex;
flex-direction: column;
}
.row {
display: flex;
min-height: 50px;
}
.cell {
flex: 4;
border: 1px solid red;
}
.cell:nth-child(1) {
flex: 1;
}
.cell:nth-child(2) {
flex: 2;
}
.cell.span4-5 {
flex: 8 24px; /* col 4,5 flex-grow/border/padding */
}
.cell.span3-4 {
flex: 8 24px; /* col 3,4 flex-grow/border/padding */
}
.cell.span3-5 {
flex: 12 36px; /* col 3,4,5 flex-grow/border/padding */
}
.row:first-child .cell {
display: flex;
justify-content: center; /* center horiz. */
align-items: center; /* center vert. */
}
.row .cell {
padding: 5px;
box-sizing: border-box;
}
<div class="tbl">
<div class="row">
<div class="cell">ID </div>
<div class="cell">Nr </div>
<div class="cell">Header 1 </div>
<div class="cell span4-5"> Header 2 </div>
</div>
<div class="row">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
</div>
<div class="row">
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell span3-5">Content</div>
</div>
<div class="row">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell span3-4">Content</div>
<div class="cell">Content</div>
</div>
</div>
This code works for me:
* {
box-sizing: border-box;
}
body, html {
height: 100%;
margin: 0;
}
#container {
width: 400px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
background-color: lightgrey;
padding: 10px;
}
.shelf {
flex: 1 1 auto;
width: 100%;
margin-bottom: 10px;
border: 1px solid black;
background-color: lightgreen;
display: flex;
flex-direction: row;
}
.shelf:last-child {
margin-bottom: 0;
}
.labelbox {
flex: 0 0 35%;
}
.valuebox {
flex: 0 0 65%;
}
<div id="container">
<div class="shelf">
<div class="labelbox">Name: </div> <div class="valuebox">Barry Carter</div>
</div>
<div class="shelf">
<div class="labelbox">DOB:</div><div class="valuebox">10/12/1980</div>
</div>
<div class="shelf">
<div class="labelbox">
Description:
</div>
<div class="valuebox">
This content goes on and on and will force the height to expand. And the label box to the left will
"move" with it. There need not be much of a relation other than that their parent div/flex-container is
getting taller as well.
</div>
</div>
<div class="shelf">
<div class="labelbox">Group:</div><div class="valuebox">Advanced</div>
</div>
<div class="shelf">
<div class="labelbox">End Date:</div><div class="valuebox">2020-09-20</div>
</div>
</div>
Use CSS Grid. You can style any table the way you like.
Keep in mind If your table is more than 700 rows, the fram rate will start to drop, no matter what js framework you use. react, angular, vue or vanila JS. the scrolling will get real laggy.
And the maximum you row can use is 1000. More than that the extra row will create bad graphic. But you wont reach 1000 anyway, because at 700th row, the scrolling speed, starts to get bad.
If somehow you need to display more than 1000 rows, you will visualized lib. Every js framework has a lib to do so. Basically, it will render the rows in the view port. The rows that not in the view port will not be rendered. They will only be rendered when user scrolls.
This is year 2021, chances you read this answer in the future, the browsers vendor might probably fix the performance of 1000 rows, they might even extend that limit. So try it out.