Flexbox align-self is changing the div's height - css

I have a flexbox setup like this
.container {
display: flex;
min-height: 300px !important;
}
.space-between {
justify-content: space-between;
}
.align-end {
align-self: flex-end;
}
.align-center {
align-self: center;
}
<div class="container space-between">
<div class="child" style="max-height: 100px"></div>
<div class="child yellow-div" style="max-height: 50px"></div>
<div class="child blue-div" style="max-height: 150px"></div>
<div class="child pink-div"></div>
</div>
The problem is, when I tried setting the align-self to end or center by applying align-end to child#2 and align-center to child#3, it changes the height of the child where it is being applied.
Any explanation why this is occurring and the possible fix? Thanks

Unless we specify some align property it'll be defaulted to auto which will stretch the content to fill the flex,
auto computes to itself on absolutely-positioned elements, and to the computed value of align-items on the parent (minus any legacy keywords) on all other boxes, or start if the box has no parent. Its behavior depends on the layout model, as described for justify-self.
So in your case once you change the align property it'll change its height to auto(takes the content height) if there is no specific height applied.
Please check the below snippet. I've applied align-self to all the children's and then changed the second child's value to stretch
.container {
display: flex;
min-height: 300px !important;
}
.space-between {
justify-content: space-between;
}
.child{
width: 100px;
border: 1px dotted red;
align-self: baseline;
}
.align-end {
align-self: flex-end;
}
.align-center {
align-self: center;
}
.yellow-div{
background: yellow;
align-self: flex-end;
}
.yellow-div+div{
align-self: stretch;
}
.blue-div{
background: blue;
align-self: center;
}
.pink-div{
background: pink;
}
<div class="container space-between">
<div class="child yellow-div" style="max-height: 50px"></div>
<div class="child" style="max-height: 100px"></div>
<div class="child blue-div" style="max-height: 150px"></div>
<div class="child pink-div"></div>
</div>

align-self has a default value of auto meaning it will get align-items of parent flex container which has a default value of stretch and since the child#2 has a max-height:50px, it can only stretch up to 50px. When you change the align-self value to something else, child#2 won't stretch and its height probably get its min-height or the height of its children.
https://jsfiddle.net/6xwn80k3/ Check this fiddle and see what happens when you change align-self of child#2 with no defined height.

Related

How can I fit images with varying sizes in a flex row?

My understanding of flex is that this;
<div class="flex-container">
<img src="image-1">
<img src="image-2">
...
<img src ="image-n">
</div>
<style>
.flex-container {
display: flex;
justify-content: space-between;
}
.flex-container img {
flex-shrink: 1;
}
</style>
with random number of random sized images should produce a block of images of width 100% of its parent with the images reduced in size proportionally to fit. I don't want to wrap the items.
The result of the above is either an overflow of the container or distorted images with varying results depending on setting max- or min-height styles on parent or children.
My understanding is obviously wrong. But why?
I have added the snippet below, in Chrome the images fit the box but are distorted, in Firefox they spill out of the box.
Setting the images to display: block is not sufficient. They need to be enclosed.
Thanks to Adriano for the comment suggestion.
<div class="flex-container">
<div>
<img src="image-1">
</div>
<div>
<img src="image-2">
</div>
...
<div>
<img src ="image-n">
</div>
</div>
<style>
.flex-container {
display: flex;
justify-content: space-between;
}
.flex-container div {
flex-shrink: 1;
}
.flex-container div img {
width: 100%;
height: auto;
}
</style>
If you want your image to keep ratio, add align-items: flex-start; to your container.
"The default for the css "align-items" property is "stretch" which is what is causing your images to be stretched to its full original height. Setting the css "align-items" property to "flex-start" fixes your issue."
Or you set each image into a container (with display:block;).
if you want your image to break and go to the next line just add flex-wrap:wrap; to your container.
.flex-container {
display: flex;
justify-content: space-between;
/* ADDED */
align-items: flex-start;
/*flex-wrap:wrap;*/
}
.flex-container img {
flex-shrink: 1;
}
<div class="flex-container">
<img src="https://dummyimage.com/600x400/000/fff">
<img src="https://dummyimage.com/200x600/e31da8/000">
...
<img src ="https://dummyimage.com/60x40/000/fff">
</div>

how to make columns the same width with css flex

