Given a flexbox container, how could I make sure that, if children have lots of content, they don't overflow the container?
.container {
display: flex;
flex-direction: column;
background-color: #ccc;
height: 210px;
width: 200px;
}
.child {
display: flex;
width: 100px;
}
.first {
background-color: rgba(255, 0, 0, 0.2);
}
.second {
background-color: rgba(0, 255, 0, 0.2);
}
.third {
background-color: rgba(0, 0, 255, 0.2);
}
<div class="container">
<div class="first child">first first first first first first first</div>
<div class="second child">second second second second second second second second second second second second second second second second second second second</div>
<div class="third child">third</div>
</div>
The children overflow their parent element because their intrinsic height (the height of their contents) is larger than the parent's height. You can advise the browser to ignore the intrinsic height by setting min-height: 0 on the child elements. If you add overflow: hidden the result should be what you seem to expect:
.container {
display: flex;
flex-direction: column;
background-color: #ccc;
height: 210px;
width: 200px;
}
.child {
width: 100px;
min-height: 0;
overflow: hidden;
}
.first {
background-color: rgba(255, 0, 0, 0.2);
}
.second {
background-color: rgba(0, 255, 0, 0.2);
}
.third {
background-color: rgba(0, 0, 255, 0.2);
}
<div class="container">
<div class="first child">first first first first first first first</div>
<div class="second child">second second second second second second second second second second second second second second second second second second second</div>
<div class="third child">third</div>
</div>
The children get height distributed among them proportionally to their content height. Overflowing content is hidden.
You could use overflow: auto on child element. In case you want to hide overflow only on largest item then you could use flex: 1 on that item.
.container {
display: flex;
flex-direction: column;
background-color: #ccc;
height: 210px;
width: 200px;
}
.child {
display: flex;
width: 100px;
overflow: auto;
}
.first {
background-color: rgba(255, 0, 0, 0.2);
}
.second {
background-color: rgba(0, 255, 0, 0.2);
flex: 1;
}
.third {
background-color: rgba(0, 0, 255, 0.2);
}
<div class="container">
<div class="first child">first first first first first first first</div>
<div class="second child">second second second second second second second second second second second second second second second second second second second</div>
<div class="third child">third</div>
</div>
flex has
Three values: flex-grow | flex-shrink | flex-basis;
you should apply particular max-height for first child.
.first {
background-color: rgba(255, 0, 0, 0.2);
flex: 0 1 1;
max-height:70px;
}
otherwise if first div height increases it will dominate on other divs.
.container {
display: flex;
flex-direction: column;
background-color: #ccc;
height: 210px;
width: 200px;
}
.child {
width: 100px;
overflow:hidden;
}
.first {
background-color: rgba(255, 0, 0, 0.2);
flex: 0 1 auto;
}
.second {
background-color: rgba(0, 255, 0, 0.2);
flex: 0 1 1;
}
.third {
background-color: rgba(0, 0, 255, 0.2);
flex: 0 1 1;
}
<div class="container">
<div class="first child">first first first first first first first</div>
<div class="second child">second second second second second second second second second second second second second second second second second second second</div>
<div class="third child">third</div>
</div>
Using min-height: 210px; instead of explicitly setting a height on your container gives you the desired affect by letting an extra long child to extend its height.
Also, great question writing! Nice to see diagrams of whats happening vs expected, ect.
Related
I want all items to be equally wide (as wide as the widest item) and wrap to the next line when there is no more space. My following code is however not working because the width of the items is just being set to 1/7th of the container instead of the width of the content inside it. How can I fix?
.flex-container {
display: flex;
flex-wrap: wrap;
background-color: rgba(255, 0, 0, 0.3);
max-width: 25rem;
gap: 1rem;
padding: 1rem;
}
.flex-item {
flex: 1 1 auto;
width: 0;
box-sizing: border-box;
background: rgba(0, 0, 255, 0.3);
}
<div class='flex-container'>
<div class='flex-item'>A</div>
<div class='flex-item'>AB</div>
<div class='flex-item'>ABC</div>
<div class='flex-item'>ABCD</div>
<div class='flex-item'>ABCDE</div>
<div class='flex-item'>ABCDEF</div>
<div class='flex-item'>ABCDEFG</div>
</div>
Set max-width value in flex-basis property
.flex-container {
display: flex;
flex-wrap: wrap;
background-color: rgba(255, 0, 0, 0.3);
max-width: 25rem;
gap: 1rem;
padding: 1rem;
}
.flex-item {
flex-basis: 8ch;
box-sizing: border-box;
background: rgba(0, 0, 255, 0.3);
}
<div class='flex-container'>
<div class='flex-item'>A</div>
<div class='flex-item'>AB</div>
<div class='flex-item'>ABC</div>
<div class='flex-item'>ABCD</div>
<div class='flex-item'>ABCDE</div>
<div class='flex-item'>ABCDEF</div>
<div class='flex-item'>ABCDEFG</div>
</div>
This question already has answers here:
Why does the outer <div> here not completely surround the inner <div>?
(2 answers)
Closed 3 years ago.
I have an element with display: grid;. The parent of the grid has a max-size and will allow the grid to be scrolled if needed.
The issue is that the grid element does not expand to the size of its children. If you scroll right you can see that the color of .grid (red) ends and .b (blue) keeps going. I'm probably missing a property I don't know about?
.wrapper {
max-width: 200px;
overflow: auto;
}
.grid {
max-width: none;
display: grid;
grid-template-columns: 150px 150px;
background: red;
border-bottom: 3px solid red;
}
.a {
background: rgba(0, 255, 0, 0.5);
border-bottom: 3px solid green;
}
.b {
background: rgba(0, 0, 255, 0.5);
border-bottom: 3px solid blue;
}
<div class="wrapper">
<div class="grid">
<div class="a">a</div>
<div class="b">b</div>
</div>
</div>
You can try inline-grid option in display property.
When you use inline-grid then all direct children of the grid container automatically become grid items.
.grid {
max-width: none;
display: inline-grid;
grid-template-columns: 150px 150px;
background: red;
border-bottom: 3px solid red;
}
https://jsfiddle.net/aviboy2006/vLd850os/
Reference : https://www.w3schools.com/css/css_grid.asp
I am trying to animate a few flex items which should collapse just beside one another when they are scaled down.
For example: see this pen.
.flex-cont {
display: flex;
}
.flex-item {
margin: 0 10px;
background: red;
padding: 10px;
transform: scale(0.25);
}
<div class='flex-cont'>
<div class='flex-item'>
Test
</div>
<div class='flex-item'>
Test
</div>
<div class='flex-item'>
Test
</div>
</div>
As you can see the items have a gap between them. I want them to be just beside each other. How can I achieve this?
All you need to do is make your margin negative on .flex-item. From your example, setting it to...
.flex-item {
margin: 0 -13px;
background: red;
padding: 10px;
transform: scale(0.25);
}
did the trick.
EDIT
If you want to maintain the position of leftmost item then...
.flex-item {
margin:0 -46px 0px 10px;
background:red;
padding:10px;
transform:scale(0.25);
}
Markup:
<div class="playground">
<div class="red">
<div class="child">I don't need all this space, but my parents are greddy. : (</div>
</div>
<div class="blue">I want to grow big!</div>
</div>
Stylesheet:
.playground {
width: 500px; height: 500px; background: #ccc; display: flex; flex-direction: column;
}
.red,
.blue {
width: 100%;
}
.red {
flex: 1; background: rgba(255,0,0,.5);
.child {
background: rgba(255,255,255,.5); padding: 10px; margin: 10px;
}
}
.blue {
background: rgba(0,0,255,.5); min-height: 100px; max-height: 300px;
}
http://jsbin.com/waset/1/
In the above example,
Red container is set to use all available space (flex-grow).
Red container is sharing space with blue.
Blue has max-height: 300px.
Red content is not taking all of the height. If red wasn't greedy, it would give away extra 200px to blue.
How to make red not greedy?
Try adding flex:1; to .blue
By the way, you misspelled width in .red,.blue
If I'm understanding you correctly, you can use flex-grow on both .red and .blue and give blue a very large value. Using flex-grow instead of the flex shorthand will default flex-basis to auto. As a result, the flex-basis will be based on the content and then only after the initial content is taken into consideration will leftover space be distributed.
The very large value on .blue will cause it to consume nearly all remaining space up until it reaches its max-width.
.red {
flex-grow: 1;
background: rgba(255, 0, 0, .5);
.child {
background: rgba(255, 255, 255, .5);
padding: 10px 10px;
margin: 10px;
}
}
.blue {
flex-grow: 999;
background: rgba(0, 0, 255, .5);
min-height: 100px;
max-height: 300px;
}
Is this what you are looking for? I can't remember where I learned this technique, but I will post credits when I come across the Website again. I created two flexboxes, a blue and red, and each one expands in size when you hover over them. Hope this helps.
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.flx
{
width: 400px;
height: 200px;
font: 12px auto;
display: -webkit-flex;
-webkit-flex-direction: column;
display: flex;
flex-direction: column;
}
.flx > div
{
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
width: 50px;
-webkit-transition: width 0.2s ease-out; /*adjust speed of size change*/
transition: width 0.2s ease-out;
}
.flx > div:nth-child(1){ background : red; }
.flx > div:nth-child(2){ background : blue; }
.flx > div:hover /*adjust size when you hover*/
{
width: 200px;
}
</style>
</head>
<body>
<div class="flx">
<div>red box</div>
<div>blue box</div>
</div>
</body>
</html>
I think you can set flex: 1; instead of flex-grow to .red and .blue. This works in Facebook's Yoga Layout.
I've got three divs next to eachother and without content in them they align perfect.
However once I place another div inside the first one, the other 2 (middle and right) are pushed down. The inner div is smaller than his parent (the left one), so I don't see why it's pushing down.
This is the global wrapper:
.main-content {
width: 1100px;
min-height: 500px;
margin: auto;
margin-top: 100px;
}
The left div:
.left-menu {
width: 250px;
height: 100%;
margin-left: 20px;
margin-top: 30px;
background-color: rgba(255, 255, 255, 0.95);
display: inline-block;
}
The middle:
.main {
width: 500px;
min-height: 500px;
background-color: rgba(255, 255, 255, 0.95);
display: inline-block;
margin-left: 20px;
}
And the right div:
.right-pane{
width: 250px;
margin-left: 15px;
margin-top: 30px;
background-color: rgba(255, 255, 255, 0.95);
display: inline-block;
}
At the moment they are classes rather than id's, but that shouldn't make a difference I guess?
Now once we place a div like the following inside left-menu the other 2 are pushed down:
<div class="leftmenu-item">
<p class="redtext">This is a quite a long sentence hehehe</p>
<p class="datetext">Date: 25-07-2013</p>
<p class="timetext">Time: 13:00</p>
</div>
css:
.leftmenu-item {
height: 100px;
width: 200px;
}
The other classes of the paragraphs only set a font type and a color.
So the whole structure looks like this:
<div class="main-content">
<div class="left-menu">
<div class="leftmenu-item">
<p class="redtext">This is a quite a long sentence hehehe</p>
<p class="datetext">Date: 25-07-2013</p>
<p class="timetext">Time: 13:00</p>
</div>
</div>
<div class="main">
Testy
</div>
<div class="right-pane">
Hello.
</div>
</div>
I've tried using float, but that is not working well either. If anyone knows a solution, i'd be happy
add vertical-align:top; to those div.
By default they are aligned from their baseline.
It may be a typo:
You have missed class selector for main