Trouble aligning items with flexbox [duplicate] - css

This question already has an answer here:
Remove space (gaps) between multiple lines of flex items when they wrap
(1 answer)
Closed 4 years ago.
enter code hereI can't really explain it better than this code example.
https://codepen.io/anon/pen/BYeger
I want to make #thing_down_here touch #thing_up_here, but I can't figure out the right combination.
html, body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box
}
#parent {
width: 100vw;
height: 100vh;
background: cornsilk;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
#thing_up_here {
flex: 1 0 100%;
background: skyblue;
height: 80px;
}
#thing_down_here {
flex: 0 0 50%;
background: lightgreen;
height: 100px;
}
<div id="parent">
<div id="thing_up_here"></div>
<div id="thing_down_here"></div>
</div>

You need to use use the align-content property to set the distribution along the cross-axis.
html, body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box
}
#parent {
width: 100vw;
height: 100vh;
background: cornsilk;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: flex-start;
}
#thing_up_here {
flex: 1 0 100%;
background: skyblue;
height: 80px;
}
#thing_down_here {
flex: 0 0 50%;
background: lightgreen;
height: 100px;
}
<div id="parent">
<div id="thing_up_here"></div>
<div id="thing_down_here"></div>
</div>
Read more about align-content.

Add align-content: flex-start to #parent
This defines the default behaviour for how flex items are laid out along the cross axis on the current line. Think of it as the justify-content version for the cross-axis (perpendicular to the main-axis).
flex-start: cross-start margin edge of the items is placed on the cross-start line
The default is stretch which is causing your issue
More on it at https://css-tricks.com/snippets/css/a-guide-to-flexbox/
html, body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box
}
#parent {
width: 100vw;
height: 100vh;
background: cornsilk;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: flex-start;
}
#thing_up_here {
flex: 1 0 100%;
background: skyblue;
height: 80px;
}
#thing_down_here {
flex: 0 0 50%;
background: lightgreen;
height: 100px;
}
<div id="parent">
<div id="thing_up_here"></div>
<div id="thing_down_here"></div>
</div>

Related

Resize flex item based on its content

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

Breaking a line with flexbox centering?

I'm trying to vertically/horizontally center my Title with the Subtitle directly beneath it. Here was my attempt:
html, body, h1 {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>
As you can see, the subtitle is in the same line as the h1, I'm trying to get it to go beneath it. I've tried setting h1 to display: block; but that seems to not work when using display: flex on the container. Any help would be appreciated.
Set flex-direction: column on container
html, body, h1 {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
}
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>
Setting flex-direction to column is one solution. It's already provided in another answer.
In some cases, if flex-direction: row is preferred (or a necessity), you can add flex-wrap: wrap to the container and give the first item a 100% width, which forces the second item to the next line.
body, h1 {
margin: 0;
padding: 0;
}
#container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
flex-wrap: wrap; /* NEW */
align-content: center; /* NEW */
text-align: center; /* NEW */
}
h1 { flex: 0 0 100%; } /* NEW */
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>

Flex item same width as children

I'm trying to make a container element, a flex item, the same width as it's span text child. As you can see by inspecting the result from the snippet, although the container .calc-text-container takes up more space than the child element does, even though the flex-grow-property is set to 0.
Is there a way to achieve the desired result?
.calc {
width: 230px;
background: green;
height: 100px;
display: flex;
justify-content: center;
flex-direction: column;
}
.calc a {
display: flex;
justify-content: center;
}
.calc-icon-container {
margin-right: 1em;
}
.calc-text-container {
flex: 0 0 0;
background: rgba(20,200,0,0.8);
}
<div class="calc">
<a href="#">
<div class="calc-icon-container"><span class="calc-icon">🔫</span></div>
<div class="calc-text-container"><span class="calc-text">To do something megagiga</span></div>
</a>
</div>
Just flex: 0 0 0; will do the job.
.calc {
width: 230px;
background: green;
height: 100px;
display: flex;
justify-content: center;
flex-direction: column;
}
.calc a {
display: flex;
justify-content: center;
}
.calc-icon-container {
margin-right: 1em;
}
.calc-text-container {
flex: 0 0 0; // or just flex: 0;
background: rgba(20,200,0,0.8);
}
<div class="calc">
<a href="#">
<div class="calc-icon-container"><span class="calc-icon">🔫</span></div>
<div class="calc-text-container"><span class="calc-text">Reallylongword Short shortandlong</span></div>
</a>
</div>

Aligning flex items horizontally in a vertical flex container

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.

CSS Flex Box Layout: full-width row and columns

