Force flex element not to grow in cross-axis direction
You were almost there with width
. What you need to do is set width
and min-width
(demo):
.statusmessage {
width:0; /* Collapses .statusmessage so it doesn't affect column width */
min-width:100%; /* Expands .statusmessage to width of column */
}
The width
can be (and probably should be) set to a value other than 0
. It should just be the minimum width of the column or smaller. So use a value that works for you.
I've tested this on Chrome and Firefox and seems to work in both. Now, is it supposed to work? I'm not sure, I haven't read into the spec that much (it could be undefined). Make sure to test in all browsers you need it to work in. (And check the spec to see if this behavior is undefined/incorrect.)
Is there a cross-axis counterpart to the flex-grow property (or flex), which affects only the main-axis?
The flex-grow
(and the shorthand flex
) property always affect the main axis, has no counterpart, and sets how to distribute the free space horizontally for flex row direction and vertically for flex column direction.
In comparison, for example the justify-content
property affects the main axis, has a counterpart, the align-items
which affect the cross axis, where both sets the alignment of the flex items.
What can be confusing here though, is that based on the flow direction they affect either the flex items horizontally or vertically.
Note, the main and cross axis has nothing to do with whether the screen is wide or tall.
It has to do with the flow direction, so for a flex row direction, which is the default, the main axis is horizontal and the cross axis is vertical, and for a flex column direction, the main axis is vertical and the cross axis is horizontal.
A really good article is A Complete Guide to Flexbox, which explains this more thoroughly.
Prevent flex container overflow along cross-axis
A bit tricky to explain but here the shrink-to-fit behavior of the absolute element is controling the width of your element. From the specification we have:
Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, calculate the available width: this is found by solving for 'width' after setting 'left' (in case 1) or 'right' (in case 3) to 0.
Then the shrink-to-fit width is:
min(max(preferred minimum width, available width), preferred width)
.
The key here is the preferred minimum width which is the minimum boundry.
To better understand let's remove some properties:
#container {
animation:change 5s linear infinite alternate;
}
@keyframes change {
from {
width:300px;
}
to {
width:50px;
}
}
<div id="container" style="position: relative; height: 100px; left: 50px; border: 1px solid red">
<div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
<div style="
display:flex">
<div style="/*flex: 1 0 auto*/">Long text 1</div>
<div style="/*flex: 0 0 auto*/">Long text 2</div>
</div>
</div>
</div>
Make flex items take content width, not width of parent container
Use align-items: flex-start
on the container, or align-self: flex-start
on the flex items.
No need for display: inline-flex
.
An initial setting of a flex container is align-items: stretch
. This means that flex items will expand to cover the full length of the container along the cross axis.
The align-self
property does the same thing as align-items
, except that align-self
applies to flex items while align-items
applies to the flex container.
By default, align-self
inherits the value of align-items
.
Since your container is flex-direction: column
, the cross axis is horizontal, and align-items: stretch
is expanding the child element's width as much as it can. (The column
setting is also the reason why display: inline-flex
isn't working.)
You can override the default with align-items: flex-start
on the container (which is inherited by all flex items) or align-self: flex-start
on the item (which is confined to the single item).
Learn more about flex alignment along the cross axis here:
- How does flex-wrap work with align-self, align-items and align-content?
Learn more about flex alignment along the main axis here:
- In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
Fill the remaining height or width in a flex container
Use the flex-grow
property to make a flex item consume free space on the main axis.
This property will expand the item as much as possible, adjusting the length to dynamic environments, such as screen re-sizing or the addition / removal of other items.
A common example is flex-grow: 1
or, using the shorthand property, flex: 1
.
Hence, instead of width: 96%
on your div, use flex: 1
.
You wrote:
So at the moment, it's set to 96% which looks OK until you really squash the screen - then the right hand div gets a bit starved of the space it needs.
The squashing of the fixed-width div is related to another flex property: flex-shrink
By default, flex items are set to flex-shrink: 1
which enables them to shrink in order to prevent overflow of the container.
To disable this feature use flex-shrink: 0
.
For more details see The flex-shrink
factor section in the answer here:
- What are the differences between flex-basis and width?
Learn more about flex alignment along the main axis here:
- In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
Learn more about flex alignment along the cross axis here:
- How does flex-wrap work with align-self, align-items and align-content?
How to disable equal height columns in Flexbox?
You're encountering the flex equal height columns feature.
An initial setting of a flex container is align-items: stretch
.
This means that flex items automatically expand the full length of the cross axis of the container. In a row-direction container, the cross axis is vertical (height).
The tallest item sets the height for all siblings. As the tallest item expands, its siblings follow along. Hence, equal height for all items.
To override this default setting, add align-items: flex-start
to the flex container:
#container_add_movies {
display: flex;
align-items: flex-start;
}
#container_add_movies {
display: flex;
align-items: flex-start; /* NEW */
}
#container_add_movies #feedback {
width: 20%;
background-color: green;
display: block;
}
#container_add_movies #search {
width: 60%;
background-color: red;
}
#container_add_movies #suggestions {
width: 20%;
background-color: yellow;
}
<div id='container_add_movies'>
<div id='feedback'>Feedback</div>
<div id='search'>
Search<br>Search<br>Search<br>Search<br>Search<br> Search
<br>Search<br>Search<br>Search<br>Search<br>
</div>
<div id='suggestions'>Suggestions</div>
</div>
Related Topics
Understanding the Difference Between the Flex and Flex-Grow Properties
CSS Width and Max-Width Combined
Changing Font-Family for Placeholder
How to Exclude a Tag from CSS Class
Using Bootstrap and My Own CSS Together
Django-Bower + Foundation 5 + SASS, How to Configure
Why Is Vertical-Align:Text-Top; Not Working in CSS
Aptana Studio 3 Code Assist for SASS (.Scss) Files
Style the First <Td> Column of a Table Differently
How to Use Calc() in Tailwind CSS
Including Margin for Width and Height
CSS Is Not Working in My Angular Component
Convert Letter-Tracking Value Set in Photoshop to Equivalent Letter-Spacing in CSS
Why Does "Left: 50%, Transform: Translatex(-50%)" Horizontally Center an Element