I have a flexbox container and several items within. Its flex-wrap property is set to wrap.
Width of the items dynamically increases (via animation property) and at a given point some of them are moved to a new line. I'd like to prevent this behavior, reserving for the items as much space as they will occupy at the end.
I see two ways to achieve this. The first is setting initial margins and decrease them as the items width increases. The second is placing the items in wrappers with fixed width equal to their maximal width.
Is there a better way based on some flexbox properties? I can't apply min-width to the items as it breaks their layout.
I have a CSS grid with a scrollable element placed in one of the grid's areas.
What'd I'd like is for the item to shrink if the content is too small to fit the area. I did this by setting align-self to start.
This works great, until the content grows. The element resizes past the end of the grid area it's assigned to.
How can I use align-start but still cap the height to the height of the grid area? I would have expected this to be the default behavior.
One solution is to have the element stretch but then have a child element inside it that contains the actual content. The parent would have overflow: auto and the child would simply grow until it's too large for the container. Unfortunately, this kills the box-shadow.
I could put the box-shadow on the outer element in this case, but then it'll be too large when the content is small.
Any ideas what I can do here? I considered using some Javascript shinnanigans but I'm not even sure how I'd grab the height of the grid area from JS.
JSFiddle: https://jsfiddle.net/1kLenm5a/2/
Apparently max-height: 100% works. I could have sworn I tried that but I was messing with so many other settings at the same time I must have missed it.
Thanks.
It's my understanding that flexbox containers and their child items flex fully along only one axis, depending on the value of the flex-direction property, row or column. With a "row" container, you can stretch and shrink the width of the container and the individual boxes it contains, but the content in those boxes does not grow or shrink to match. On the other hand, resizing a window vertically does cause content to resize accordingly. (I think the situation is vice versa with "column" containers, though I haven't tried them alone.)
So my questions:
Do I have that right? I've read through many nice blog posts on flexboxes, but none covered this characteristic explicitly as a main 'feature.'
Is there a flexbox-only workaround, some arrangement of rows-inside-columns or the other way around, maybe with specific properties set special ways?
I tried putting a columnar container inside a flexbox belonging to a row container, and then putting text into that, but I saw no change in resizing behavior--the text still resizes only when the window/viewbox is resized vertically, not horizontally. See this codepen.
(About the example: first, I apologize for extraneous properties or properties set to random-ish values, but I was trying anything and everything. I tried to pare them back without messing up the demo but I'm sure there's much to improve. The svg logo on the left is just in a top-level flexbox in the main container for that row--it behaves as expected, shrinking/growing only with vertical window resizes. I put a hidden logo in a third box on the right so with equal-width boxes on either side, the text between them comes out centered in the viewbox, if you don't use shrink too much side to side. Maybe there's a less kludgy way with flexbox to a row with centered text and a logo on the left.)
It is wildly highlighted that Flexbox is for 1-D and Grid for 2-D but I have not found a clear explanation why Grid could not be used for 1-D and replace Flexbox. The closest I came to is
But you could also argue that purely 1D layout like this is more
powerful in Flexbox, because Flexbox allows us to move those elements
around easier (e.g. move them all to one side or another, change their
order, space them out evenly, etc).
I use Grid and Flexbox for basic layout: a general placement of the boxes on the page and some dynamic ones, usually stacked. The esthetical ones (toasters, modals, ...) are managed through a framework. I have not yet found a case where Grid could not replace Flexbox out of the box (that is without advanced CSS gymnastics or a lot of code).
To take the example of the quote above, all the "moves" mentioned are directly available in Grid, usually with the same semantics as in Flexbox.
What are the fundamental areas covered by Flexbox which are difficult or impossible to manage with Grid?
EDIT: the browser support is not important (I only use evergreen browsers and can switch if needed)
Advantage Flexbox
Here are 13 areas where flexbox comes out ahead of Grid (Level 1):
Centering wrapped items. Imagine five elements. Only four per row. The fifth one wraps. In a flex container, that fifth one can be easily aligned across the entire row with justify-content. Try centering this fifth item in a grid container. Not a simple matter.
Aligning grid items across the entire row/column (like flex items can)
How to center elements on the last row in CSS Grid?
How to offset a grid item, also shifting its siblings?
Can I have a varying number of columns per row in a CSS grid?
Wrapping. Flex items of variable lengths have no problem wrapping. Try getting grid items of variable lengths to wrap. Not possible.
How to get grid items of different lengths to wrap?
Can grid items wrap?
Auto margins. Flex items can be placed, packed and spaced away throughout their container with auto margins. Grid items, however, are confined to their tracks, greatly diminishing the utility of auto margins.
Can auto margins work in CSS Grid like they do in Flexbox?
Min, Max, Default – all in one. Setting the min-width, max-width and default width of a flex item is easy. How can all three lengths be set on a grid column or row? They can't.
Setting the minimum, maximum and default length of a grid column / row
Set minimum and maximum widths to grid column using percentages (related, but not exactly the same problem)
Sticky footer / header. It's just so much simpler and easier to pin a footer or header with flexbox.
How can I have a sticky footer with my CSS Grid layout?
Consuming remaining space. A flex item can consume remaining space with flex-grow. Grid items have no such function.
Aligning grid items across the entire row/column (like flex items can)
Make grid item use remaining space like flex item with flex-grow: 1
How to make the items in the last row consume remaining space in CSS Grid?
How to make CSS Grid last row to take up remaining space
Hiding a left column in CSS Grid
How to get the effect of grid layout's grid-template-columns with a variable number of columns?
CSS fr / fractional units minimum too large
Shrinking. Flex has flex-shrink. Grid has... nothing.
Shrink grid items just like flex items in css
Limiting the column count in a dynamic layout. With flexbox, creating a wrapping two-column grid that remains fixed at two-columns across screen sizes is no problem. In Grid, despite having all these great functions, such repeat(), auto-fill and minmax(), it can't be done.
Make CSS Grid auto-fill only 2 columns
CSS grid - maximum number of columns without media queries
Creating space between first and last items. In a grid container with a variable number of columns, it's not easy to add an empty first and last column. Margins, padding, columns and pseudo elements each have their limitations. It's simple and easy with flexbox.
Add space before and after first and last grid items
An important benefit of the inline-level container is lost in some cases. If you have a Grid layout with a dynamic number of columns – meaning you cannot set the number of columns or a width for the container – then display: inline-grid doesn't work. All items stack in a single column. This is because the default setting on grid-auto-columns is one column. In at least some cases, flexbox fixes the problem.
How to make a grid container shrink to fit the content?
Getting columns with author-defined grid areas to wrap without media queries. Let's say you have a two-column grid containing grid areas that have set locations, and want the grid to automatically transition to a single column (with the second column wrapping below the first) on smaller screens. With grid, you would need a media query. The auto-fill and auto-fit functions will not work because the locations of grid areas have been specified. If you want to avoid a media query, flexbox's flex-wrap function may be useful.
Two-Column grid should wrap into One-Column grid
There is no column-reverse function in CSS Grid. Getting items to populate a container starting from the bottom isn't possible with a single rule applied to the grid container. With flexbox, however, the task is simple with flex-direction: column-reverse.
Filling cells starting from the bottom in CSS Grid
https://stackoverflow.com/q/67620185/3597276
The resize property on a grid item has no effect on the track. Unless a column or row track is set to auto (content-based sizing), resizing a grid item will overflow the track. Since flexbox doesn't have column and row tracks, it may be a useful alternative.
Resize property on grid items results in overlap of other grid items
Flexbox and CSS grid are two different features and I don't agree about saying that one can replace another or that CSS grid is a superset of flexbox.
You said:
I have not found a clear explanation why Grid could not be used for 1-D and replace Flexbox.
Here is a basic flexbox example that involve wrapping that you cannot achieve (or probably difficult to achieve) using CSS grid. Reduce the window size and see how the elements will behave.
.box {
display: flex;
flex-wrap: wrap;
}
.box>span {
border: 1px solid;
padding: 10px;
flex-grow: 1;
}
<div class="box">
<span>some text very long here some text very long here </span>
<span>text here</span>
<span>A</span>
<span>B</span>
</div>
This is a 1-D layout where each line may have elements resized differently depending on the free space without being inside a 2-D grid. It will be difficult to achieve the same output using CSS-grid.
Basically flexbox is more suited when it comes to multiline/multirow content following one direction whereas CSS grid is more about a Grid with row and columns. Of course, when it comes to only one line a 2D grid can be considerd as 1D thus flexbox and CSS grid may achieve the same thing.
It's like comparing a table with only one tr and multiple td with a set of inline-block element inside one line BUT when it comes to wrapping and multiple tr it's clear that table and inline-block are different.
Worth to note that you can achieve what you want using any techniques in general. In the past, Flexbox wasn't there and developers were able to build layout using float (Boostrap is the best example). Then flexbox come with more powerful features to make things easier. Same thing for CSS grid and for future features.
Here is an example : https://drafts.csswg.org/css-align-3/
This Draft is talking about a future enhancement of alignment where we can consider jutify-content, align-items, etc without even using flexbox or CSS grid but directly on block elements.
If implemented, will this make Flexbox and CSS Grid useless? I don't think so.
I should probably point out that CSS Grid is MUCH newer than CSS Flexbox and therefore may actually be intended as a replacement to some extent. Much like Flexbox replaced the typical use case for float (not the intended use).
I'm going to preface this by saying, I rarely NEED the complexities/capabilities of Grid so I still use Flexbox for most things.
However, in my experience, the flex-wrap capabilities, especially with variable screen sizes, is one place that I feel Grid isn't a great replacement.
As a reminder: Flexbox vs Grid IS NOT an all-or-nothing question. You can, and sometimes should, use grids inside flexboxes or even add tables to grids or floats to tables. The driving factor should be to use the right tool for the job NOT to simply discard everything else in favor of the newest option.
Is it possible to put a whole 960 grid inside a div on the page?
I need to make a page wider than 960px, so I thought I might have the sidebars laid out outside the 960 grid, and have the 960 grid control the middle column.
Yes, you just need to assign the parent div as the container_12.
Then you can use the child elements the grid_# that works for you.
But it would be better if you updated the 960.css with the new resolution values. I.E. 1024.css