Hello fellow programmers!
I've got a simple box-layout which I would love to achieve using flexbox, but I simply can't figure it out. It should look like this image.
So basically a row and two columns, with the row being fixed at lets say 100px in height, but all in one container. My code so far is:
#productShowcaseContainer {
display: inline-flex;
flex-flow: row wrap;
height: 600px;
width: 580px;
background-color: rgb(240, 240, 240);
}
#productShowcaseTitle {
display: inline-block;
height: 100px;
width: 100%;
background-color: rgb(200, 200, 200);
}
#productShowcaseDetail {
flex: 3;
background-color: red;
}
#productShowcaseThumbnailContainer {
flex: 2;
background-color: blue;
}
<div id="productShowcaseContainer">
<div id="productShowcaseTitle"></div>
<div id="productShowcaseDetail"></div>
<div id="productShowcaseThumbnailContainer"></div>
</div>
I know this can be achieved in many ways, but I would really prefer to use CSS Flex.
You've almost done it. However setting flex: 0 0 <basis> declaration to the columns would prevent them from growing/shrinking; And the <basis> parameter would define the width of columns.
In addition, you could use CSS3 calc() expression to specify the height of columns with the respect to the height of the header.
#productShowcaseTitle {
flex: 0 0 100%; /* Let it fill the entire space horizontally */
height: 100px;
}
#productShowcaseDetail,
#productShowcaseThumbnailContainer {
height: calc(100% - 100px); /* excluding the height of the header */
}
#productShowcaseContainer {
display: flex;
flex-flow: row wrap;
height: 600px;
width: 580px;
}
#productShowcaseTitle {
flex: 0 0 100%; /* Let it fill the entire space horizontally */
height: 100px;
background-color: silver;
}
#productShowcaseDetail {
flex: 0 0 66%; /* ~ 2 * 33.33% */
height: calc(100% - 100px); /* excluding the height of the header */
background-color: lightgray;
}
#productShowcaseThumbnailContainer {
flex: 0 0 34%; /* ~ 33.33% */
height: calc(100% - 100px); /* excluding the height of the header */
background-color: black;
}
<div id="productShowcaseContainer">
<div id="productShowcaseTitle"></div>
<div id="productShowcaseDetail"></div>
<div id="productShowcaseThumbnailContainer"></div>
</div>
(Vendor prefixes omitted due to brevity)
Alternatively, if you could change your markup e.g. wrapping the columns by an additional <div> element, it would be achieved without using calc() as follows:
<div class="contentContainer"> <!-- Added wrapper -->
<div id="productShowcaseDetail"></div>
<div id="productShowcaseThumbnailContainer"></div>
</div>
#productShowcaseContainer {
display: flex;
flex-direction: column;
height: 600px; width: 580px;
}
.contentContainer { display: flex; flex: 1; }
#productShowcaseDetail { flex: 3; }
#productShowcaseThumbnailContainer { flex: 2; }
#productShowcaseContainer {
display: flex;
flex-direction: column;
height: 600px;
width: 580px;
}
.contentContainer {
display: flex;
flex: 1;
}
#productShowcaseTitle {
height: 100px;
background-color: silver;
}
#productShowcaseDetail {
flex: 3;
background-color: lightgray;
}
#productShowcaseThumbnailContainer {
flex: 2;
background-color: black;
}
<div id="productShowcaseContainer">
<div id="productShowcaseTitle"></div>
<div class="contentContainer"> <!-- Added wrapper -->
<div id="productShowcaseDetail"></div>
<div id="productShowcaseThumbnailContainer"></div>
</div>
</div>
(Vendor prefixes omitted due to brevity)
Just use another container to wrap last two divs.
Don't forget to use CSS prefixes.
#productShowcaseContainer {
display: flex;
flex-direction: column;
height: 600px;
width: 580px;
background-color: rgb(240, 240, 240);
}
#productShowcaseTitle {
height: 100px;
background-color: rgb(200, 200, 200);
}
#anotherContainer{
display: flex;
height: 100%;
}
#productShowcaseDetail {
background-color: red;
flex: 4;
}
#productShowcaseThumbnailContainer {
background-color: blue;
flex: 1;
}
<div id="productShowcaseContainer">
<div id="productShowcaseTitle">1</div>
<div id="anotherContainer">
<div id="productShowcaseDetail">2</div>
<div id="productShowcaseThumbnailContainer">3</div>
</div>
</div>
This is copied from above, but condensed slightly and re-written in semantic terms. Note: #Container has display: flex; and flex-direction: column;, while the columns have flex: 3; and flex: 2; (where "One value, unitless number" determines the flex-grow property) per MDN flex docs.
#Container {
display: flex;
flex-direction: column;
height: 600px;
width: 580px;
}
.Content {
display: flex;
flex: 1;
}
#Detail {
flex: 3;
background-color: lime;
}
#ThumbnailContainer {
flex: 2;
background-color: black;
}
<div id="Container">
<div class="Content">
<div id="Detail"></div>
<div id="ThumbnailContainer"></div>
</div>
</div>

Resources