flex-layout icon indicating copy to clipboard operation
flex-layout copied to clipboard

rfc: new layout system

Open CaerusKaru opened this issue 5 years ago • 11 comments

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.

CaerusKaru avatar Feb 02 '20 09:02 CaerusKaru

Ref: #1141, #1130, #1161, #1035, #501

CaerusKaru avatar Feb 10 '20 05:02 CaerusKaru

Is there any estimated release date for this ?

erkanmaras avatar Apr 10 '20 17:04 erkanmaras

Is there any estimated release date for this ?

I don't believe so.

Splaktar avatar May 26 '20 23:05 Splaktar

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">
  1. What about fxLayoutAlign?
  2. What about fxFlex="33%" and the other variations?
  3. How does CSS Grid play into this?
  4. 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 avatar May 26 '20 23:05 Splaktar

@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 and fxFlex="33%"? They should translate to align and flex respectively. (fxFlexAlign translates to flex-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

CaerusKaru avatar May 26 '20 23:05 CaerusKaru

Thank you for the quick response! I'm just starting to dig into the full README.md

Splaktar avatar May 27 '20 00:05 Splaktar

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

samal-rasmussen avatar Jun 10 '21 12:06 samal-rasmussen

@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 avatar Jun 10 '21 18:06 CaerusKaru

@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 avatar Jul 23 '21 18:07 epelc

@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.

CaerusKaru avatar Aug 03 '21 03:08 CaerusKaru

@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 and fxFlex="33%"? They should translate to align and flex respectively. (fxFlexAlign translates to flex-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

ckorherr avatar Aug 29 '21 13:08 ckorherr