Make flexbox divs wrap content vertically - css

I am trying to get three flex box divs placed next to each other in a row.
<div style="display: flex; flex-direction: row">
<div style="flex:1; border: 1px solid #ccc;">1<br />A<br />B<br />C<br />D<br />E</div>
<div style="flex:1; border: 1px solid #ccc;">2</div>
<div style="flex:1; border: 1px solid #ccc;">3</div>
</div>
Here, I have not applied any height style to the child divs but they show up like
Notice that the div with content 2 and 3 have assumed the height of 1st division with content, 1ABCDE
Fiddle of the above code
https://jsfiddle.net/4oddowjw/4/
I want it to look like this but I do not have the luxury to use height on these divs
I cannot specify the height. As in my application, height is dynamic and applied to children of these flex boxes.
Is there a way to make these divs wrap their content vertically ?
I tried adding 'height: auto' to the divs but it did not work out
Example with 'height: auto' applied https://jsfiddle.net/4oddowjw/5/

You have to add align-items:flex-start; to the container:
.container {
align-items:flex-start;
display: flex;
flex-direction: row;
}
.item {
flex:1;
border: 1px solid #ccc;
}
<div class="container">
<div class="item">1<br />A<br />B<br />C<br />D<br />E</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
Your updated fiddle: https://jsfiddle.net/4oddowjw/7/
Explanation:
The default alignment of the container items is stretch. All the items has the equals height. If you want to wrap the items by content you have to overwrite this default value on the container with align-items:flex-start;.
More information about flexbox you can find here: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
The official W3C specification: https://drafts.csswg.org/css-flexbox-1/#align-items-property

Related

Is there a CSS-way to make text grow column-wise horizontally

I'm working for a client that had the super good idea to integrate a horizontal scroll effect into his one pager flow layout. That means that the user keeps scrolling down, but at some point the page starts moving from right to left instead of bottom to top. I implemented that via ScrollMagic.
So the problem starts when it gets responsive. When I start scrolling horizontally, the screen is now fixed to the device height and I need to extend my page content to the right when it flows out, instead of the normal "my content just flows out of the bottom, which I can follow by vertically scrolling".
My first idea was to kind of manually solve the problem when managing the content. I.E. giving different versions of content for mobile and desktop content. But it seems devices are just too different and I need a CSS solution.
My Question is: Do you have any idea of how to make content grow horizontally? Like height auto, but width "auto" (which doesn't work bc it's not the same)? Or like display: inline-block in the following example, but the outer wrapper (yellow border) wrapping all sub-boxes, not just the first column.
#wrapper {
display: inline-block;
border: 2px solid #ffff00;
}
#main {
width: 100%;
height: 200px;
border: 1px solid #0000ff;
display: flex;
flex-flow: column wrap;
}
#main div {
width: 100%;
height: 50px;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="wrapper">
<div id="main">
<div style="background-color:coral;">A</div>
<div style="background-color:lightblue;">B</div>
<div style="background-color:khaki;">C</div>
<div style="background-color:pink;">D</div>
<div style="background-color:lightgrey;">E</div>
<div style="background-color:lightgreen;">F</div>
</div>
</div>
</body>
</html>
EDIT:
After reading Temani Afifs Answer I found an additional specification of my problem: I need it to work with "column-width", so that I am able to write text which automatically expands to a second column when using up all vertical space. Pretty much just like here. The only reason the linked example is not perfect for me is that the wrapping container div does not expand and a scrollbar appears. I want to be able to add another .container-div to the right.
Maybe using CSS grid:
#wrapper {
display: inline-block;
background:yellow;
}
#main {
max-height: 100vh; /* don't take more than the screen height */
border: 1px solid #0000ff;
box-sizing:border-box;
display: grid;
grid-auto-flow: column; /* column flow */
/* fill all the column and wrap to the next one if no more space */
grid-template-rows: repeat(auto-fill, minmax(50px, 1fr));
}
#main div {
padding:20px;
}
body {
margin: 0;
}
<div id="wrapper">
<div id="main">
<div style="background-color:coral;">A</div>
<div style="background-color:lightblue;">B</div>
<div style="background-color:khaki;">C</div>
<div style="background-color:pink;">D</div>
<div style="background-color:lightgrey;">E</div>
<div style="background-color:lightgreen;">F</div>
</div>
</div>

Max-width not working on Flexbox item (item is shrinking to width of content)

