flex-layout: flex-layout is not applying the inline styles on host elements

flex-layout is not applying the inline styles on host elements where the host elements are getting their flex-layout attributes via @HostBinding

    @Component({
        selector: 'column-node',  //flex-layout not working on host elements
        host: { '[@visibility]': 'visibility' },
        template: `<ng-content></ng-content>`,
    })    
    
    export class LayoutColumnNodeComponent {
        @HostBinding('attr.fxLayout') fxlayout = 'column';
    }

fxLayout attribute is added in DOM <column-node fxLayout="column"> but flex-layout inline styles are not being applied.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 8
  • Comments: 30 (12 by maintainers)

Most upvoted comments

This will cause a huge amount of redundant markup in my html files. For every node I will have to code inline all the flex properties rather than setting them once in the reusable component.

my html file will be very busy with all this repeated flex attributes on each selector. Seems I should be able to set this once in the column-node.component.ts

<column-node fxLayout="row" fxLayoutAlign="space-between center" fxFlex.xs="10" fxFlex.sm="25" fxFlex.md="50" fxFlex.lg="100"> 
   ...COLUMN NODE CONTENT...
</column-node>

//could be many nodes cluttering up the file, making it difficult to scan.

<column-node></column-node> would be much cleaner and all the flex attributes set in the column-node.component.ts

`

@mcwebdev - until the Angular Compiler is fixed to address this issue, a reasonable work around is this:

    @Component({
        selector: 'column-node', 
        host: { '[@visibility]': 'visibility' },
        template: `
           <div [fxLayout]="layoutDir">
              <ng-content></ng-content>
            </div>
        `,
    })        
    export class LayoutColumnNodeComponent {
        layoutDir = 'column';
    }

This approach uses an inner wrapper <div> as a host for the flex-layout directives.

Related to https://github.com/angular/angular/issues/11716 Related to https://github.com/angular/angular/issues/14114

@ThomasBurleson There is already at least one directive in flex-layout (I think fxFlex?) which reaches “up” to its parent to apply CSS styles in certain cases. What about another use of that same notion? There could be a directive which can be used on a top-level element within the component, which reaches upward to configure flex properties on the component element itself.

This could be considered hackish… but has the merit that it could be implemented now, rather than after core Angular signs a high quality solution for the host directive issue.

We have two issues discussed here:

The Host-Directive issue may be fixed… but not in the near-term future. A reasonable interim workaround is the manual use of CSS class for the host-element.

We will reopen this issue to continue exploring other options.

@mattiLeBlanc - No. This is a bug with Angular itself. If your component wants to to have a vertical flow, then simply wrap your component html within a wrapper:

<div fxLayout="column">
   .... your original template content... 
</div>

My expectation is that <test-app fxLayout="column" fxLayoutAlign="start start"></test-app> get the flex styling applied, I may dynamically add children in later. My issue is that host selectors don’t generate any kind of inline flex css. Looking at the inspector in chrome. element.style is empty, however it should not be given the flex properties fxLayout="column" fxLayoutAlign="start start" bound to <test-app>.

element.style should reflect

 {
    box-sizing: border-box;
    max-height: 100%;
    display: flex;
    flex-direction: row;
    -webkit-box-orient: horizontal;
    -webkit-box-direction: normal;
    justify-content: space-between;
    align-items: center;
    align-content: center;
    -webkit-box-align: center;
}```

@gogakoreli - that is twisted and creative. LOL. @CaerusKaru - perhaps we should discuss possibilities (and risks) of @kylecordes suggestions above.

My compiler is warning me against using host properties, I have another workaround:

import { Component, OnInit, HostBinding } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Component({
  selector: 'app-landingpage',
  templateUrl: './landingpage.component.html',
  styleUrls: ['./landingpage.component.css'],
})
export class LandingpageComponent implements OnInit {
@HostBinding('attr.style') style;

  constructor(private sanitizer: DomSanitizer) {
    this.style = sanitizer.bypassSecurityTrustStyle('flex: 1 1 100%;')
   }
}

Now the landing page is properly expanded

screen shot 2017-07-27 at 00 26 47

Is there any update in this issue?