I'm trying to accomplish this design by using flexbox:
It's supposed to be a one page website.
.container {
display: flex;
}
.big {
flex: 2;
height: 70vh;
background: gray;
}
.small {
flex: 1;
height: 70vh;
background: gray;
}
<div class="container">
<div class="small">
</div>
<div class="smallest">
</div>
<div class="big">
</div>
</div>
I have no idea how to implement the "smallest" div to be 25% of the big, let alone make the "small" 75% of the big one.
Also the height really confuses me, I need them to always have the same height.
With flexbox you can wrap the small and the smallest into a separate div and use column flexbox on the left section.
I have no idea how to implement the "smallest" div to be 25% of the big
25% to 75% ratio means 1:3 ratio - and in flexbox language that is flex: 1 to the small element and flex: 3 to the big element.
Also the height really confuses me, I need them to always have the same height.
You can set the height of the container to the container element - your flexbox will fill to this height.
See demo below:
.container {
display: flex;
height: 70vh;
}
.big {
flex: 3;
background: gray;
margin-left: 5px;
}
.left {
flex: 1;
display: flex;
flex-direction: column;
}
.left .small {
background: gray;
flex: 3;
}
.left .smallest {
margin-top: 5px;
background: gray;
flex: 1;
}
<div class="container">
<div class="left">
<div class="small">
</div>
<div class="smallest">
</div>
</div>
<div class="big">
</div>
</div>
Related
This question already has answers here:
Make a div fill the height of the remaining screen space
(41 answers)
Percentage Height HTML 5/CSS
(7 answers)
Flexbox fill available space vertically
(2 answers)
Closed 3 years ago.
Consider the following code:
.container {
display: flex;
flex-direction: column;
}
.header {
flex: 1;
background-color: red;
}
.content {
flex: 1;
background-color: blue;
height: 100%;
}
<div class="container">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<h1>CONTENT</h1>
</div>
</div>
Why is my CONTENT not getting full available height (from HEADER bottom to the bottom of page) ? How to solve it ?
I'm putting this answer to clear up a few things mentioned in the comments, if it's not appropiate due to the question already having an answer I'll delete this.
By making the changes I proposed, we set the .container's height to 100vh, to explicitly define that it must have the full viewport's height, without this, the .container only has the needed height to contain the elements inside of it.
This applies the same to the body and html elements.
.container {
display: flex;
flex-direction: column;
height: 100vh;
}
.header {
flex: 1;
background-color: red;
}
.content {
flex: 1;
background-color: blue;
}
<div class="container">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<h1>CONTENT</h1>
</div>
</div>
Using percentages to define a height or width require some reference to calculate how much space that % unit is; so for example:
If we set a width of 1000px for .container, we can set its children's width to say, 50% and 100% and they will resize accordingly to 500px and 1000px because they have the 1000px reference from their parent.
EDIT: As noted by #Temani, this reference is always present for the width property, so using percentages for width will never fail, even if we don't specify an explicit width in a parent container.
.container {
display: flex;
flex-direction: column;
width: 1000px;
}
.header {
flex: 1;
width: 50%;
background-color: red;
}
.content {
flex: 1;
background-color: blue;
width: 100%
}
<div class="container">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<h1>CONTENT</h1>
</div>
</div>
The same happens with the height property; we define a specific
height for the parent, and the children's height can be set with percentages since now they have a reference.
.container {
display: flex;
flex-direction: column;
height: 500px;
}
.header {
height: 20%;
background-color: red;
}
.content {
background-color: blue;
height: 80%
}
<div class="container">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<h1>CONTENT</h1>
</div>
</div>
Your container is missing an height , you can use height:100vh; to fill window's height.
You can also use % , but you need to inherit a valid value from a parent. In this case, it can be take from html, send to body, and finally used by your container:(example in this duplicate)
html,body,.container {height:100%;}
example with vh
body {
margin: 0;
}
.container {
display: flex;
flex-direction: column;
/*or min-height*/ height: 100vh;
}
.header {
/* flex: 1; not needed */
background-color: red;
}
.content {
flex: 1;
background-color: blue;
/*height: 100%; not needed */
}
<div class="container">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<h1>CONTENT</h1>
</div>
</div>
Its going to depend on what you want to ultimately do the page and how you are going to use the page.
You can set your .container full page width & height:
.container {
display: flex;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
and then grow/shrink your containers as needed:
.header{ flex: 1 }
.content { flex: 2 } // twice as large as header
How #ivanS95 says '.container only has a height based on its content'.
Instead, you can do this by setting all parents (html, body) elements to 100% also the .container at 100% too, and changing your flex propierty of .header not allowing it to grow.
Example here:
flex: 0 1;
https://codepen.io/pen/
This question was very nicely answered before by #Pebbl at:
Make a div fill the height of the remaining screen space
please check it.
I'm trying to create the following basic layout:
And I'm currently using the following basic HTML markup (with slightly different class names and additional markup within each of the HTML elements):
<div class="siteContainer">
<div class="sidebar">
<div class="topGreenStrip">
</div>
<div class="sidebarContainer">
<div class="sidebarInnerContainer">
<div class="brownSection">
</div>
<div class="purpleSection">
</div>
<div class="pinkSection">
</div>
<div class="redSection">
</div>
</div>
<div class="rightOrangeStrip">
</div>
</div>
</div>
<div class="lightPurpleContent">
</div>
</div>
And then the following starting CSS for the markup above:
.sidebar {
bottom: 0;
display: flex;
flex-direction: column;
left: 0;
position: fixed;
top: 0;
width: 300px;
}
.topGreenStrip {
height: 5px;
justify-self: flex-start;
}
.sidebarContainer {
flex-grow: 1;
justify-self: stretch;
}
The problem I'm having though is that because I start by stretching everything vertically with flexbox, I don't know how to then stretch things horizontally but still keep everything 100% the height of the screen.
That is, minus the 5px green top strip, I want the rest of the sidebar to occupy 100% the height of the screen. The large pink section should fill in whatever the brown, purple and red sections don't naturally.
I was able to get that part working without the orange bar by using justify-self: flex-start;, justify-self: stretch; and justify-self: flex-end;. However, once I add the orange bar in, I don't know how to keep doing what I'm doing.
The orange bar has a bit of dynamic content in it, so I can't set a static width, and the brown, purple, pink and red sections should use whatever width is not taken up by the orange bar (I'm assuming with flex-grow: 1;).
Anyway, how do I get this layout where (within the sidebar), I'm trying to stretch things both to 100% the height and 100% the width? Can I do this with just flexbox, or am I going to have to used positioned/floated elements to get this all to work?
Sorry for the vagueness, but after trying several things and getting nowhere close, I'm not sure where to begin. Thank you.
You need to make use of flex-direction: column on certain elements to stack the children. Also, using flex: 1 will force that element to grow and fill available space in it's parent.
By setting height: 100% on the html and body you can stretch .siteContainer to be the full height of the window.
I've added the background colours so you can see the layout in action.
html,
body {
margin: 0;
height: 100%;
}
.siteContainer {
display: flex;
height: 100%;
}
.sidebar {
display: flex;
flex-direction: column;
width: 300px;
}
.topGreenStrip {
height: 5px;
}
.sidebarContainer {
flex: 1;
display: flex;
}
.sidebarInnerContainer {
display: flex;
flex-direction: column;
flex: 1;
}
.pinkSection,
.lightPurpleContent {
flex: 1;
}
.topGreenStrip { background: green; }
.brownSection { background: peru; }
.purpleSection { background: darkviolet ; }
.pinkSection { background: pink; }
.redSection { background: red; }
.rightOrangeStrip { background: orange; }
.lightPurpleContent { background: lavender; }
<div class="siteContainer">
<div class="sidebar">
<div class="topGreenStrip">green
</div>
<div class="sidebarContainer">
<div class="sidebarInnerContainer">
<div class="brownSection">brown
</div>
<div class="purpleSection">purple
</div>
<div class="pinkSection">pink
</div>
<div class="redSection">red
</div>
</div>
<div class="rightOrangeStrip">orange
</div>
</div>
</div>
<div class="lightPurpleContent">lightpurple
</div>
</div>
This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 5 years ago.
I have 2 flexboxes and a flexbox inside one.
I want the text to break into multiple lines if it is bigger than it's parent. For some reason it works if I sent a fixed value (e.g. 250px) as width. If I set the width to 100%, it will not break into multiple lines.
This is the code I have:
#flexparent {
display: flex
}
#flexchild1 {
flex: 1;
background-color: green;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column
}
#flexchild3 {
background-color: purple;
width: 100%;
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
</div>
</div>
</div>
This is how I want it but without the spaces in the long sentence.
#flexparent {
display: flex
}
#flexchild1 {
flex: 1;
background-color: green;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column
}
#flexchild3 {
background-color: purple;
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
Thisisasuperlongsentence Loremipsum dolorsitametcon secteturadipisicingelitAsperi resnecessitatibusneu eodioImpeditistenes ciuntescorru ptiessecumrepudia ndaequidolor umIllumtempori busquoerrorcumqu eeximpeditmagnam Lore mipsumdo lorsitam etconsecteturadipisicing elitAsperioresne cessitatibusneueodi oImpeditisten esciuntescorruptiessecumrepudia ndaequidolorumIll umtemporibusq uoerrorc umqueeximpe ditmagn amtstLoremipsu mdolorsitametcon secteturadipisici ngelitAsperio resnecessitati busn
</div>
</div>
</div>
Here are the codepens I made for this.
The code I have: https://codepen.io/tomzz/pen/mpJMow
How I want it but without the 250px width: https://codepen.io/tomzz/pen/VyLMaW
How I want it but without the spaces in the sentence: https://codepen.io/tomzz/pen/vpOeJp
This is a min-width issue, where a flex item can't be smaller than its content.
The default value of min-width is auto, and in this case it happens to the flex item #flexchild2
Give it min-width: 0 and it will work.
Also, the width: 100% is not needed, since a flex "column" item's align-items default to stretch, and as such automatically take full width of its parent, and can be removed.
Stack snippet
#flexparent {
display: flex
}
#flexchild1 {
flex: 1;
background-color: green;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column;
min-width: 0; /* added */
}
#flexchild3 {
background-color: purple;
/*width: 100%; removed */
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
</div>
</div>
</div>
The problem is that percentage-based widths are based off of the immediate parent. If the immediate parent has no width, the child cannot know what 100% of an arbitrary value is. flex: 1 is shorthand that contains flex-grow: 1, meaning that #flex2 can grow infinitly without setting this width constraint.
Percentage-based widths bubble up to the point a fixed width is known, so all you have to do is set a width of 100% of #flexchild2 as well in order for #flexchild3 to inherit the width of #flexparent:
This can be seen in the following:
#flexparent {
display: flex;
}
#flexchild1 {
flex: 1;
background-color: green;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column;
width: 100%;
}
#flexchild3 {
background-color: purple;
width: 100%;
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
</div>
</div>
</div>
However, note that due to you using two columns, you'll probably want to give #flexparent a width of 100%, and set your two columns to 20% and 80% respectively. Note that #flexchild3 still inherits 100% of the width of #flexchild2 (which is 80% of the width of #flexparent):
#flexparent {
display: flex;
width: 100%;
}
#flexchild1 {
flex: 1;
background-color: green;
width: 20%;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column;
width: 80%;
}
#flexchild3 {
background-color: purple;
width: 100%;
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
</div>
</div>
</div>
Hope this helps! :)
This question already has answers here:
Is it possible for flex items to align tightly to the items above them?
(5 answers)
Make a div span two rows in a grid
(2 answers)
Closed 5 years ago.
I am trying to have one div on the left and two on the right. The bottomright should always be below the topRight div. The topRight is the only div with a variable height.
I am currently trying to achieve this using flexbox als you can see in my code below.
I would like to have some directions.
.wrapper {
display: flex;
height: 100px;
}
.left {
background-color: green
}
.topRight {
background-color: yellow
}
.bottomright {
background-color: red
}
<div class="wrapper">
<div class="left">Left</div>
<div class="topRight">TopRight</div>
<div class="bottomright">Bottom</div>
</div
With a fixed height on the container, as you have in your code, you can use flex-direction: column and flex-wrap: wrap. The fixed height serves as a break point, telling flex items where to wrap.
.wrapper {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100px;
}
.left {
flex: 0 0 100%; /* consumes full height of first column; forces siblings to wrap */
background-color: lightgreen
}
/* variable height div */
.topRight {
background-color: yellow
}
.bottomright {
flex: 1; /* consumes remaining space in column */
background-color: red
}
<div class="wrapper">
<div class="left">Left</div>
<div class="topRight">TopRight<br>variable height</div>
<div class="bottomright">Bottom</div>
</div>
On html put a div with a class called right wrapping both topRight and bottomRight and use this css on css:
.wrapper {
display: flex;
height: 100px;
}
.right {
display: flex-flow;
}
.left {
background-color: green
}
.topRight {
background-color: yellow;
height: 50px;
}
.bottomright {
background-color: red;
height: 50px;
}
I hope that helps you :)
For infos
display:grid is made for this .... very soon available for most browsers and yet for a few
A tutorial among others : https://css-tricks.com/snippets/css/complete-guide-grid/
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* any height s */
background-color: green;
}
.leftspan {
grid-row: span 2;/* if 2 rows avalaible */
}
.topRight {
background-color: yellow;
grid-column: 2 /-1
}
.bottomright {
background-color: red;
grid-column: 2 /-1
}
.bottomfull {
background-color: red;
grid-column: 1 /-1
}
<div class="wrapper">
<div class="leftspan">Left spanning 2 rows</div>
<div class="topRight">Top <br/>Right</div>
<div class="bottomright">Bottom <br/>Right</div>
</div>
<p> or did you mean ?
<div class="wrapper">
<div class="left">Left</div>
<div class="topRight">Top Right</div>
<div class="bottomfull">Bottom <br/>Right</div>
</div>
render if your browsers understand grid:
I want to separate my window in 2 equal parts, same height but width is 50% for each.
So I used this
.container {
display: flex;
height : 100%;
}
.column {
flex: 1;
height : 100%;
}
.column-one {
order: 1;
}
.column-two {
order: 2;
}
My html is structured like this
<div class="container">
<div class="column column-one"> Column 1
<div class="x" id="sliceX" ></div>
<div class="y" id="sliceY"></div>
<div class="z" id="sliceZ"></div>
</div>
<div class="column column-two"> Column 2
<div class="x" id="sliceX2"> </div>
<div class="y" id="sliceY2"></div>
<div class="z" id="sliceZ2"></div>
</div>
</div>
This is working well.
Now I want that my .x will take 100% of width but 50% of height. .y and .z will be displayed just after. Both taking 50% of height(the rest). But each class will only take 50% of width so .y will be displayed on the left and .z on the right
Like this:
Col1 Col2
xxxx xxxx
xxxx xxxx
yyzz yyzz
yyzz yyzz
How can I structure my css get this working with my actual separation in 2 columns ?
One thing you could try is to make your .column a flex container also and set it's wrap to allowing wrapping. Then set .x to width:100%; and .y, .z to width:50%; then give them all a height:50%;
Like this:
.column {
flex: 1;
height : 100%;
display:flex;
flex-wrap:wrap;
}
.x{
width:100%;
height:50%;
}
.y, .z{
width:50%;
height:50%;
}
See this fiddle.
You'll probably have best results with a second flex definition. You can use flex-wrap to wrap the layout quite effectively. Something like this:
html,
body {
height: 100%;
margin: 0;
}
.container {
display: flex;
height: 100%;
align-items: stretch;
}
.column {
flex: 0 0 50%;
display: flex;
flex-wrap: wrap;
align-items: stretch;
}
.x {
flex: 0 0 100%;
}
.y, .z {
flex: 0 0 50%;
}
.x {background-color: #ff8080}
.y {background-color: #80ff80}
.z {background-color: #8080ff}
<div class="container">
<div class="column column-one">
<div class="x" id="sliceX"></div>
<div class="y" id="sliceY"></div>
<div class="z" id="sliceZ"></div>
</div>
<div class="column column-two">
<div class="x" id="sliceX2"></div>
<div class="y" id="sliceY2"></div>
<div class="z" id="sliceZ2"></div>
</div>
</div>
In the above, the .x takes 100% of the width, pushing the .y and .z onto the second row. Each of these then takes 50% of the width, making a nice result. You can of course further adjust the balance to 30/70 or anything you choose.
Great job on using Flex, by the way - it's definitely a great tool for this job :)