I am learning CSS flexbox and was doing a simple layout where I wanted the first flex child to displayed with 100% width of the parent and rest flex items wrapping below. Also, the wrapped flex items should occupy width in a specific ratio (easy to set with 'flex' property).
To do this I set "flex-basis" property of first flex item to 100% and set flex property of next 2 to the ratio I want. Here is what the pertinent CSS looks like (link to complete fiddle is below):
.main{
max-width: 1000px;
margin: 100px auto;
display: flex;
flex-flow: row wrap;
}
/*using ususal shorthand notation*/
.flex-item:nth-child(1) {
flex:1 100%;
}
.flex-item:nth-child(2) {
flex:2;
}
.flex-item:nth-child(3) {
flex:3;
}
This should set the first item's width to 1000px and for the next two as 400px and 600px respectively; wrapped and displayed below the first child.
But for some reason the CSS breaks, and the 2nd and 3rd items are pushed outside main container.
What more strange is that adding margin to the flex items fixes the whole thing and I don't understand how this is happening (I must be doing something stupid). Even addding some border or padding to the '.flex-item' rule works.
.flex-item{
margin: 5px;
}
Here is the JS Fiddle. You can try un-commenting the '.flex-item' rule in CSS to see what is going on.
I was lazy not to add the any prefixes (since almost every new browser supports it) ,but the problem is same across latest FF, IE and chrome.
The second and third elements have 0 width, so they can fit in any place ..
That's way they stay in the first line.
just set 1px for basis, and they will be in the second row
*{
box-sizing: border-box;
padding: 0;
margin: 0;
}
body{
font-family: 'Raleway', Helvetica, sans-serif;
font-size: 14px;
font-weight: 300;
color: #555;
}
.main{
max-width: 1000px;
margin: 20px auto;
border: 1px dotted #999;
padding: 20px;
display: flex;
flex-flow: row wrap;
}
/* adding any border, margin, padding rules here fixes it */
.flex-item:nth-child(2) {
flex:2 1px;
background-color: lightyellow;
}
.flex-item:nth-child(3) {
flex:3 1px;
}
.flex-item:nth-child(1) {
flex:1 100%;
}
<div class="main">
<p class="flex-item">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin non consequat lorem. In dignissim mauris eu est commodo, ac ullamcorper dui facilisis. Sed feugiat eros quis facilisis feugiat. Pellentesque eu quam egestas, facilisis augue eu, aliquam mi. Nunc nunc metus, eleifend id finibus sit amet, imperdiet eget mi.
</p>
<p class="flex-item">
In dignissim mauris eu est commodo, ac ullamcorper dui facilisis. Sed feugiat eros quis facilisis feugiat. Pellentesque eu quam egestas, facilisis augue eu, aliquam mi. Nunc nunc metus, eleifend id finibus sit amet, imperdiet eget mi.
</p>
<p class="flex-item">
In dignissim mauris eu est commodo, ac ullamcorper dui facilisis. Sed feugiat eros quis facilisis feugiat. Pellentesque eu quam egestas, facilisis augue eu, aliquam mi. Nunc nunc metus, eleifend id finibus sit
.flex-item:nth-child(2) {
flex:2 1px;
}
.flex-item:nth-child(3) {
flex:3 1px;
}
Related
This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 2 years ago.
Child flex item is overflowing the width of the parent container. I tried setting min-width:0 as well but still it is not working.
Here is my HTML and CSS code :
.parent{
display: flex;
border: 2px solid red;
}
.child1{
background: cyan;
height: 40px;
width: 40px;
flex-shrink: 0;
}
.child2 {
background: pink;
height: 20px;
width: 20px;
}
.child3 {
background: yellow;
height: 20px;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div class='parent'>
<div class='child1'>1</div>
<div>
<div class='child2'>2</div>
<div class='child3'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed luctus sagittis odio, ac pulvinar tortor sagittis et. In hac habitasse platea dictumst. Phasellus ut velit dolor. Vestibulum pulvinar orci libero, in aliquet arcu auctor non. Morbi volutpat elit id lacus cursus, at imperdiet tellus eleifend. Morbi euismod vehicula urna, sed pretium felis ullamcorper vitae. Nunc at ligula a odio eleifend convallis eget sed orci. Praesent fermentum, sem in congue tempus, ex diam suscipit neque, in ullamcorper orci erat eu orci.</div>
</div>
</div>
My motive is to prevent the child3 from overflowing the parent container and show ellipsis(...) when it overflows.
Any help is appreciated.
There are a couple of issues with what you posted, but fear not we can sort you out.
What is flex, what is not
First let's look at your markup:
.parent is an element with display: flex. From your naming we might incorrectly assume that its children are:
.child1,
.child2, and
.child3.
…but this is not the case.
The children of .parent are actually:
.child1, and
a classless div.
The classless div has no styles set for it, so .child2 and .child3 are not positioned in a flexbox context. For this reason, your min-width: 0 on .child3 doesn't solve your problem, as that solution only applies for flex children.
Applying min-width in the correct context
To start, let's give that child div a class: .foo.
.foo itself has a block display, but currently it is allowing content (in .child3) to overflow. It is this element on which we want to prevent overflow:
.foo {
min-width: 0;
}
That should be all you need. It seems you're already familiar with why we use min-width to help with this, but just in case you can read about it in CSS Tricks: Flexbox and Truncated Text.
Solution
Below is all of it put together.
.parent {
display: flex;
border: 2px solid red;
}
.foo {
min-width: 0;
outline: 1px solid rebeccapurple;
}
.child1 {
background: cyan;
height: 40px;
width: 40px;
flex-shrink: 0;
}
.child2 {
background: pink;
height: 20px;
width: 20px;
}
.child3 {
background: yellow;
height: 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
<div class='parent'>
<div class='child1'>1</div>
<div class="foo">
<div class='child2'>2</div>
<div class='child3'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed luctus sagittis odio, ac pulvinar tortor sagittis et. In hac habitasse platea dictumst. Phasellus ut velit dolor. Vestibulum pulvinar orci libero, in aliquet arcu auctor non. Morbi volutpat elit id lacus cursus, at imperdiet tellus eleifend. Morbi euismod vehicula urna, sed pretium felis ullamcorper vitae. Nunc at ligula a odio eleifend convallis eget sed orci. Praesent fermentum, sem in congue tempus, ex diam suscipit neque, in ullamcorper orci erat eu orci.
</div>
</div>
</div>
If you want the exact same results:
.parent{
display: flex;
border: 2px solid red;
}
.child1{
background: cyan;
height: 40px;
width: 40px;
flex-shrink: 0;
}
.child-wrapper{
display:flex;
flex-direction: column;
overflow: hidden;
}
.child2 {
background: pink;
height: 20px;
width: 20px;
}
.child3 {
background: yellow;
height: 20px;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div class='parent'>
<div class='child1'>1</div>
<div class='child-wrapper'>
<div class='child2'>2</div>
<div class='child3'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed luctus sagittis odio, ac pulvinar tortor sagittis et. In hac habitasse platea dictumst. Phasellus ut velit dolor. Vestibulum pulvinar orci libero, in aliquet arcu auctor non. Morbi volutpat elit id lacus cursus, at imperdiet tellus eleifend. Morbi euismod vehicula urna, sed pretium felis ullamcorper vitae. Nunc at ligula a odio eleifend convallis eget sed orci. Praesent fermentum, sem in congue tempus, ex diam suscipit neque, in ullamcorper orci erat eu orci.</div>
</div>
</div>
As I said in my comments, you don't have anything limiting the length of your child-3 div. Your min-width:0 is not going to have any effect because that is just saying the div can take up as much space at it wants.
child-3 (and child-2 by the way) doesn't have any parent so there is nothing to limit it and therefore it is using all of the available width.
You need to give the child a flex parent with overflow:hidden that will then set a limit on its width. Assuming you want the same parent type, you can do the following:
UPDATE: the code below, you can use the same parent class to wrap your child-2 and child-3, making it act the same way:
.parent {
display: flex;
border: 2px solid red;
overflow: hidden;
}
.child1 {
background: cyan;
height: 40px;
width: 40px;
flex-shrink: 0;
}
.child2 {
background: pink;
height: 20px;
width: 20px;
}
.child3 {
background: yellow;
height: 20px;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div class='parent'>
<div class='child1'>1</div>
<div class='parent'>
<div class='child2'>2</div>
<div class='child3'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed luctus sagittis odio, ac pulvinar tortor sagittis et. In hac habitasse platea dictumst. Phasellus ut velit dolor. Vestibulum pulvinar orci libero, in aliquet arcu auctor non. Morbi volutpat
elit id lacus cursus, at imperdiet tellus eleifend. Morbi euismod vehicula urna, sed pretium felis ullamcorper vitae. Nunc at ligula a odio eleifend convallis eget sed orci. Praesent fermentum, sem in congue tempus, ex diam suscipit neque, in ullamcorper
orci erat eu orci.
</div>
</div>
</div>
I have this css code:
.post {
margin-top: 0.5em;
margin-left: 2em;
margin-right: 2em;
text-align: center;
}
.post p{
max-width: 1200px;
padding: .5em;
text-align: justify;
margin: 0;
top: 1.25em;
}
.post h1{
text-align: center;
}
and have this in html:
<div class="post">
<h1>Title of Sample Work 2</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus id nisl ut suscipit. Nullam vel justo tellus. Suspendisse vehicula rhoncus nunc sed accumsan. In hac habitasse platea dictumst. Mauris vel dolor velit. Phasellus finibus massa mauris, at interdum nisl luctus at. Etiam porttitor, metus non dapibus pretium, orci arcu pretium nulla, eget congue augue libero at lectus. Mauris pretium urna tristique, laoreet enim rhoncus, euismod tortor.</p>
</div>
And this is what I see:
Why there is so much margin at the top and the text title is so down?
You can see an example of the actual page on the web here:
http://www.nanogomo.com/sample1.html
It is interesting that if I add more content to it, it pushes the text up.
Because the #wrapper has display:flex and has a before. You should you remove the following:
#wrapper::before {
content: '';
display: block;
}
The flex container contained 3 elements home-back, post and before. Before is absolutely positioned so it is removed from the normal flow (doesn't take space). Before (with no width) and post are positioned on the main ax (vertical because direction is flex column) with justify-items: space-between (main ax is vertical).
use margin top and give value according to the need.
.post h1{
text-align: center;
margin-top: -7px;
}
Try setting a value to margin and padding:
.post h1{
text-align: center;
margin: 0px;
padding: 0px;
}
I have a flex layout with two flex items, displayed as rows (flex-direction: column). The items should have a minimum height but they should maintain the same height it one of them needs to grow. See this JSFiddle and decrease the width of the result pane; this forces the second .component element to increase its height, but the height of the first .component element remains the same.
Is it possible to force the flex items to maintain the same height? Please note that the main thing in this is the stacking of the two .component elements, which I couldn't achieve without flex-direction: column; flex-direction: row would have made the same height possible but the stacking does not work.
Here is the result of what I have so far:
div {
border: 1px solid black;
box-sizing: border-box;
}
.container {
display: flex;
flex-direction: column;
align-content: stretch;
}
.component {
min-height: 300px;
}
.left {
margin-left: 50px;
margin-top: 50px;
margin-right: 100px;
background-color: lightyellow;
}
.right {
margin-left: 100px;
margin-top: -250px;
margin-right: 50px;
background-color: lightgreen;
}
<div class="container">
<div class="component left">
</div>
<div class="component right">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sed orci scelerisque, scelerisque enim at, ullamcorper ipsum. Cras eget sapien mi. Aliquam ultrices, ligula ut mollis maximus, ligula massa imperdiet libero, at faucibus mauris ante non
magna. Sed ex lacus, efficitur sit amet neque ut, venenatis hendrerit libero. Suspendisse ornare orci mi. Nulla iaculis egestas libero, eu tincidunt urna tristique et. Quisque nec odio non elit molestie facilisis.
</p>
<p>
Vestibulum scelerisque justo urna, a semper nisi sollicitudin in. Cras congue enim eu euismod semper. Proin consequat gravida felis, quis tincidunt massa pulvinar quis. Morbi nec diam eget orci vestibulum malesuada. Sed volutpat metus eget mattis commodo.
Nulla facilisi. Praesent lectus mauris, consequat eu varius vitae, cursus vitae leo. Vivamus sagittis lacinia tortor eu ullamcorper. Integer eget velit magna. Duis vestibulum molestie posuere.
</p>
</div>
</div>
The flex equal height columns feature – which is the result of align-items: stretch, a default setting of a flex container – applies only to flex items on the same row.
It doesn't work for items in a multi-line flex container. This behavior is defined in the spec:
6. Flex Lines
In a multi-line flex container (even one with only a single line), the
cross size of each line is the minimum size necessary to contain the
flex items on the line (after alignment due to align-self), and the
lines are aligned within the flex container with the align-content
property.
In other words, when there are multiple lines in a row-based flex container, the height of each line (the "cross size") is the "minimum size necessary to contain the flex items on the line".
In addition, because align-items: stretch works along the cross-axis, the equal height columns feature is useless in flex-direction: column, where the cross-axis is horizontal.
To achieve equal height columns/rows across multiple lines consider a Javascript solution.
However, without knowing much about your overall objective, here's a simple way to achieve equal height rows in your current layout:
Add duplicate content in both divs. In the .component.left div, use visibility: hidden.
Revised Fiddle
You can just wrap those flexbox columns in another flexbox that's a row, there's no reason you can't have items be both flexboxes and flex items.
#container {
display: flex;
}
#container .col {
flex-grow: 1;
display: flex;
flex-direction: column;
background: grey;
}
<div id="container">
<div class="col">
asdf
asdf
asdf
</div>
<div class="col">
asdf
asdf
asdf
</div>
</div>
https://jsfiddle.net/1dp87bm2/1/
In advance, thank you all.
I'm learning. So I messed up my layout, and can't figure out to solve it.
I basically have a container who contains 3 divs (some blocks of text).
The main container should be <div id="main">. It has 1024px width and 500px height.
It should contain the 3 articles or 3 divs. They should spread horizontal.
The first "article" should be 67px from the left of the "main div".
The third "article" should also be 67px from the right of the "main div".
Between the articles there should be around 55px space, or around that value.
I read that I need to nest those articles into another div (<div class=artcontainer">) and do margin: 0 auto
I did it but not so good.
Here is the jsfiddle
<div id="main">
<div class="artcontainer">
<article class="pulllft">
<h2>Adipiscing elit</h2>
<br>
<p>Mauris malesuada dapibus ornare. Aenean molestie, lorem vitae eleifend tincidunt, ipsum nibh cursus libero, ac molestie magna sem in eros. Interdum et malesfaucibus. Integer at id nulla congue. Praesent quis dolor mattis, vitae feugiat erat commodo.Read More</p>
</article>
<article class="pulllft">
<h2>Lorem Ipsun</h2>
<br>
<p>Suspendisse id varius enim. Nulla facilisi. Pellentesque dapibus, ut luctus faucibus, erat metus tempor sem, a fringilla lacus diam a massa. Praesent porta, augue vel suscipit convallis, augue velit ultricies mauris, ut tempor massa ipsum ut magna.</p>
</article>
<article class="pulllft">
<h2>Lorem Ipsun</h2>
<br>
<p>Aliquam in mauris nulla. Cras neque mauris, congue vitae dignissim eu, euismod sit amet dolor. Etiam luctus tempor interdumEtiam in mi feugiat, rutrum nulla eget, posuere nibh. Mauris rhoncus velit nec leo luctus, ut dictum dolor laoreet. In consequat risus lectus.</p></article>
</div>
Also I'm interested if I used right properties, in a desperate attempt, I clicked what I need to and don't need. And is the use of article tag ok for this, or should I use some other tag.
The Css:
#main {
width: 1024px;
float: left;
font-family: 'Source Sans Pro', sans-serif;
font-size: 1em;
color: rgba(51,51,51,1);
z-index: 99;
height: 500px;
position: static;
/* [disabled]visibility: inherit; */
background-color: #f3f2f1;
clear: both;
overflow: hidden;
text-align: center;
}
.pulllft {
width: 274px;
text-align: justify;
line-height: 1.3em;
float: left;
color: rgba(79,30,31,.8);
font-family: "Exo 2", "sans-serif;";
font-weight: 400;
font-size: 1.3em;
display: inline-block;
padding-left: 10px;
padding-right: 10px;
height: 300px;
margin-top: 100px;
}
.artcontainer {
width: 895px;
position: relative;
margin-top: 0;
margin-right: auto;
margin-bottom: 0;
margin-left: auto;
background-color: rgba(0,153,102,1);
}
Is this what you are looking for?
What I changed:
So first off, you had the wrong width of the inner div; you wanted it to have 67px margins on each side in a 1024px width div.
1024 - 2(67) = 890
You had 895.
Secondly, you wanted 55px between the three articles, so subtract that from the width of the container:
890 - 2(55) = 780
Divide it by 3 for the 3 articles:
780 / 3 = 260
There's your width.
Then apply the padding to the right side of the articles:
.pulllft
{
padding-right: 55px;
}
And don't apply to the last child:
.pulllft:last-child
{
padding-right: 0;
}
Sorry in advance, this is long and weird.
I found this bug in native IE8 when working with Bootstrap and have stripped it all the way back to find the cause. But I want to know why it happens.
The setup: I have a .container, inside the container I have a .box (another container essentially) and inside that box I have a <div> element that is display: inline-block.
The conditions: .box must be floated.
The issue: The inline block element that is inside the first .box element will have it's text not wrapping (it will overflow the containers). The inline block element that is inside any other .box element will have it's text wrapping as expected.
Fixes: This can be fixed either removing the float of the .box or by applying a border to the .inline-block element (can be transparent), suggesting that it's a hasLayout bug (although zoom: 1 doesn't fix it). But I thought display: inline-block didn't have the hasLayout bug?
So why does this issue happen and why is it only that first child?!?
I've put the demo code on my server as JSBin doesn't work on IE8, sorry for the link off.
HERE'S THE DEMO
Demo HTML
<div class="container">
<h2>A container (red) with 1 box child (blue) which has 1 inline-block child (green background - border will fix issue)</h2>
<div class="box">
<div class="inline-block">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh eget orci convallis at posuere leo convallis. Sed blandit augue vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus augue.</div>
</div>
</div>
<div class="container">
<h2>A container (red) with 2 box children (blue) which each have 1 inline-block child (green background - border will fix issue)</h2>
<div class="box">
<div class="inline-block">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh eget orci convallis at posuere leo convallis. Sed blandit augue vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus augue.</div>
</div>
<div class="box">
<div class="inline-block">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh eget orci convallis at posuere leo convallis. Sed blandit augue vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus augue.</div>
</div>
</div>
</div>
Demo CSS
*, *:before, *:after {
-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
body {
margin: 0;
}
.container {
width: 800px;
margin: 10px auto;
padding: 10px;
border: 1px solid red;
}
/* Clear the float */
.container:before,
.container:after {
content: " ";
display: table;
}
.container:after {
clear: both;
}
.box {
float: left; /* THIS IS THE TRIGGER (without float it works) */
width: 100%;
padding: 10px;
margin: 10px 0;
border: 1px solid blue;
}
.inline-block {
display: inline-block;
background: #c4df9b;
/*border: 1px solid green;*/ /* Having a border fixes it (when there's a float) */
}
.inline-block + .inline-block {
background: #9db678;
}
BIG PICTURE!
Is there any specific reason to use display: inline-block; in class .inline-block
I use all your code and here is the Demo. checked in IE7 and IE8 works.
.block {
display: block; /*I remove the inline*/
background: #c4df9b;
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
/*border: 1px solid green;*/ /* Having a border fixes it (when there's a float) */
}
.block + .block {
background: #9db678;
}