Making features generic in CSS
Rachel Andrew ·
CSS has two new positional alignment keywords as part of CSS Box Alignment Level 3: flow-start and flow-end. These are defined as aliases for the existing flex-start and flex-end keywords. Therefore, in a supporting browser, the following two lines should align flex items to the end of the flex container (the right assuming you are ... Making features generic in CSS
CSS has two new positional alignment keywords as part of CSS Box Alignment Level 3 : flow-start and flow-end . These are defined as aliases for the existing flex-start and flex-end keywords. Therefore, in a supporting browser, the following two lines should align flex items to the end of the flex container (the right assuming you are working in English).
.box { display: flex; justify-content: flex-end; } .box { display: flex; justify-content: flow-end; } You can read the discussion that led to this change in the issue on Github , including the IRC transcript of the meeting where the resolution was made. Making this change means these keywords can also be used in grid lanes (masonry) layout.
This is not the first time the CSS Working Group has taken a property or value name that was tied to a particular layout method and generalised it. The gap properties for grid and flexbox started life as grid-gap properties. Use grid-gap rather than gap in your code, and you will still get a gap between grid tracks. If developers have started to use the property or value by the change is made, it will live forever as an alias, to prevent us from breaking the web .
You might wonder why these properties and values were designed to be specific to one layout method. Perhaps the Working Group could have foreseen that there might be new layout methods requiring the same type of flow end as flexbox, or gaps as in grid—we do have a list of things we’re intending to fix once time travel is invented . However, it’s sometimes useful to scope things down to one layout method, and it’s not always easy to see into the future to decide which things that applies to.
I’ve just returned from W3C TPAC in Dublin and two days of CSS Working Group meetings where a couple of things in this category were discussed.
The CSS reading-flow property controls the order that items in grid, flex, and block layouts are exposed in terms of focus order. It lets you manage the issue where a grid layout can move items around so they are tabbed to in an unintuitive way. The new grid lanes layout mode can create this kind of disconnect and, as the final layout is not controlled by the web developer, without reading-flow support there’s no way to control that experience. We have already resolved to add support, at the meeting at TPAC we needed to resolve on the names of the grid lanes properties . The final resolution was to use grid-lanes-flow and grid-lanes-track , specific values for grid lanes.
Why do we have specific values for the reading-flow property for each type of layout? Partly this is because the layout methods have different needs, only grid layout has both columns and rows, for example. Having common values would mean that in some layout methods only some of the values would do anything, which is confusing. In addition, because the reading-flow property messes with focus order, we wanted to make sure that when people used it, they were very carefully doing so, with consideration of the specific thing they were trying to achieve. I don’t expect most grid layouts to need this property, as the source order is very likely to be the best focus order. By adding the friction of needing to use the right values for the layout, we prevent a global switching on of a ‘visual’ flow.
There has been a long discussion about implementing masonry in CSS, with different proposals from the Webkit and Chrome teams. A key decision that had to be made was whether masonry was to be part of CSS Grid Layout, or its own value of display . I’ve held the view, even before I was part of the Chrome team, that it should be a separate thing. The main reason for this is detailed in this blog post on developer.chrome.com . Masonry is a very specific type of layout, and by including it in grid, we have to allow lot of complex grid things to also work in masonry. This includes things that already exist, and also anything we add to grid in the future. Similar to the values of reading-flow , sometimes things are just different enough that it’s best to keep them separate so that they aren’t confusing.
Two years on from that blog post, and masonry in CSS is now called grid lanes. It is a separate value of display, however it also reuses grid properties and the specification details that “All CSS properties work the same as in a regular grid container unless otherwise specified by this specification.” We got the separate value for display , but haven’t made the layout method truly separate. In particular the reusing of the grid-template-columns and grid-template-rows properties mean that we bring along all of the complexity of those definitions to grid lanes, including the subgrid value.
Back to the discussion at the CSS Working Group, which was about subgrid in grid lanes. Supporting this value creates a lot of complexity, not least because there are multiple possibilities. You might have a regular grid layout with a grid-lanes subgrid, or a grid lanes layout with a regular grid subgrid, or subgrids that matched their parent. The conversation in Issue 14380 is converging on a possible solution of only allowing subgrids of the same type (grid lanes or regular grid) as their parent, but we don’t know if there are compelling use cases that would provide a reason to add the additional complexity. If you have such use cases, or other thoughts on the matter, we weren’t able to come to a resolution during the meeting. Please post them to the issue.
There is a final reason why sometimes having a completely separate property or value is useful, and that’s when it comes to testing support for the feature. A separate property name or property value combination can easily be tested for with @supports , which takes a property and value pair and tests if it can be parsed. This means that you could test specifically for support of reading-flow: grid-lanes-track , which will currently fail in Chrome where reading-flow: grid-columns will pass. We ran into this problem with the gap property because there was no way to test for support of gap:10px in flexbox, the property and value would successfully parse because it was already supported for grid. The named-feature() addition , is designed to help with this, but requires up front identification and the adding of a name when these scenarios appear.
This turned into a longer post than I had anticipated, but perhaps it gives a bit of insight into why we seem to bikeshed features endlessly. It hopefully also shows why real use cases are important. With any feature development, the more you understand how a feature might be used, the better you can design it. This is true for the web platform as it is for any other product. If you see something being discussed, and wonder if it might work for some other use case you have, let us know.