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>
Related
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>
I am being asked to generate html that looks like the mock up image below. I have some sample HTML and CSS that generate a grid of squares etc. I need to be able convert this grid to look like the mock up image attached below. Preferably would like to use CSS only but I am not limited to using only CSS. My snippet doesn't uses bootstrap but I have access to Bootstrap 4.
* {box-sizing: border-box;}
.wrapper {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
}
.wrapper > div {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
.wrapper div:nth-child(1) {
grid-column: 1/1;
grid-row: 1/5;
}
.wrapper div:nth-child(2) {
grid-column: 2/4;
grid-row: 1/3;
}
.wrapper div:nth-child(3) {
grid-column: 2/2;
grid-row: 3/5;
}
.wrapper div:nth-child(4) {
grid-column: 3/3;
grid-row: 3/5;
}
.wrapper {
display: grid;
grid-template-columns: repeat(2,4);
grid-auto-rows: 100px;
grid-auto-flow: dense;
}
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
</div>
My solution is close but the second row and third column doesn't match.
This can be done easily with the Bootstrap 4 grid system. The red border is for visualisation. From here you can add the correct padding/margin to the column contents.
<div class="container">
<div class="row">
<div class="col-3 red-border">
Block 1
</div>
<div class="col">
<div class="row">
<div class="col red-border">
Block 2
</div>
</div>
<div class="row">
<div class="col-4 red-border">
Block 3
</div>
<div class="col red-border">
Block 4
</div>
</div>
</div>
</div>
</div>
<style>
.red-border {
border: 1px solid red;
}
</style>
You can make this with Bootstrap grid
<div class="container">
<div class="row no-gutters">
<div class="col-md-4"></div>
<div class="col-md-8">
<div class="row">
<div class="col-md-12"></div>
</div>
<div class="row">
<div class="col-md-5"></div>
<div class="col-md-6"></div>
</div>
</div>
</div>
Find more details here : https://getbootstrap.com/docs/4.0/layout/grid/
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.
Newbie to flex use/web development.
I currently have 6 boxes within a flex container ordered like this for mobile devices:
Mobile view
with code more or less like this (CSS not included, but the class “box” is the grey box you see above):
<div class="flex-container">
<div class=“box item” />
<div class=“text item”>
<h4>Text</h4>
</div>
<div class=“box item” />
<div class=“text item”>
<h4>Text</h4>
</div>
<div class=“box item” />
<div class=“text item”>
<h4>Text</h4>
</div>
</div>
This is what I want for mobile devices!
For desktop however, I’d like to achieve this: Desktop View
Currently, the only way I’m achieving this is by using this unappealing flex order css:
item:nth-of-type(1) {order:1;}
item:nth-of-type(2) {order:2;}
item:nth-of-type(3) {order:4;}
item:nth-of-type(4) {order:3;}
item:nth-of-type(5) {order:5;}
item:nth-of-type(6) {order:6;}
My question is, is there a way to achieve my desired goal (i.e. switching the order of items 3 and 4) without having to order every single item in the container creating a yucky, repetitive block of code?
You can accomplish that with only 2 CSS selectors, and with order defaults to 0, we re-position item 3 and 5/6, here done with a media query for screens wider than 600px, to 1 and 2.
.item:nth-of-type(3) { order:1; } /* put 3 after 4 */
.item:nth-of-type(n+5) { order:2; } /* put 5,6 after 3 */
Stack snippet
.flex-container { display: flex; flex-wrap: wrap; }
.item { height: 50px; flex-basis: 100%; }
.box { background: lightgray; }
#media (min-width: 600px) {
.item { flex-basis: 50%; }
.item:nth-of-type(3) { order:1; } /* put 3 after 4 */
.item:nth-of-type(n+5) { order:2; } /* put 5,6 after 3 */
}
<div class="flex-container">
<div class="box item"></div>
<div class="text item">
<h4>Text</h4>
</div>
<div class="box item"></div>
<div class="text item">
<h4>Text</h4>
</div>
<div class="box item"></div>
<div class="text item">
<h4>Text</h4>
</div>
</div>
As far as I know if you reorder items, you need to explicitly order items after the re-ordered items. So you could probably do:
item:nth-of-type(3) {order:4;}
item:nth-of-type(4) {order:3;}
item:nth-of-type(5) {order:5;}
item:nth-of-type(6) {order:6;}
If you only ever want to switch those two, you could wrap them in another flex container and simply switch ordering within. That way your outer flow won't have to be redefined, and you could set up the container to be reused in other areas where you need to achieve the same thing.
<div class="container">
<div class="item one">One</div>
<div class="item two">Two</div>
<div class="item three">Three</div>
<div class="switch">
<div class="item four">Four</div>
<div class="item five">Five</div>
</div>
<div class="item six">Six</div>
<div class="item seven">Seven</div>
</div>
.item {
flex: 1 0 100%;
line-height: 39px;
height: 40px;
width: 100%;
background: #cecece;
margin-bottom: 10px;
text-align: center;
}
.container {
display: flex;
flex-wrap: wrap;
}
.switch {
display: flex;
flex-wrap: wrap;
flex: 1 0 100%;
}
#media (min-width: 400px) {
.switch .item:nth-of-type(1) {
order: 2;
}
}
fiddle
In addition to TripWire's answer, you need not to set a different order number for every <div> after the 4th one.
.item:nth-of-type(3), .item:nth-of-type(4) ~ .item {order:100;}
.item:nth-of-type(4) {order:50;}
A pen: https://codepen.io/israfel/pen/eEbWWG
I have a normal html/css layout as below. However, for max-width 480px, I want to reverse the order of section1 and section2. I use bootstrap.
I want section2 row to come before section1 row. How can I do that?
<div class="container" id="content">
<div class="row" id="section1">
</div>
<div class="row" id="section2">
</div>
<div class="row" id="section3">
</div>
</div>
<footer>
</footer>
You can use flexbox and alter the order property on the child you want to re-order.
#media (max-width: 480px) {
.container {
display: flex;
flex-direction: column;
}
#section2 {
order: -1;
}
}
<div class="container" id="content">
<div class="row" id="section1">1
</div>
<div class="row" id="section2">2
</div>
<div class="row" id="section3">3
</div>
</div>
Here is a flexbox option using order at a certain media query to only move the 2nd box before the first. The rest of the order would be the same:
.container {
display: flex;
flex-wrap: wrap;
}
.row {
width: 100%;
height: 3em;
border: 1px solid red;
order: 2;
}
#media (max-width: 600px) {
#section2 {
order: 1;
}
}