Is it possible to prevent the yellow child growing and to take just 50% from parent (like the green takes, because has no content), using just flex properties (grow, shrink, basis)?
Parent has flex-direction: column and both of the children have flex-basis: 50%
I know that a fast solution is to set on yellow child height: 50% and overflow: auto to trigger the scrollbar, but I wanted to achieve that without using the height property.
body{
margin: 0;
}
.parent{
height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
}
.parent div:first-child{
background-color: yellow;
flex-basis: 50%;
width: 200px;
}
.parent div:last-child{
background-color: blue;
flex-basis: 50%;
width: 200px;
}
<div class="parent">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat non magna sit amet sagittis. Praesent auctor sed risus vitae dapibus. Aliquam ex purus, fa
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat non magna sit amet sagittis. Praesent auctor sed risus vitae dapibus. Aliquam ex purus, fa
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat non magna sit amet sagittis. Praesent auctor sed risus vitae dapibus. Aliquam ex purus, fa
</div>
<div>
</div>
</div>
Is it possible to prevent the yellow child growing and to take just 50% from parent (like the green takes, because has no content), using just flex properties?
No.
There are no flex properties that would allow you to solve this issue. The flexbox layout mode takes into account the content of its children and like most CSS does, it will try its best to make content visible.
If you want your yellow box to only take up 50% height you have to decide what will happen to the content that will have no room. Below is one example where setting overflow-y: scroll allows the box to reveal the remaining content while still being only 50% height.
body{
margin: 0;
}
.parent{
height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
}
.parent div:first-child{
background-color: yellow;
flex-basis: 50%;
width: 200px;
overflow-y: scroll;
}
.parent div:last-child{
background-color: blue;
flex-basis: 50%;
width: 200px;
}
<div class="parent">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat non magna sit amet sagittis. Praesent auctor sed risus vitae dapibus. Aliquam ex purus, fa
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat non magna sit amet sagittis. Praesent auctor sed risus vitae dapibus. Aliquam ex purus, fa
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat non magna sit amet sagittis. Praesent auctor sed risus vitae dapibus. Aliquam ex purus, fa
</div>
<div>
</div>
</div>
Related
How can we get Flexbox to stop equalizing space in sibling elements when both of the elements are using flex-grow: 1. This is difficult to explain upfront, so here is the code quickly followed by example screenshots of the issue, and desired behavior.
.Parent {
display: flex;
flex-direction: column;
background-color: lightcoral;
width: 400px;
min-height: 200px;
}
.Parent>div {
flex: 1;
}
.child1 {
background-color: lightblue;
}
.child2 {
background-color: lightgreen;
}
<div class="Parent">
<div class="child1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sagittis lorem at odio euismod tincidunt. Proin aliquet velit nec augue venenatis laoreet. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus.</div>
<div class="child2">Lorem ipsum</div>
</div>
The issue:
Notice the equal space under the content of each div.
Desired:
When there is little content in the children divs, the divs should be of equal height:
When one of the divs has a lot of content, I would expect the div with more content to only be as tall as the content (if it passes the original flex grow allotment).
How can I get this behavior? Seems it should be easy using Flexbox.
flex-basis is the property you're looking for. https://developer.mozilla.org/en-US/docs/Web/CSS/flex-basis
The flex-basis CSS property specifies the flex basis which is the initial main size of a flex item. This property determines the size of the content-box unless specified otherwise using box-sizing.
By default, flex will take into account the content in the element when computing flex-grow - to disable that, just specify flex-basis: 0
.Parent {
display: flex;
flex-direction: column;
background-color: lightcoral;
width: 400px;
min-height: 200px;
}
.Parent>div {
flex-grow: 1;
flex-basis: 0;
}
.child1 {
background-color: lightblue;
}
.child2 {
background-color: lightgreen;
}
<div class="Parent">
<div class="child1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sagittis lorem at odio euismod tincidunt. Proin aliquet velit nec augue venenatis laoreet. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus </div>
<div class="child2">Lorem ipsum</div>
</div>
By setting min-height on .Parent (along with setting the flex-direction to column), you're triggering the browser to fill the space with direct descendants of .Parent. It does so by distributing the space amongst all elements equally (that's the feature of Flexbox).
If you don't want that behavior, remove the min-height from .Parent and set a min-height on .Parent > div elements.
.Parent {
display: flex;
flex-direction: column;
background-color: lightcoral;
width: 400px;
}
.Parent>div {
flex: 1;
min-height: 100px;
}
.Parent > div:nth-child(odd) {
background-color: lightblue;
}
.Parent > div:nth-child(even) {
background-color: lightgreen;
}
<div class="Parent">
<div class="child1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sagittis lorem at odio euismod tincidunt. Proin aliquet velit nec augue venenatis laoreet. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus. Nullam sagittis lorem at odio euismod tincidunt. Proin aliquet velit nec augue venenatis laoreet. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus.</div>
<div class="child2">Lorem ipsum</div>
<div>Lorem ipsum doler sit amet</div>
<div>When there is little content in the children divs, the divs should be of equal height.</div>
</div>
I've got div containers that are using flex. I have a bold senescence inside my flex child containers.
example
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc at lectus vitae libero pulvinar fringilla. Nullam vel vestibulum orci.
However, when I create my flex container it's not making the bold text inline. It's creating a block between the regular text and the bold text.
example
Lorem ipsum dolor
sit amet, consectetur adipiscing elit. Nunc at lectus vitae libero
pulvinar fringilla. Nullam vel vestibulum orci.
I've set my flex container as follows:
.flexparent { display: flex; flex-direction: row; justifty-content: center; flex-wrap: wrap-reverse }
.flexchild1 { display: inline-flex; flex-direction: column; flex-wrap: nowrap; justify-contetn: center; width: 65%; margin-right: 4%;}
.flexchild2 { display: inline-flex; flex-direction: column; flex-wrap: nowrap; justify-contetn: center; width: 35%;}
My ideal solution is something like this where .flexchild1 is green and .flexchild2 is yellow.
If you're going to use a flex container, keep in mind that all child elements will become flex items and stack vertically or horizontally, depending on flex-direction.
So, if we consider this code:
<div class="flex-container"><b>Lorem ipsum dolor sit amet</b> consectetur adipiscing elit. <span>Nunc at lectus vitae libero</span> pulvinar fringilla. <i>Nullam vel vestibulum orci.</i></div>
Although, the <b>, <span> and <i> elements are inline-level in a block formatting content...
.flex-container {
display: block;
flex-direction: row;
background-color: lightgreen;
}
span { color: red; }
<div class="flex-container"><b>Lorem ipsum dolor sit amet</b> consectetur adipiscing elit. <span>Nunc at lectus vitae libero</span> pulvinar fringilla. <i>Nullam vel vestibulum orci.</i></div>
ALL child elements are blockified in a flex formatting context...
.flex-container1 {
display: flex;
flex-direction: row;
background-color: lightgreen;
}
.flex-container2 {
display: flex;
flex-direction: column;
background-color: lightgreen;
}
span { color: red; }
<div class="flex-container1"><b>Lorem ipsum dolor sit amet</b> consectetur adipiscing elit. <span>Nunc at lectus vitae libero</span> pulvinar fringilla. <i>Nullam vel vestibulum orci.</i></div>
<hr>
<div class="flex-container2"><b>Lorem ipsum dolor sit amet</b> consectetur adipiscing elit. <span>Nunc at lectus vitae libero</span> pulvinar fringilla. <i>Nullam vel vestibulum orci.</i></div>
What you may want to do is wrap your text in its own block-level container within the flex container.
.flex-container1 {
display: flex;
flex-direction: row;
background-color: lightgreen;
}
.flex-container2 {
display: flex;
flex-direction: column;
background-color: lightgreen;
}
span {
color: red;
}
<div class="flex-container1">
<div>
<b>Lorem ipsum dolor sit amet</b> consectetur adipiscing elit. <span>Nunc at lectus vitae libero</span> pulvinar fringilla. <i>Nullam vel vestibulum orci.</i>
</div>
</div>
<hr>
<div class="flex-container2">
<div>
<b>Lorem ipsum dolor sit amet</b> consectetur adipiscing elit. <span>Nunc at lectus vitae libero</span> pulvinar fringilla. <i>Nullam vel vestibulum orci.</i>
</div>
</div>
I'm trying to setup a section of my page with 3 columns using Flexbox.
The 3 columns are set up just fine, the issue I am having is with the section1 div not being as tall as the children elements.
I have tried height: auto, height:100%, overflow: auto, overflow:visible, etc. The only time the section1 div changes height is when I specifically state a pixel height. It seems as though the flexbox items are acting as floats so I tried a clear:both to no avail.
I have searched both stackoverflow and other sites and have not found an answer which leads me to believe it is something I am doing wrong with flexbox.
body {
background: lightgrey;
}
.body {
position: relative;
width: 75% /* 747.75px */;
margin: auto;
top: -3.5em;
background-color: white;
border-top: 3px solid #ff8400;
}
.top-border {
display: block;
position: relative;
top: 2em;
border-top: 1px solid #eef3f0;
width: 95%;
left: 2.5%;
}
.section1 {
position: relative;
display: flex;
justify-content: space-around;
top: 5em;
height: auto;
}
<div class="body">
<div class="top-border"></div>
<div class="section1">
<div class="what-i-do">
<img class="what-i-do-icon" src="images/what-i-do.png" />
<h1 class="what-i-do-title">What I Do</h1>
<p class="what-i-do-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam semper quam arcu,
a consequat tellus cursus vel. Vivamus lacus massa, feugiat non malesuada sed, efficitur eu elit. </p>
<p class="view-more-btn">View More</p>
</div>
<div class="development">
<img class="development-icon" src="images/development.png" />
<h1 class="development-title">Development</h1>
<p class="development-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam semper quam arcu,
a consequat tellus cursus vel. Vivamus lacus massa, feugiat non malesuada sed, efficitur eu elit. </p>
</div>
<div class="design">
<img class="design-icon" src="images/design.png" />
<h1 class="design-title">Design</h1>
<p class="design-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam semper quam arcu, a
consequat tellus cursus vel. Vivamus lacus massa, feugiat non malesuada sed, efficitur eu elit. </p>
</div>
</div>
</div>
See Relative positioning
Once a box has been laid out according to the normal flow or
floated, it may be shifted relative to this position. This is called
relative positioning. Offsetting a box (B1) in this way has no effect on the box (B2) that follows: B2 is given a position as if B1
were not offset and B2 is not re-positioned after B1's offset is
applied. This implies that relative positioning may cause boxes to
overlap.
Here you don't want to shift a single box, you want it to push following content too. Then, you should use margins for that.
body {
background: lightgrey;
}
.body {
width: 75% /* 747.75px */;
margin: auto;
margin-top: -3.5em;
background-color: white;
border-top: 3px solid #ff8400;
}
.top-border {
top: 2em;
border-top: 1px solid #eef3f0;
width: 95%;
margin-left: 2.5%;
}
.section1 {
display: flex;
justify-content: space-around;
margin-top: 5em;
}
<div class="body">
<div class="top-border"></div>
<div class="section1">
<div class="what-i-do">
<img class="what-i-do-icon" src="images/what-i-do.png" />
<h1 class="what-i-do-title">What I Do</h1>
<p class="what-i-do-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam semper quam arcu,
a consequat tellus cursus vel. Vivamus lacus massa, feugiat non malesuada sed, efficitur eu elit. </p>
<p class="view-more-btn">View More</p>
</div>
<div class="development">
<img class="development-icon" src="images/development.png" />
<h1 class="development-title">Development</h1>
<p class="development-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam semper quam arcu,
a consequat tellus cursus vel. Vivamus lacus massa, feugiat non malesuada sed, efficitur eu elit. </p>
</div>
<div class="design">
<img class="design-icon" src="images/design.png" />
<h1 class="design-title">Design</h1>
<p class="design-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam semper quam arcu, a
consequat tellus cursus vel. Vivamus lacus massa, feugiat non malesuada sed, efficitur eu elit. </p>
</div>
</div>
</div>
I have a simple webpage with the center content with a red background. I'd like that background color to reach all the way to the bottom of the page, regardless of whether there is that much content in it or not.
I've tried various combinations of methods but nothing seems to stretch it correctly. In the Fiddle, I am attempting to use a flexbox but it doesn't appear to be working.
body {
background-color: white;
}
.main {
max-width: 80%;
background-color: red;
margin: 0 auto;
padding: 10px;
display: flex;
align-content: stretch;
flex-direction: row;
}
<section class="main">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce at aliquam dolor. Pellentesque a nibh in magna blandit elementum. Sed sodales porttitor dolor vel bibendum. Ut viverra justo in elit scelerisque, nec accumsan arcu facilisis. Nam ultricies
leo vitae felis sollicitudin lobortis. Cras nec nibh venenatis, bibendum neque at, suscipit lacus. Vestibulum interdum sodales cursus. Pellentesque feugiat eu velit venenatis egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam
faucibus risus quis est pellentesque ultrices.
</p>
</section>
<section class="main">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</section>
body
{
background-color:white;
}
.main
{
max-width:80%;
background-color:red;
margin: 0 auto;
padding: 10px;
display:flex;
align-content:stretch;
flex-direction:row;
}
I've tried various combinations of methods but nothing seems to stretch it correctly
I assume that you don't want a flex ONLY solution, because you can actually achieve this without the flex, so if that's the point, than set the parent elements height to 100%
Demo
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
background-color: white;
height: 100%;
}
.main {
max-width: 80%;
background-color: red;
margin: 0 auto;
padding: 10px;
height: 100%;
}
<section class="main">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce at aliquam dolor. Pellentesque a nibh in magna blandit elementum. Sed sodales porttitor dolor vel bibendum. Ut viverra justo in elit scelerisque, nec accumsan arcu facilisis. Nam ultricies
leo vitae felis sollicitudin lobortis. Cras nec nibh venenatis, bibendum neque at, suscipit lacus. Vestibulum interdum sodales cursus. Pellentesque feugiat eu velit venenatis egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam
faucibus risus quis est pellentesque ultrices.
</p>
</section>
Also, you would see, am using the snippet below
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
will do nothing but count the borders, padding of the element inside instead of default box model which counts these outside the element, thus it won't result in vertical scroll as you were using padding and I used height: 100%; so as I explained, padding will be counted outside of the element, and will thus result in scroll.
box-sizing is a good option, its a CSS3 property.
I have one more option.
body, html {
min-height:100%;
height: 100%;
margin:0;
}
.innerBox {
min-height:100%;
width: 80%;
background: red;
margin: 0 auto;
}
<div class="innerBox">
Testing
</div>
What about using a new div for wrapping your content ?
Like this http://jsfiddle.net/MNQjk/2/
.block
{
max-width:80%;
background-color: red;
height: 1000px;
margin: 0 auto;
}
See the following code: http://jsfiddle.net/chricholson/tyLbE/1/
HTML
<section>
<div>Secondary content</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dictum nunc at nibh elementum vestibulum. Curabitur nisi tortor, porttitor sed facilisis vel, volutpat in quam.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dictum nunc at nibh elementum vestibulum. Curabitur nisi tortor, porttitor sed facilisis vel, volutpat in quam.</p>
</section>
CSS
section { border: 1px solid red; overflow: hidden; }
div { float: right; width: 48%; height: 200px; background: #eee; }
p { width: 48%; }
I have a div (BoxA) floated to the right, which allows me to keep my paragraph tags outside of any separate container. I use the overflow hack to ensure that the outer container grows to the height of either a) the paragraphs or b) BoxA.
What I'd like, is to re-order the HTML to
Paragraphs
BoxA
The obvious solution to me is CSS positioning the secondary content but this of course prevents any growth of the outer container should BoxA box be longer than the paragraph list. I'd like to avoid any kind of Javascript here to set a height, it's not THAT important just desirable from an SEO point of view.
The other solution I can think of is to wrap the paragraphs in their own container, but this feels like unnecessary markup which shouldn't really be there (it's a visual thing which should really be handled by CSS).
I'm not sure if I've got you right but it seems that, in the markup, you want to move <p>s before <div> but you want the display to be same as your fiddle, i.e., gray area on right. check this fiddle to see if it solves your problem.
update
css
section{ border: 1px solid red; overflow: hidden; }
div{
background: none repeat scroll 0 0 #EEEEEE;
border: 1px solid #000000;
display: table-cell;
height: 246px;
width: 1%;
}
p{
clear: left;
float: left;
width: 48%;
}
and the markup (unchanged)
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dictum nunc at nibh elementum vestibulum. Curabitur nisi tortor, porttitor sed facilisis vel, volutpat in quam.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dictum nunc at nibh elementum vestibulum. Curabitur nisi tortor, porttitor sed facilisis vel, volutpat in quam.</p>
<div>
Secondary content
</div>
</section>
I would suggest you to use a html wrapper like in this example:
http://jsfiddle.net/tyLbE/4/
<section>
<div class="left">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dictum nunc at nibh elementum vestibulum. Curabitur nisi tortor, porttitor sed facilisis vel, volutpat in quam.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dictum nunc at nibh elementum vestibulum. Curabitur nisi tortor, porttitor sed facilisis vel, volutpat in quam.</p>
</div>
<div class="right">
Secondary content
</div>
<div class="clear"></div>
</section>
and the css:
section { border: 1px solid red; overflow: hidden; }
div.left { float: left; width: 48%; }
div.right { float: right; width: 48%; height: 200px; background: #eee; }
div.clear { clear: both; }
you can leave out the "clear", since you dont have any content after the left and right box, but this is how you can stop floating if you want to have some content below the two boxes (even if they dont have the same height)
First off, +1 to Ejay, that was certainly the outcome I was after. However, a few things worried me about the implementation (notably the display: table-cell and width: 1%. I can't really fault it, because it did work, but my gut instinct was screaming at me that something wasn't right and might catch me out in the future. It did actually slightly break, dependant on container width I'd get a 1px gap in Chrome:
Anyway, it inspired me to try harder and I came up with this: http://jsfiddle.net/z6TMJ/2/
HTML
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dictum nunc at nibh elementum vestibulum. Curabitur nisi tortor, porttitor sed facilisis vel, volutpat in quam.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dictum nunc at nibh elementum vestibulum. Curabitur nisi tortor, porttitor sed facilisis vel, volutpat in quam.</p>
<div>Secondary content</div>
</section>
CSS
section {
border: 1px solid red;
overflow: hidden;
}
div {
background: none repeat scroll 0 0 #EEEEEE;
margin-left: 50%;
width: 50%;
height: 246px;
border: 1px solid #000;
box-sizing: border-box;
}
p {
clear: left;
float: left;
width: 50%;
}
The paragraphs are styled in the same way, but now the div is left alone to do its natural thing. It is then positioned on the right using margin-left (removing the margin will actually make the div appear behind the paragraphs.
While this may not suit ALL scenarios, where I know a few things like the width of the container and the widths of the paragraphs and secondary content this way seems fine.