I have a full viewport width, full viewport height "hero image" on a homepage. I've made this a Flex container. Inside the flex container is one child div (containing a heading). This flex item should be aligned to the bottom of the flex container. It has a max-width and should be horizontally centered inside the parent.
However, the max-width is being ignored. The div is taking the width of its content - the heading. Please see JS Fiddle: https://jsfiddle.net/4h7q6d5x/
As you can see the .main div inside the hero image is taking the width of its content - unlike the .main div below the hero image.
I have looked at various questions, including this one max-width not working on flex item
But adding width:100% to the flex item doesn't work. At smaller viewport sizes the the width and padding don't play nicely and the heading is cropped off the right hand edge.
How do I get max-width to work with Flexbox?
.hero_image {
min-height: 100vh;
background-color:yellow;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.main {
max-width:500px;
margin:0 auto;
padding:0 50px;
background-color:pink;
}
<div class="hero_image">
<div class="main">
<h1>Heading <br>couple of words</h1>
</div>
</div>
<div class="main">
<p>Lots of content</p>
</div>
The default "width" (actually flex-basis) inside flex-containers is auto which makes it only as wide as it's content.
But adding width:100% to the flex item doesn't work. At smaller viewport sizes the the width and padding don't play nicely and the heading is cropped off the right hand edge.
Then I'd suggest a couple of changes. Don't use a flex-column but position your .main div using align-items:flex-end.
Then set the default "width" (actually flex-grow) with flex: 1.
.hero_image {
min-height: 50vh;
/* for example */
background-color: yellow;
display: flex;
align-items: flex-end;
justify-content: center;
}
.main {
flex: 1;
max-width: 50%;
/* for example */
margin: 0 auto;
padding: 0 50px;
background-color: pink;
}
<div class="hero_image">
<div class="main">
<h1>Heading <br>couple of words</h1>
</div>
</div>
<div class="main">
<p>Lots of text</p>
</div>

layouting 2 divs with dynamic content

I need to layout 2 divs (http://jsfiddle.net/tWE8W/) positioned in a container with a fixed width and height:
<div class="container">
<div class="left">
<div class="element"></div>
</div>
<div class="right">
<div class="element"></div>
</div>
</div>
both divs contain divs of type element with fixed dimensions. the elements can be added and removed dynamically.
div1 is positioned left. The elements should be stacked 2 high and grow to the right.
div2 is positioned right.The elements should be positioned horizontally (float: left). When the elements reach the right corner of div2 (also the rght corner of the container). The should start a new line.
div1 should have a dynamic width based on th enumber of elements it contains.
it only needs to work on the latest version of Google Chrome.
Use the Flexible Box Layout for the boxes on the left like
A C E
B D
FIDDLE
(Relevant) CSS
.left{
float:left;
display:flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
}
Browser support is also quite good nowadays
EDIT:
You can fiddle with the align-content property to align the boxes on the left.
Setting align-content: space-between; spaces the boxes out like this:
FIDDLE
I hope i understood right http://jsfiddle.net/nindos/8DTp2/9/
<style>
.container
{
height: 50px;
width: 300px;
overflow: hidden;
border: 1px solid black;
}
.left,.right{float:left;width:50%;height:100%;overflow:auto}
.left{background-color:red}
.right{background-color:blue}
.element{display:inline-block;background-color:pink}</style>

How to left-center two elements using flexbox?

This is what I want to have:
I want to be able to left-center two elemenets using flexbox. It would be easy to do this (as I have shown in the jsfiddle, if I had a third box called C, but I have not found a solution to the image above this with flexbox. Anyone?
HTML:
<div class="parent">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
</div>
CSS:
.parent {
display: flex;
border: 1px solid grey;
justify-content: space-between;
}
The code on jsfiddle: http://jsfiddle.net/3DD6E/
Add the following style to all of the child containers:
.parent div{
flex:1;
}
The flex style alters the space within the flex box (available to it) that the element will take up (1=100%) or 'take up 100% of what you can' -- which in this case would be 50% of the parent.
JSFiddle

How to vertically align div in another div with text?

I'm trying to center a div vertically in a parent div, where text is present. Here's what I've got:
It looks a little funny because the text seems to be centered properly, but the yellow boxes aren't. This is how I'm doing it:
.btn {
background-color: #ccc;
color: #000;
width: 200px;
border: solid 1px black;
text-align: center;
vertical-align: middle;
display: table-cell;
}
.square {
background-color: #ff0;
width: 20px;
height: 20px;
display: inline-block;
}
.inner {
display: inline-block;
}
<div class="btn">
<div class="square"></div>
<div class="inner">Hello</div>
<div class="square"></div>
</div>
Should my usage of "table-cell" + vertical-align be working? I only care about html5, I'm really just targeting the latest versions of mobile safari, so don't have to worry about older browsers etc.
Here's a js fiddle of this:
http://jsfiddle.net/TrJqF/
Thanks
Set vertical-align:top on the square class. The extra space comes from space reserved for descendant text elements like j, g, y etc. that drop below the line.
jsFiddle example
Actually there is no difference between both the height. Apply yellow background color to inner class and see the difference in explicit and no height.
both square div doesn't have content and inner div have content. The css box aligning by itself based on its content. Add empty space to the square div as follows:
<div class="btn">
<div class="square"> </div>
<div class="inner">Hello</div>
<div class="square"> </div>
</div>
If you want you can add top and bottom margin 1 or 2 pixel which will show your expectation.

Resources