Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Smarter grid directive for layouts with fixed number of columns (or rows) to achieve cleaner css #1198

Open
@simeyla

Description

@simeyla

Feature Request

What is the desired behavior?

A better way to specify a grid layout with a fixed number of rows or columns - and taking advantage of this value to intelligently only add margin where needed - with no negative values.

For example it could look something like this:

<div fxLayout="row wrap" fxLayoutGap="1em" fxCols="3">
   <div>A1</div>
   <div>A2</div>
   <div>A3</div>
   <div>B1</div>
   <div>B2</div>
   <div>B3</div>
</div>

Given that we know we have 3 columns - when adding margin we can intelligently do this:

  <!-- split elements into groups of 3 -->

  <!-- row 1: add margin on left except for first item -->
  <div style="margin: 0 0 0 0">A1</div>  
  <div style="margin: 0 0 0 1em">A2</div>
  <div style="margin: 0 0 0 1em">A3</div>

  <!-- row 2: add margin on left except for first item, and add margin on top for all items -->
  <div style="margin: 1em 0 0 0">B1</div>
  <div style="margin: 1em 0 0 1em">B2</div>
  <div style="margin: 1em 0 0 1em">B3</div>

This is similar to the fxLayoutGutter directive feature request but specifically for row / column grid layouts where a fixed number of columns or rows is required.

A few points:

  • You would only be allowed to specify one of fxCols or fxRows
  • CSS grid may be mature enough for many people's use cases.
  • It may need to be the user's responsibility to ensure that the flex items fit the width or height and didn't wrap (which would completely break the layout). Another possibility would be to insert a spacer to force a newline but that may be too complicated.
  • Per the previous point it might be possible to add a calculated percentage based on number of columns eg. style.flex="0 1 33%"
  • Only applicable for items of the same size, which is most of the times I've ever needed a grid.
  • Wouldn't conflict with other similar existing directives - although there may be confusion as to valid combinations

What is the use-case or motivation for the desired behavior?

Existing directives such as fxLayoutGap="1em grid" create fragile css where usage of negative margins and padding is applied. Child components extend beyond the bounds of their parents and when child items are components the grid layout padding conflicts with existing @HostBinding padding from the component itself. This means you have to add another div to wrap the component.

Sample code

This is very non-production code I wrote a while ago to test the concept - based upon flexLayoutGap.

Only including the triggerUpdate function - this is for a mythical fxColumns directive. Please escuse the hardcoded dimensions.

    private triggerUpdate() {
        
        const items = this.childrenNodes
                      .filter(el => el.nodeType === 1);

        items.forEach((ele, ix) => {

            // this layout is for columns
            const isFirstRow = ix < this.fxColumns;   
            const isFirstCol = ix % this.fxColumns == 0;

            if (this.fxColumns == 1)
            {
                // special case for a one column layout
                const margin = (isFirstRow ? '0' : '1em 0 0 0');
                this.renderer.setStyle(ele, 'margin', margin);
            }
            else 
            {
                // add left margin - except for first column
                // add top margin - except for first row
                const margin = (isFirstRow ? '0' : '1.5em') + ' 0 0 ' + (isFirstCol ? '0' : '1.5em');
                this.renderer.setStyle(ele, 'margin', margin);
            }
        });

Is there anything else we should know?

Metadata

Metadata

Assignees

No one assigned

    Labels

    P5Low-priority issue that needs considerationdiscussionFurther discussion with the team is needed before proceedingfeature

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions