I can't figure out for the life of me how to make this page work.
I'm trying to have the "Top" be a header, the "Bottom" be the footer, and "table" and "section" be two separate columns in between.
Although I can't figure it out. Thanks.
html {
height: 100%;
}
body {
display: flex;
height: 100%;
justify-content: flex-start;
align-content: flex-start;
flex-direction: column;
flex-wrap: wrap;
margin: 0;
}
#pageTop {
background-color: lightgrey;
padding-left: 1em;
padding-top: .5em;
flex-grow: 1;
}
#table {
background-color: blue;
width: 50%;
flex-grow: 8;
flex-shrink: 1;
}
#pageSection {
background-color: lightpink;
width: 50%;
flex-flow: 8;
flex-shrink: 1;
}
#pageBot {
flex-grow: 1;
background-color: grey;
}
<body>
<div id="pageTop">Top</div>
<nav id="table">table</nav>
<div id="pageSection">section</div>
<div id="pagebot">Bottom</div>
</body>
Like Micheal_B stated:
Wrap the #table and the #section in one container. That container becomes the second flex item in the parent flex container. Then add display: flex to the new container.
Changes
Added main#pageContent to body and wrapped it around nav#table and section#pageSection
Added display: flex, justify-content: center, and flex: 2 0 auto
Changed all flex-grow and flex-shrink to flex shorthand.
ex. flex: 0 1 auto = flex-grow: 0 flex-shrink: 1 flex-basis: auto
note. The ruleset above is default for all flex children.
Removed align-content and justify-content; and changed the value of flex-wrap from wrap to nowrap; and added overflow:hidden and width: 100% to normalize a little.
Added width: 100% to everything with the exception of #pageSection and #table.
Added height: 2em to #pageTop and #pageBot(BTW, corrected typo)
Changed all of the tags to it's semantic equivalents.
main#pageContent
Height is set up to take up the freespace that the footer and header leave by height: calc(100% - 4em). This probably overkill since it also has flex: 2 0 auto.
It is a flex container (flex: display) and a flex child (flex: 2 0 auto)
section#pageSection
overflow-x: hidden will prevent any content from busting out of the borders sideways. overflow-y:auto will accommodate any content that extends the bottom border by adding a scrollbar. I have added content (a few <p>) to demonstrate.
SNIPPET
html {
height: 100%;
width: 100%;
}
body {
display: flex;
height: 100%;
width: 100%;
flex-direction: column;
flex-wrap: nowrap;
margin: 0;
overflow: hidden;
}
#pageContent {
width: 100%;
height: calc(100% - 4em);
display: flex;
justify-content: center;
flex: 2 0 auto;
}
#pageTop {
width: 100%;
height: 2em;
background-color: violet;
padding-left: 1em;
padding-top: .5em;
flex: 0 0 auto;
}
#table {
background-color: cornflowerblue;
width: 50%;
flex: 0 0 auto;
}
#pageSection {
background-color: darksalmon;
width: 50%;
flex: 1 0 auto;
overflow-x: hidden;
overflow-y: auto;
}
#pageBot {
width: 100%;
height: 2em;
flex: 0 0 auto;
background-color: gold;
}
<body>
<header id="pageTop">Top</header>
<main id='pageContent'>
<nav id="table">table</nav>
<section id="pageSection">
<p>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.</p>
<p>He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections. The bedding was hardly able to cover it and seemed ready to slide off any moment.</p>
<p>His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked. "What's happened to me? " he thought. It wasn't a dream.</p>
<p>His room, a proper human room although a little too small, lay peacefully between its four familiar walls.</p>
<p>A collection of textile samples lay spread out on the table - Samsa was a travelling salesman - and above it there hung a picture that he had recently cut out of an illustrated magazine and housed in a nice, gilded frame. It showed a lady fitted
out with a fur hat and fur boa who sat upright, raising a heavy fur muff that covered the whole of her lower arm towards the viewer. Gregor then turned to look out the window at the dull weather. Drops</p>
</section>
</main>
<footer id="pageBot">Bottom</footer>
</body>
Add a div with flex row, as it (adjust cols width with width attribute):
html {
height: 100%;
}
body {
display: flex;
height: 100%;
justify-content: flex-start;
align-content: flex-start;
flex-direction: column;
flex-wrap: wrap;
margin: 0;
}
#pageTop {
background-color: lightgrey;
padding-left: 1em;
padding-top: .5em;
}
#mainContainer {
display: flex;
flex-direction: row;
}
#table {
background-color: blue;
width: 50%;
}
#pageSection {
background-color: lightpink;
width: 50%;
}
#pagebot {
background-color: grey;
}
<body>
<div id="pageTop">Top</div>
<div id="mainContainer">
<nav id="table">table</nav>
<div id="pageSection">section</div>
</div>
<div id="pagebot">Bottom</div>
</body>
PS: I also fixed a pagebot/pageBot variant. Be aware, CSS is case-sensitive.
Related
I have a problem, I need a form that will be limited in width and use the gap.
CodePen
body {
margin: 0;
padding: 0;
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 18px;
min-height: 100vh;
}
.container--example {
background-color: #000;
width: 100%;
height: 100px;
}
<div class="container">
<div class="container--example"></div>
<div class="container--example"></div>
<div class="container--example"></div>
<div class="container--example"></div>
</div>
Here the div is stretched to 100%, the whole screen, I can set the width settings on the element in the container, but then gap will not work.
Thank you so much in advance for your answer
Unfortunately, I do not know how to fix this problem, I hope to find the answer here.
UPD: Also, it is possible to put widths on the text and so on, but it's too much of a pain.
Set a padding to the parent of .container, in the example that would be body.
CSS body { padding: 0 2rem } would create a space of 2rem on either side of .container, which would be true for every child of body.
With a little math you can even make that space responsive:
16px space on a 320px viewport
256px space on a 1920px viewport
would yield equation y = 0.15x + 32 using Linear Equation y=mx+b for points p1(320,16) and p2(1920,256).
body {
margin: 0;
/* Using y=mx+b => y = 0.15x + 32 for points p1(320,16) and p2(1920,256) */
padding: 0 calc(15vw - 2rem);
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 18px;
max-width: ;
min-height: 100vh;
}
.container--example {
background-color: #000;
width: 100%;
height: 100px;
}
<div class="container">
<div class="container--example"></div>
<div class="container--example"></div>
</div>
I'm trying to put two flex containers next to each other using flexbox, taking this layout as reference (I want it to be like the first row here, with part of the image on the left inside a box and the other one on the right)
This is my code so far for the two containers:
.chaco-container {
border: $borde-textos;
background-color: #bda89c;
margin: 0;
padding: 1em;
width: 50%;
display: inline-flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.plan-container {
background-color: white;
border: $borde-textos;
width: 50%;
display: inline-flex;
}
display: flex; needs to be applied on the parent container. Check out the below example snippet.
.flex-container {
display: flex;
}
.chaco-container {
width: 50%;
background-color: yellow;
}
.plan-container {
width: 50%;
background-color: skyblue;
}
<div class="flex-container">
<div class="chaco-container">...content</div>
<div class="plan-container">...content</div>
</div>
I think you might be facing gap between the two inline flex elements which is resulting to the second element going to the next line.
To fix this:
Use this as a reset:
*{
margin: 0;
padding: 0;
box-sizing:border-box;
}
2)Give negative margin to the plan(second) container:
margin-left:-4px;
(increase the number of negative pixels until both flexboxes are on the same row)
Sorry, another flexbox related question :)
I have two flex elements :
A container (red) containing a centered div (yellow)
A footer (blue) with an undefined height
The red container has a flex-grow:1 attribute, forcing it to take the remaining space on the screen
The issue happens when the yellow element is bigger than the screen size. I would like my red container to grow based on its content. Any idea of how I could do that ?
HTML:
<div class="container">
<div class="content"></div>
</div>
<div class="footer"></div>
CSS:
body,
html {
margin: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.container {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
background: red;
}
.content {
background: yellow;
height: 2000px;
width: 100px;
}
.footer {
flex-shrink: 0;
height: 50px;
background-color: blue;
}
https://codepen.io/stepinsight/pen/roRVGQ
== EDIT ==
Andre helped me find the answer, thanks heaps !
The only thing you need to change in the code above is to replace height by min-height and the % by vh for the body/html tags 🎉
body,
html {
margin: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
}
Simply remove the height property on the body element and add height: 100% to html
* { box-sizing: border-box; }
html {
height: 100%
}
body {
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
}
.container {
display: flex;
align-items: center;
justify-content: center;
background: red;
}
.content {
background: yellow;
height: 2000px;
width: 100px;
}
.footer {
height: 50px;
background-color: blue;
}
Corrected: https://codepen.io/ferreirandre/pen/maoVvb
Feel free to play around with the height of .content
I have a div with one image and one paragraph in it.
<div id="container">
<img src="..." />
<p>
This is my text
</p>
</div>
I use flex-box and flex-direction: column to align them.
#container {
display: flex;
flex-direction: column;
height: 300px;
width: 400px;
}
img {
max-width: 80%;
flex-basis: 50%;
}
p {
flex-basis: 50%;
}
Since both img and p have flex-basis 50% I would expect each of them to take up 50% of the space. In Firefox it works, but in Chrome the image is bigger (in height) than the container itself.
I have made a jsfiddle to demonstrate this: https://jsfiddle.net/q2esvro9/1/
How can I get the behaviour from Firefox in Chrome?
(Another interesting fact: In Internet Explorer 11 the image and text take up the same space, but the image is stretched in width. Which means 3 different behaviours for a very short and simple CSS code)
#container {
display: flex;
align-items: center;
align-content: center;
text-align: center;
flex-direction: column;
border: solid 2px red;
height: 300px;
width: 400px;
}
img {
max-width: 80%;
flex-basis: 50%;
}
p {
flex-basis: 50%;
border: solid 2px green;
}
<div id="container">
<img src="https://image.freepik.com/free-icon/apple-logo_318-40184.jpg" />
<p>
This is my text
</p>
</div>
There are flexbox rendering variations between the major browsers.
When dealing with images, the number of variations grows.
What I've found to work consistently across browsers is to not use img elements in a flex formatting context (i.e., don't make them flex items).
Instead, wrap an img in a div element, making the div the flex item and keeping the image in a block formatting context.
#container {
display: flex;
align-items: center;
align-content: center;
text-align: center;
flex-direction: column;
border: solid 2px red;
height: 300px;
width: 400px;
}
#container > div {
flex: 0 0 50%; /* 1 */
min-height: 0; /* 2 */
}
img {
height: 100%;
}
p {
flex-basis: 50%;
border: solid 2px green;
}
<div id="container">
<div>
<img src="https://image.freepik.com/free-icon/apple-logo_318-40184.jpg" />
</div>
<p>
This is my text
</p>
</div>
Notes:
The meaning and benefits of flex: 1
Why don't flex items shrink past content size?
I have a flexbox-based layout with two panels (top and bottom) occupying 1/3 and 2/3 of the viewport, respectively. (Actually there are more panels, but I've distilled it to the minimal example).
The top panel is also a flex container, because I want its children to flow top to bottom and be vertically centered when there is room. When there is more stuff in top panel than would fit in it, I want it to be scrollable, hence overflow: auto.
The problem: the contents of top shrink to its size, even with flex-shrink: 0, and the scrollbar never pops up.
Observe how the content is shrunk in the following demo, even though it has an explicitly specified height:
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.main {
display: flex;
height: 100%;
flex-direction: column;
}
.top {
display: flex;
flex-direction: column;
flex-basis: 33%;
border-bottom: 1px solid #ccc;
overflow: auto;
justify-content: center;
padding: 20px;
}
.bottom {
overflow: auto;
flex-basis: 67%;
}
.content {
height: 500px;
background-color: #eee;
}
<div class="main">
<div class="top">
<div class="content">Content</div>
</div>
<div class="bottom"></div>
</div>
The questions:
How to fix this while preserving the layout requirements? Disabling display: flex for the top panel gives the desired effect in the demo. I could position contents of top in a flexboxless way, but I lose the benefits of flex layout and the automatic vertical centering.
Why does this happen? References to CSS spec would be welcome.
You wrote:
The problem: the contents of top shrink to its size, even with flex-shrink: 0, and the scrollbar never pops up.
Actually, the solution is flex-shrink: 0. So the question becomes, where did you apply it?
It wouldn't work if you applied it to top – a flex item in the primary container with flex-basis: 33% (i.e., height: 33%, in this case) – because the length of top is a percentage. As such, it will shrink / expand naturally as percentage lengths are relative to the parent container.
You need to apply flex-shrink: 0 to .content – a flex item in the nested container with a fixed height (height: 500px / flex-basis: 500px).
So this will work:
.content {
height: 500px;
flex-shrink: 0;
}
or this:
.content {
flex-basis: 500px;
flex-shrink: 0;
}
or, better yet, this:
.content {
flex: 0 0 500px; /* don't grow, don't shrink, stay fixed at 500px */
}
From the spec:
7.2. Components of
Flexibility
Authors are encouraged to control flexibility using the flex shorthand
rather than with its longhand properties directly, as the shorthand
correctly resets any unspecified components to accommodate common
uses.
body {
margin: 0;
}
.main {
display: flex;
flex-direction: column;
height: 100vh;
}
.top {
display: flex;
flex-direction: column;
flex-basis: 33%;
border-bottom: 1px solid #ccc;
overflow: auto;
justify-content: center;
padding: 20px;
}
.bottom {
overflow: auto;
flex-basis: 67%;
}
.content {
flex: 0 0 500px;
background-color: #eee;
}
<div class="main">
<div class="top">
<div class="content">Content</div>
</div>
<div class="bottom"></div>
</div>
Then you have a second problem, which is that the upper section of the top element gets cut off and is inaccessible via scroll. This is caused by justify-content: center on the container.
This is a known issue. It is solved by using flex auto margins.
So instead of this:
.top {
display: flex;
flex-direction: column;
flex-basis: 33%;
border-bottom: 1px solid #ccc;
overflow: auto;
/* justify-content: center; <--- REMOVE */
padding: 20px;
}
do this:
.content {
flex: 0 0 500px;
margin: auto 0; /* top & bottom auto margins */
background-color: #eee;
}
body {
margin: 0;
}
.main {
display: flex;
flex-direction: column;
height: 100vh;
}
.top {
display: flex;
flex-direction: column;
flex-basis: 33%;
border-bottom: 1px solid #ccc;
overflow: auto;
/* justify-content: center; USE AUTO MARGINS ON FLEX ITEM INSTEAD */
padding: 20px;
}
.bottom {
overflow: auto;
flex-basis: 67%;
}
.content {
flex: 0 0 500px;
margin: auto 0;
background-color: #eee;
}
<div class="main">
<div class="top">
<div class="content">Content</div>
</div>
<div class="bottom"></div>
</div>
Here's a complete explanation:
Can't scroll to top of flex item that is overflowing container
The scrollbar appears when there are enough .content element shrinked to their very minimal height (one line height in this case).
That's not really how things work with flex. height is not strictly respected. If you still want to work with height, you can fix this by setting a min-height to .content according to the minimum height you want for them.
Or you can instead set flex on .content (and get rid of height):
css
flex: 100px 1 0;
Which will set a minimum height (flex-basis) of 100px, flex-grow at 1 so that it takes all the available space, and flex-shrink at 0 so that the element is always at least 100px tall.