flex-layout
flex-layout copied to clipboard
rfc: new layout system
Angular Layout Condensed
Introduction
In its original form, Angular Flex Layout was a series of twenty or so directives. Each directive was meant to correspond to a unique type of style framework (e.g. the Flex directive works to make applying flex
CSS styles easier). The selectors for each directive were extended to include responsive breakpoints to easily add and remove stylings based on the current active media query of the page. This gave developers an incredible tool in designing responsive webpages.
However, this approach led to a lot of bloat, as the overhead in shipping twenty-plus Angular directives, and the core utilities to power them, took its toll. Not only that, but it became harder and harder to write directives that would create conflicting styles. Finally, the performance hit of multiple directives instantiated on a single element was also non-trivial, despite the addition of a style caching mechanism.
Therefore, a new approach was developed, favoring a single, unified directive and centralized media processing service. This allows us to completely decouple the style generation utilities from the media responsive engine, while simultaneously allowing developers to seamlessly extend both.
A New Syntax
Previously, the way to describe a template in Angular Flex Layout was as follows:
<div fxLayout.xs="column" fxLayout.gt-xs="row" fxLayoutGap="10px" fxLayoutGap.md="25px">
<div fxFlex>Part 1</div>
<div fxFlex>Part 2</div>
<div fxFlex>Part 3</div>
</div>
Straight away, you can see there's now a lot of clutter. The intention of the stylings are lost under the weight of the breakpoints. Ordering doesn't matter, and it's easy to create conflicts or to lose sight of certain values.
The new syntax in Angular Layout Condensed (for the same template) is as follows:
<div ngl gap="10px">
<bp name="xs" layout="column">
<bp name="gt-xs" layout="row">
<bp name="md" gap="25px">
<div ngl flex>Part 1</div>
<div ngl flex>Part 2</div>
<div ngl flex>Part 3</div>
</div
Here, the ngl
(Angular Layout) directive is the unified directive that is responsible for registering values to the centralized media processing service. The bp
directives are responsible for simply acting as wrappers for capturing the values for those specific breakpoints, for consumption by the host directive.
The benefits of the new approach make the overall template simpler and easier to reason about. Determining expectations vs reality is also much more straightforward.
Finally, the ultimate benefit of the new approach: a 70% size reduction compared to the previous version, coming out to ~25KB minified, with room for improvement.
Other details are omitted from this design, like the ease of extending the interface to provide new breakpoints and style generation providers. Needless to say, that experience is also greatly improved.
Ref: #1141, #1130, #1161, #1035, #501
Is there any estimated release date for this ?
Is there any estimated release date for this ?
I don't believe so.
I love the 70% bundle size reduction! I'm curious how much of that is JS vs CSS?
Would this be valid?
<bp name="gt-xs" layout="row" gap="25px">
Or do you need to do this?
<bp name="gt-xs" layout="row">
<bp name="gt-xs" gap="25px">
- What about
fxLayoutAlign
? - What about
fxFlex="33%"
and the other variations? - How does CSS Grid play into this?
- Would the library have an API that doesn't map directly to Grid/Flexbox and be able to determine when it was best to use Grid vs Flexbox?
@Splaktar <bp name="gt-xs" layout="row" gap="25px">
is totally valid, and is the intention of the design (consolidating by breakpoint).
- (1 and 2) What's special about
fxLayoutAlign
andfxFlex="33%"
? They should translate toalign
andflex
respectively. (fxFlexAlign
translates toflex-align
, but this is not dogmatic) - CSS Grid is the exact same interface (e.g. alignColumns, gridGap, etc)
- No but no reason that can't be a follow-up feature
Thank you for the quick response! I'm just starting to dig into the full README.md
Does this implementation reduce the amount of layout thrashing compared to what the existing implementation does?
The performance issues with the use of inline styles in the existing implementation is discussed here: https://github.com/angular/flex-layout/issues/1299
@fxck Please consider moving your comment to the discussion thread, since your comment has no bearing on this PR.
@samal-rasmussen Last I remember, this does not incorporate a class-based approach for a few reasons. 1) was to semi-maintain parity with the existing toolset, which prioritizes style CSS rank vs performance, and 2) there are certain features that simply can't be handled with a class-based approach. This does not mean we won't add that functionality later, or in the current version of the library; it's distinct from this proposal, which is more about how to structure the directives themselves in the markup.
@CaerusKaru are there any plans for an automatic upgrade using ng update
or similar? The feature set seems largely the same and like this could be supported.
Also is there a link to the discussion thread? I could find anything here.
@epelc I would love to have some ng update
functionality, and if we ever invested in this actively, that would definitely be a fast follow to release (again, if it were up to me). Feel free to add discussion directly to this PR. It would be too tedious to go back and forth on certain points between here and a tracking issue.
@Splaktar
<bp name="gt-xs" layout="row" gap="25px">
is totally valid, and is the intention of the design (consolidating by breakpoint).
- (1 and 2) What's special about
fxLayoutAlign
andfxFlex="33%"
? They should translate toalign
andflex
respectively. (fxFlexAlign
translates toflex-align
, but this is not dogmatic)- CSS Grid is the exact same interface (e.g. alignColumns, gridGap, etc)
- No but no reason that can't be a follow-up feature
One thing is special about the align
attribute, it is really badly rendered in vscode, see: https://github.com/Microsoft/vscode/issues/66723