I am trying to set up a responsive grid so that when you click on a grid-item, it fills the horizontal space of its row and pushes the other items either above it or below it. To fill the remaining empty space.
Here's my current code which does fill the row but leaves empty space.
JSFIDDLE
$(".box").click(function() {
$(this).toggleClass("enlarge");
});
body {
margin: 0;
}
.enlarge {
flex-basis: 100% !important;
}
.boxes {
display: flex;
flex-wrap: wrap;
}
.boxes .box {
flex-basis: calc((100% / 3) - 2rem);
margin: 1rem;
height: 200px;
box-sizing: border-box;
text-align: center;
transition: all 1s;
background-color: rgb(220, 220, 220);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="boxes">
<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>
Try this...
$(".box").click(function(){
$('.box').removeClass("enlarge");
$(this).toggleClass("enlarge");
});
body {
margin: 0;
}
.enlarge {
flex-basis: 100% !important;
}
.boxes {
display: flex;
flex-wrap: wrap;
}
.box {
flex-basis: calc((100% / 3) - 2rem);
flex-grow:1;
display:flex;
margin: 1rem;
height: 200px;
box-sizing: border-box;
text-align: center;
transition: all 1s;
background-color: rgb(220, 220, 220);
align-items:center;
justify-content:center;
}
<div class="boxes">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Related
I have also examined various documents but could not understand the logic in the code below. Let's say we gave 25% for Flex-Basis. As you can see when we give Flex-Grow 0.25 to the other box with the same features, the dimensions are different, but shouldn't it be the same?
Also, what is the difference between using the flex basis as a percentage and using flexible growth? Thank you very much for your interest in advance.
html body {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container {
width: 90%;
margin: 2em auto;
height: 35px;
display: flex;
background: rgb(51, 153, 73);
}
.box {
flex-basis: auto;
background: rgb(160, 166, 221);
}
.second {
flex-basis: 25%;
}
.third {
flex-grow: 0.25;
}
<div class="container">
<div class="box first">First Box</div>
</div>
<div class="container">
<div class="box second">Second Box</div>
</div>
<div class="container">
<div class="box third">Third Box</div>
</div>
You can have the same result if you define flex-basis:0 with flex-grow.
flex-basis:25% means take 25% of the total width while flex-grow:0.25 means take 25% of the free space + the initial width. If you make the initial width 0 (using flex-basis:0) then 25% of the free space will be equal to 25% of the total width
html body {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container {
width: 90%;
margin: 2em auto;
height: 35px;
display: flex;
background: rgb(51, 153, 73);
}
.box {
flex-basis: auto;
background: rgb(160, 166, 221);
}
.second {
flex-basis: 25%;
}
.third {
flex-grow: 0.25;
flex-basis: 0;
}
<div class="container">
<div class="box first">First Box</div>
</div>
<div class="container">
<div class="box second">Second Box</div>
</div>
<div class="container">
<div class="box third">Third Box</div>
</div>
This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 2 years ago.
I want to make a website with a list using bootstrap + css's flexbox, where the item list should have a height up to the screen's bottom not overflowing it.
I was able to get a working solution like this:
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
}
body {
background-color: black;
}
.wrapper .content-wrapper .content {
flex: 1 1 1px;
}
.wrapper .content-wrapper .content {
display: flex;
flex-direction: column;
}
.wrapper .content-wrapper {
width: 100%;
}
.wrapper {
display: flex;
height: 100%;
}
.side {
background-color: blue;
display: flex;
flex-direction: column;
width: 224px;
}
.content-wrapper {
display: flex;
flex-direction: column;
}
.topbar {
height: 100px;
background-color: aqua;
}
.main {
flex: 1 1 1px;
background-color: pink;
overflow-y: scroll;
}
.item {
background-color: white;
border-style: solid;
height: 200px;
}
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="wrapper">
<div class="side"></div>
<div class="content-wrapper">
<div class="content">
<div class="topbar"></div>
<div class="main">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
</div>
</div>
</div>
</div>
</body>
</html>
With the help from this link:
Prevent flex item from exceeding parent height and make scroll bar work
As you can see the scroll bar's bottom arrow is at the end of the screen. (Expected behaviour)
However, when I try to expand my main div into 2 more columns (using bootstrap + flex):
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
}
body {
background-color: black;
}
.wrapper .content-wrapper .content {
flex: 1 1 1px;
}
.wrapper .content-wrapper .content {
display: flex;
flex-direction: column;
}
.wrapper .content-wrapper {
width: 100%;
}
.wrapper {
display: flex;
height: 100%;
}
.side {
background-color: blue;
display: flex;
flex-direction: column;
width: 224px;
}
.content-wrapper {
display: flex;
flex-direction: column;
}
.topbar {
height: 100px;
background-color: aqua;
}
.main {
flex: 1 1 1px;
background-color: pink;
display: flex;
}
.header {
background-color: yellow;
overflow-y: scroll;
height: 100%;
}
.details {
background-color: crimson;
}
.item {
background-color: white;
border-style: solid;
height: 200px;
}
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="wrapper">
<div class="side"></div>
<div class="content-wrapper">
<div class="content">
<div class="topbar"></div>
<div class="main">
<div class="header col-lg-4">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
</div>
<div class="details col-lg-8"></div>
</div>
</div>
</div>
</div>
</body>
</html>
Now the item list overflow below the bottom of the screen. (see the bottom arrow of the scrollbar is missing)
Any help would be appreciated.
You have a couple of fixed lengths in your code, including:
.side {
width: 224px;
}
.topbar {
height: 100px;
}
These hard limits make the solution to overflow problems relatively simple, since the easiest way to trigger a scrollbar is to create an overflow condition, which is best accomplished with a fixed length.
In this case, the .topbar { height: 100px } is the key to the scrollbar on the sibling element.
(Note that you need to disable flex-shrink on these lengths for the values to always be respected.)
Here's a revised version of your code, with various adjustments for greater performance and efficiency.
body {
margin: 0;
background-color: black;
}
.wrapper {
display: flex;
height: 100vh;
}
.side {
/* width: 224px; */ /* will not be respected without adding `flex-shrink: 0` */
flex: 0 0 224px; /* new; flex-grow, flex-shrink, flex-basis */
background-color: blue;
display: flex;
flex-direction: column;
}
.content-wrapper {
flex: 1; /* consume remaining space */
display: flex;
flex-direction: column;
}
.wrapper .content-wrapper .content {
display: flex;
flex-direction: column;
}
.topbar {
flex: 0 0 100px;
/* height: 100px; */
background-color: aqua;
}
.main {
height: calc(100vh - 100px); /* new; sets overflow condition */
background-color: pink;
display: flex;
}
.header {
background-color: yellow;
overflow-y: scroll;
/* height: 100%; */
}
.details {
background-color: crimson;
}
.item {
background-color: white;
border-style: solid;
height: 200px; /* not a flex item, so no need to disable flex-shrink */
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="wrapper">
<div class="side"></div>
<div class="content-wrapper">
<div class="content">
<div class="topbar"></div>
<div class="main">
<div class="header col-lg-4">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
</div>
<div class="details col-lg-8"></div>
</div>
</div>
</div>
</div>
jsFiddle demo
What I thought would be a simple layout turned out to be something I'm not able to accomplish yet.
I need the grid to be responsive and spread from one side to another (it has to be aligned with the text and box above).
I tried a few options, I commented them out for easier checking:
.big-container {
padding: 0 20%;
}
.header {
width: 100%;
height: 50px;
background-color: blue;
}
.container {
border: 1px solid black;
/* display: flex;
flex-wrap: wrap;
*/
/* display: flex;
flex-wrap: wrap;
justify-content: space-between;
*/
}
.box {
border: 1px solid black;
width: 100px;
height: 30px;
background-color: yellow;
/* float: left;
margin-left: 10px; */
}
<div class="big-container">
<div class="header"></div>
<p>Text</p>
<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>
</div>
I tried with flex but it doesn't sort nicely the last row, flex-wrap: wrap and float:left with some margin doesn't align correctly to the left.
If you use flexbox and set justify-content: space-between then last row will also have the same spacing instead of left align. Instead you can use grid-layout for this.
.big-container {
padding: 0 20%;
}
.header {
width: 100%;
height: 50px;
background-color: blue;
}
.container {
border: 1px solid black;
display: grid;
justify-content: space-between;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-gap: 10px;
}
.box {
border: 1px solid black;
height: 30px;
background-color: yellow;
}
<div class="big-container">
<div class="header"></div>
<p>Text</p>
<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>
</div>
I'm trying to get an element to have items aligned to the right, and all overflowing elements to be hidden but accessed by scrollbar.
But it seems like the scrollbar disappears when specifying justify-content: flex-end. Why is that, and how do I fix it?
Here is demo: https://jsfiddle.net/efguz4mp/1/
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
overflow: auto;
justify-content: flex-end;
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<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>
...and here is demo without justify-content: flex-end;: https://jsfiddle.net/efguz4mp
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
overflow: auto;
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<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>
When an overflow occur to the left (or top), a scroll doesn't get rendered, and the reason is that a HTML document's normal flow is left-to-right (top-to-bottom).
Flexbox has a row-reverse direction, which will solve that, thought 2 things comes with that:
One need to reorder the items or use an inner wrapper
I.a. Firefox and Edge doesn't show the scroll (possible bug)
Stack snippet
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
flex-direction: row-reverse;
overflow: auto;
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
/* no wrapper */
.row > .box:nth-child(1) { order: 6; }
.row > .box:nth-child(2) { order: 5; }
.row > .box:nth-child(3) { order: 4; }
.row > .box:nth-child(4) { order: 3; }
.row > .box:nth-child(5) { order: 2; }
.row > .box:nth-child(6) { order: 1; }
/* wrapper */
.inner {
display: flex;
}
<div class="row">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<div><br><br></div>
<div class="row">
<div class="inner">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
</div>
Possible workarounds are:
Use direction: rtl to change the flow direction
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
overflow: auto;
direction: rtl;
}
.inner {
display: flex;
direction: ltr;
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<div class="inner">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
</div>
Use transform to flip the row element
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
overflow: auto;
transform: scale(-1,1); /* flip horizontally */
}
.inner {
display: flex;
transform: scale(-1,1); /* reset so items is not backwards */
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<div class="inner">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
</div>
Use a script on page load to scroll to the right
window.addEventListener("load", function(e) {
var el = document.querySelector(".row");
el.scrollLeft = el.scrollWidth;
});
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
overflow: auto;
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
The main problem is that you're dealing with a contradiction:
The justify-content property is designed to distribute extra space in the container.
However, an overflow condition occurs when there is no space left in the container.
Basically, justify-content and overflow have no association. The former applies only inside the container. The latter applies only outside the container.
With justify-content: flex-end, the flex items must be packed at the end of the container (not the end of the flex-start overflow area).
If the end-aligned items are too big to fit in the container, they will overflow on the start side, which is what you're seeing in your layout. But because the overflow property only applies in the direction of the writing mode (LTR, in this case), scrollbars are not rendered (more details).
So I would suggest forgetting about justify-content to make this layout work.
Instead, consider this: Use an invisible spacer item to push your content items to the right.
.row {
display: flex;
overflow: auto;
max-width: 500px;
background: #DADADA;
}
.box {
flex: 0 0 200px;
height: 40px;
margin: 4px 10px;
background: red;
}
.row::before {
content: "";
flex: 0 0 400px;
visibility: hidden;
}
<div class="row">
<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>
You'll notice that the last item margin collapses. That issue is explained here:
Last margin / padding collapsing in flexbox
Here's how I would recommend you do it
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
flex: 1;
display: flex;
overflow: auto;
}
.box {
display: flex;
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<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>
I would like an intro section on the left side of a .container and a side bar on the right.
On the left side underneath the .intro section I want there to be four divs equally spaced like a grid.
I'm having problems with getting the "grid set up". I think part of the problem is that the parent has some flexbox attribute effecting the children.
Requirement : The intro section should be centered in the .left-side and the "grid" should not be centered the boxes should take up as much space as necessary to fit 2 on a row with margins in between. The .intro should be 80 percent of the width of the leftside.
I don't want to do any major changes to the structure this is just a small sample of how my project is set up.
.container{
width: 80%;
margin: 0 auto;
display: flex;
}
.left-side{
flex:8;
display: flex;
justify-content:center;
flex-wrap: wrap;
}
.side-bar{
flex: 2;
height: 100vh;
background: powderblue;
}
.intro{
flex:3;
width:80%;
height: 300px;
background: skyblue;
}
.box{
background: red;
width: 45%;
height: 100px;
flex:4;
border:1px solid orange;
}
<div class="container">
<div class="left-side">
<div class="intro">
intro
</div>
<div class="recent">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
</div>
<div class="side-bar">
sidebar
</div>
Flex items can also be flex containers. This enables you to nest multiple containers, with flex-direction: row or column, in a larger container.
For your layout, you can build a column consisting of two flex items. The first item (.intro) has 80% width and can be centered horizontally. The second item (.recent) can be a flex container with four items arranged in a 2x2 grid.
.container {
width: 80%;
margin: 0 auto;
display: flex;
justify-content: center;
height: 100vh;
}
.left-side {
flex: 4;
display: flex;
flex-direction: column;
}
.side-bar {
flex: 1;
background: powderblue;
}
.intro {
flex: 3;
height: 300px;
width: 80%;
margin: 0 auto;
background: skyblue;
}
.recent {
display: flex;
flex-wrap: wrap;
background-image: url("http://i.imgur.com/60PVLis.png");
background-size: contain;
}
.box {
margin: 5px;
flex-basis: calc(50% - 10px);
height: 100px;
box-sizing: border-box;
background: red;
}
body { margin: 0; }
<div class="container">
<div class="left-side">
<div class="intro">intro</div>
<div class="recent">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
</div>
<div class="side-bar">
sidebar
</div>
</div>