Try to imagine a situation
there is a div and inside the container there are three divs ,
and sometimes we need to let the inside divs self-adaption.
like this
css:
.a{display:-webkit-box;width:300px;height:100px;background:#222}
.a div{-webkit-box-flex:1;height:100px}
.a-1{background:red}
.a-2{background:yellow}
.a-3{background:blue}
html:
<div class="a">
<div class="a-1">abc</div>
<div class="a-2">abcdddd</div>
<div class="a-3">abcdddddddde</div>
</div>
but a-1 ,a-2 , a-3 do not self-adaption .i mean a-1 a-2 a-3 do not equal in length. it seems also depends on the text length.
how solve?
Looks like you have misunderstood the purpose of the flexible box layout. It works by taking the unused space in the containing element and adding into its children. So for example if your containing box is 300px, and you have three elements originally 80px, 100px, and 60px, then you have 300-80-100-60 = 60px. Then if your three child elements all have a flex value of 1 then it allocates 60/(3*1) = 20px to each. So the child sizes are now 100px, 120px, and 80px.
For your example, as you want them equal sizes, you should make the -webkit-box-flex to 0 for all three children, but set their width (or height if appropriate) to 33.33% each.
I have occasions where I do not know the number of elements that will be within an element, but I still want them to be layed out evenly. For instance if I had 3 elements their width would be 33%, but for 4 elements the width would be 25%. To get around this I set the width to 1% first, then set flex to 1.
.flex-container {
display: -webkit-box;
display: -moz-box;
display: -ms-box;
display: box;
}
.flex-element {
-webkit-box-flex: 1;
-moz-box-flex: 1;
-ms-box-flex: 1;
box-flex: 1;
width: 1%;
}
I think you need to add display: -webkit-box to .a div{-webkit-box-flex:1;height:100px}
Related
I have a flex container with three children. Each child has a min and max width and I would like to have them grow/shrink in a specific order. So, as the window width decreases, Item1 should shrink to its min width, and then Item2 should decrease to its min width, followed by Item3. Can someone help me figure out what I'm doing wrong? I've tried to discern from the documentation how to get the order set up, but I'm just not understanding.
<div className="MainContainer">
<div className="Item1">
I should shrink first/expand last!
</div>
<div className="Item2">
I should shrink & expand second!
</div>
<div className="Item3">
I should shrink last/expand first!
</div>
</div>
And my CSS:
.MainContainer {
display: flex;
flex-direction: row;
justify-content: center;
padding-left: 15px;
padding-right: 15px;
}
//Should shrink first/expand last
.Item1{
min-width: 350px;
max-width: 816px;
flex: 1;
flex-grow: 0;
}
//Should shrink/expand second
.Item2{
max-width: 816px;
flex: 1;
flex-grow: 1;
}
//Should shrink last/expand first
.Item3{
min-width: 300px;
max-width: 224px;
flex: 1;
flex-grow: 2;
}
That's not the way flexbox works, you can't say "shrink last" - all you can say is "shrink/grow at a rate in proportion to other items shrink/growth rates"
I imagine you're also generally setting too many widths and confusing yourself about which properties are actually taking effect. Just let things happen naturally and see where they end up.
This is an example with commentary that will hopefully paint a clearer picture:
.Item1{
flex-grow: 1;
flex-shrink: 0;
flex-basis: 350px;
// this means it will not shrink, have a min width of 350px, and grow at a rate of "1" (proportional to the other children in it's container) to fill up the remaining space
// flex: 1 0 350px; <- the above is the same as this
}
//Should shrink/expand second
.Item2{
flex-grow: 1;
flex-shrink: 0;
flex-basis: auto; // this means it will not shrink, have a min width of it's "intrinsic size" and grow AT THE SAME RATE (1) as Item1 to fill up the remaining space
// flex: 1; <- this is the shorthand for the above
}
The best reference on the internet for flexbox is https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Using this SO question as a starting point, I was able to achieve my goal.
I have slightly simplified the sizes to make it easier to read, but I have gotten my project working in the same way.
Check out this codesandbox to see my fully working implementation using React and TypeScript (popping the preview out to a new window will help see what's going on). I have created a custom component that will show the current size of each element as the window is resized. This is not necessary for doing this yourself, of course.
The main thing to look at is the wrappers that hold my resizing elements and the styles in the scss, specifically how the 'first-to-shrink' and 'second-to-shrink' classes are combined with the max-width, min-width, and flex-basis set on individual components. One other 'gotcha' is that I had to set the flex-basis of the container that housed two elements as the sum of the children's max-widths.
I have 3 objects that need to shrink/expand in a specific order. In display order, they are:
Secondary Document - Primary Document - Answer Pane
Secondary Document has a min width of 250px, a max width of 500px, and should shrink first.
Primary Document has a min width of 250px, a max width of 500px, and should shrink last.
Answer Pane has a min width of 150px, a max width of 300px, and should shrink second.
After all 3 objects have shrunk to their minimum, there is overflow that happens, but that is ok with my implementation.
The 'trick' here is that I had to use wrapper/container objects in twos:
SecondaryDocument-container houses the Secondary Document while PrimaryDocument-AnswerPane-container houses both the Primary Document and Answer Pane.
I am using flex property to display the progress of work in an office. I have multiple rows of data displaying. But the child div width is showing differently on each row depends on a number of children inside the parent div. How to show every time equal width for all same values ?
Thank you 04FS for the information on flex-grow and flex-shirnk to make zero. I have changed the CSS for my flex box and given the width of each column in %. This solved my issue
#parent
{
width: 750px;
display: flex;
}
.grow {
width: 100%;
text-align:center;
white-space:nowrap;
}
I am attempting to create a layout using Flexbox. In one of these layouts, I want 3 equal width columns. To accomplish this I am using calc to set the column width. This is working fine in modern browsers, but of course in IE it doesn't want to work. Here is my code:
.container {
width:50vw;
margin:0 auto;
display:flex;
}
.container > div {
flex:1 0 calc(100% / 3);
}
<div class="container">
<div>Test</div>
<div>Test</div>
<div>Test</div>
</div>
As I mentioned, this works fine in modern browsers, but in IE the columns just collapse on each other unless I use a specific percentage in place of calc.
It's a known bug.
IE 10-11 ignore calc() functions used in flex shorthand declarations.
Since this bug only affects the flex shorthand declaration in IE 11, an easy workaround (if you only need to support IE 11) is to always specify each flexibility property individually.
source: https://github.com/philipwalton/flexbugs#flexbug-8
So, in other words, instead of:
flex: 1 0 calc(100% / 3)
Try:
flex-grow: 1;
flex-shrink: 0;
flex-basis: calc(100% / 3);
Also, consider this: You don't even need the calc() function.
If you want three equal width columns, this will do:
flex: 1
or
flex: 1 0 30%
or even:
flex: 1 0 26%;
With flex-grow: 1 defined in the flex shorthand, there's no need for flex-basis to be 33.33%.
Since flex-grow will consume free space on the line, flex-basis only needs to be large enough to enforce a wrap (should it become necessary).
In this case, with flex-basis: 26%, there's plenty of space for the margins, borders, padding, etc., but never enough space for a fourth item.
I want to make table using divs. I nested divs in this manner:
<div class='table'>
<div class='row'>
<div class='cell'>
</div>
...
...
</div>
</div>
I change width of each div and not everything changes as expected.
Changing width of table div behaves just fine.
Table width set to 70%:
Table width set to 80%:
Changing width of row div does nothing.
Row width set to 70%:
Row width set to 100%:
Changing width of cell div behaves totally unexpected.
Cell width set to 30%:
Cell width set to 20%:
Cell width set to 7%:
I tried including position: relative, didn't change anything.
Relevant css code is:
.table{
}
.heading{
display: table-row;
}
.row{
display: table-row;
}
.cell{
display: table-cell;
border: solid;
border-width: thin;
padding-left: 5px;
}
I change width of each class through Firefox's Dev tools.
Can you help me understand underlying logic?
Your table class needs css of:
display:table;
Additional Info:
Table Width: Changing the table width will make the entire table whatever size you specify, unless the content within is larger than what you've set it to. Cells will auto resize to fit the width.
Row Width: Does nothing. You aren't supposed to set a width on rows because they always take up 100% of the table width.
Cell Width: These need to always add up to 100% to work predictably. For example, if you have four cells per row, then you can set them to 25% width. Setting them all to 15% width doesn't make sense because 15*4=60... which leaves 40% unaccounted for.
You can, however, set a SINGLE cell's width to 15%, and then don't set any width for the remaining cells. At that point, the one you've set will always be 15%, and the rest will just take up the remaining space. Like this: http://jsfiddle.net/4g2Lavmy/4/
Add the class name "cell" to all the div's which are inside the div.table and use CSS like this:
div.cell{width:30%;}
I have a simple structure of:
<div></div><span></span><span></span>
but I want to force them all on one line! at the moment, they appear:
<div />
<span /><span />
unfortunately, I HAVE to have the first element as a div; the div is acting as a bar from a bar chart (so rounded corners, width = jquery stuff, no content and block colour inside), the next span is the value the bar represents and the last span is what the value is associated to.
so I want
[____________] 25% ObjectA
[________________________] 50% ObjectB
[______] 12.5% ObjectC
[______] 12.5% ObjectD
and not
[____________]
25% ObjectA
[________________________]
50% ObjectB
[______]
12.5% ObjectC
[______]
12.5% ObjectD
Put the CSS property display: inline-block on the div to make it act like an inline element instead of taking up the whole line.
Edit:
#Mr_Green's suggestion to use the after pseudo-element to clear each line is absolutely necessary to prevent a broken layout.
The suggestion of Dylan will work but sometimes if one of the div's width is very less then the next div will come inline with this div element. see this fiddle. So, my suggestion is to use :after pseudo element which will be display: block. This pseudo element will be for the last span in every bar section.
div {
/* width and height are just for example */
width: 100px;
height: 50px;
background-color: red;
display: inline-block;
}
div+span+span:after { /* last span element's pseudo element */
content:"";
display: block;
}
Working Fiddle
Since <div> elements default to display: block, which takes up all available width, you'll need to set it to display: inline-block. You'll also need to break the lines manually with a <br>, or do something fancy on the last <span> to make it fill the rest of the available space.
Alternatively, wrap each row in another block-level element (such as another <div>) to create new rows.
At your span add the CSS property:
white-space: nowrap;