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>
Related
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>
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>
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.
I am wondering if this is possible: I have a header that can contain a variable amount of text. Below that I have another element which I want to take up the remaining height of the page.
<div class="header row">
<div class="title column large-5">Potentially very long text</div>
<div class="menu column large-7">Menu items</div>
</div>
<div class="content">
</div>
<div class="footer">
</div>
Normally I would do this using calc, eg:
.content {
height: calc(100vh - 75px);
}
Where 75px is the set height of .header.
But in this example, the .header element is dynamic and does not have a set height. Only a padding and font-size are set.
To complicate things, this also uses the Foundation Grid layout, which makes me nervous about using display: table (.title and .menu sit side by side on desktop, but stacked on mobile) .
Is there anyway to get the height of the dynamic header element (without resorting to JQuery)?
You can use flexbox and set .content to flex-grow: 1 so that it will fill to grow the available space.
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
.content {
flex-grow: 1;
background: #eee;
}
<div class="header row">
<div class="title column large-5">Potentially very long text</div>
<div class="menu column large-7">Menu items</div>
</div>
<div class="content">
</div>
<div class="footer">
</div>
I made a small pen to show the way to do this using flex box, it involved changing your markup a bit:
css:
.container {
display: flex;
flex-direction: column;
height: 250px; // whatever you want here
}
.header {
width: 100%;
background: red;
padding: 10px;
}
.content {
background: yellow;
width: 100%;
flex-grow: 1;
}
So the content will always take the available space inside the content div.
check the whole pen: http://codepen.io/anshul119/pen/yMYeLa
hope this helps.
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)