hello I need to basicaly display a table but with flex (only because I need to adjust the look for mobile)
.container {
display: flex
}
<div class="container">
<div class="row">
<div>1000</div>
<div>mary</div>
</div>
<div class="row">
<div>1</div>
<div>john</div>
</div>
<div class="row">
<div>11</div>
<div>mike</div>
</div>
</div>
how can I make each column have the same width? or at least the width of the largest item.
If you apply flex-grow: 1 to each div in the .row then it will expand accordingly. Note that the .row divs need the display flex (flex only apply to the DIRECT children of the flexed element.
The width can be set by using flex-basis and calc() and dividing the full-width by the number of columns you want (2 in this case). I added a border to demonstrate.
I would be remiss if I didn't suggest that the best tool to display a table structure - is a ... table... then you can work out how to modifiy for responsive layout - but the semantic structure of a table is correct for tabulr content.
.container {
width: 100%;
}
.row {
display: flex;
width: 100%;
}
.row div {
flex-grow: 1;
flex-basis: calc(100% / 2);
padding: 4px 8px;
border: solid 1px red;
}
<div class="container">
<div class="row">
<div>1000</div>
<div>mary</div>
</div>
<div class="row">
<div>1</div>
<div>john</div>
</div>
<div class="row">
<div>11</div>
<div>mike</div>
</div>
</div>
Use flex-basis to set the 'default' width first.
Use flex-grow and/or flex-shrink to allow it to grow /shrink
Use max-width' and min-width` to define by how much it can grow/shrink
.container{ #Stack the div inside the conainer
display:flex;
flex-flow: columns nowrap;
}
.row{ # Set div as cell in the row.
display:flex;
flex-flow: row nowrap;
flex-basis: 33%; # Calculate width from there.
flex-grow:1; #Allow resizing bigger
flex-shrink:1; #Allow resize smaller.
max-width:50%; #Adjust to your liking
min-width:25%; #Adjust o your liking
}
Please consider this ressource https://css-tricks.com/snippets/css/a-guide-to-flexbox/
You can add a flex-basis to the .row items by doing this:
.row {
flex-basis:calc(100% / 3);
}
.container {
width: 100%;
}
.row {
display: flex;
width: 100%;
}
.row div {
flex-grow: 1;
flex-basis: calc(100% / 2);
padding:10px;
margin: 5px;
background: #eee;
}
<div class="container">
<div class="row">
<div>1000</div>
<div>mary</div>
</div>
<div class="row">
<div>1</div>
<div>john</div>
</div>
<div class="row">
<div>11</div>
<div>mike</div>
</div>
</div>

Why is height:auto not working for this image?

I have a flexbox container with two flex items in it. One is an image and the other a paragraph. I've been trying to resize the image proportionally by giving width:some-percentage and height:auto but it's not working. Please help me solve this.
.item{
display:flex;
}
img{
width: 25%; /* not working */
height: auto;
}
<div class="item">
<img
src=
"https://png.pngtree.com/element_origin_min_pic/16/10/16/105802ebe43fe0f.jpg"/>
<p>some paragraph</p>
</div>
JSFiddle link - https://jsfiddle.net/dizzyramen/xfot3Lwv/2/
A default setting on a flex container is align-items: flex-start.
In a row-direction container, this makes flex items, not having a defined height (e.g. height: auto), extend the full height of the container (full explanation).
In this particular case, however, the image is stretching to its fullest, and expanding the size of the container along with it.
The solution is to set a height limit on the container or override the default with align-items: flex-start on the container or align-self: flex-start on the item.
jsFiddle demo
.item {
display: flex;
}
img {
width: 25%;
align-self: start; /* new */
}
<div class="item">
<img src="https://png.pngtree.com/element_origin_min_pic/16/10/16/105802ebe43fe0f.jpg" />
<p>some paragraph</p>
</div>
here is another option:
wrap your img in a div <div class="image-wrapper"> and set manage the width in this node.
asign width: 100%; height: auto; to the img so it adjust proportionally to its parent.
Here you have it in a snippet. Hope it helps.
<div class="item">
<div class="image-wrapper">
<img
src=
"https://png.pngtree.com/element_origin_min_pic/16/10/16/105802ebe43fe0f.jpg"/>
</div>
<p>some paragraph</p>
</div>
<style>
.item{
display:flex;
}
.image-wrapper {
width: 25%; /* means 25% of .item */
}
img{
width: 100%; /* means 100% of its parent .image-wrapper */
height: auto;
}
</style>
It happens because, per default the tag <img>is inline. You need to change it to block or flex

Set width of child elements in flex container/parent div

Is it possible, using flex, to set the width of children elements in the style of the their parent div?
For example I want each element in a flex container to stretch 1/3 of the container, or 1/2, or 100% width. They would all have equal widths. The width is a dynamic value which can change.
This issue is, I can add dynamic style values only to the .flex-container div. I can't add anything dynamic to .element divs.
So I can't do this...
<div class="flex-container">
<div class="element" style="width: 33%"></div>
<div class="element" style="width: 33%"></div>
etc...
</div>
Only..
<div class="flex-container" style="some value that will set children divs to 1/3 width of container, or 1/2, etc)">
<div class="element"></div>
<div class="element"></div>
etc...
</div>
My CSS for the flex container:
.flex-container {
display: flex;
flex-wrap: wrap;
}
.element {
// I can't add dynamic styles to this like width
}
Yes you can dynamically set the width.
Then use media queries to change them depending on your window size.
html, body {
height: 100%;
}
.flex-container {
display: flex;
height: 50%;
}
.element {
width: 33.33%;
align-self: stretch;
}
.element:nth-of-type(1) {
align-self: flex-start;
background: red;
}
.element:nth-of-type(2) {
align-self: flex-end;
background: green;
}
.element:nth-of-type(3) {
align-self: stretch;
background: blue;
}
<div class="flex-container">
<div class="element">
Test Element 1
</div>
<div class="element">
Test Element 2
</div>
<div class="element">
Test Element 3
</div>
</div>

Set flexbox children to have different heights to use up available space

Using a two-column flexbox layout, how can different-sized children be made to fill all available space, instead of all children having the height of the tallest child of the row?
I set up a demo on jsbin that illustrates the problem. I'd like for all the children to be the size of their wrapped contents.
#container {
width: 800px;
display: flex;
flex-wrap: wrap;
}
.cell {
width: 300px;
flex; 1 auto;
}
<div id="container">
<div class="cell">
Cells with arbitrarily long content.</div>
<div class="cell">
</div>
<div class="cell">
</div>
<div class="cell">
</div>
<div class="cell">
</div>
</div>
</body>
</html>
This is how Flexbox rows are expected to behave. Flexbox is not meant to recreate Masonry with pure CSS: items in one row cannot occupy space allocated for a preceding/following row (same goes for columns if you're using column orientation). You can use align-items to prevent them from stretching, but that's about it:
http://cssdeck.com/labs/9s9rhrhl
#container {
width: 800px;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
.cell {
width: 300px;
flex: 1 auto;
padding: 10px;
border: 1px solid red;
}
Otherwise, you should be using the column orientation or the multi-column module (see this SO answer: https://stackoverflow.com/a/20862961/1652962)

Resources