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.
Added two attributes to the <test-app> selector.
`@HostBinding('attr.fxLayout') fxlayout = 'column';
@HostBinding('attr.fxLayoutAlign') alignment = 'start start'; `

K. While this was not an intended usage, it does present some odd ideas.
With your hostBindings, your are hoping to set this equivalent?
<test-app fxLayout="column" fxLayoutAlign="start start"></test-app>
but you have only one child within test-app. So what do you expect to happen ?
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
json
{
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;
}

I am not certain HostBinding(s) will actually create a compiled, active directive. Most likely it considers the attr.fxLayout to be a static attribute (which is NOT compiled).
This is a known bug/feature request on Angular core.
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
html
<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
`
This feature is under consideration by angular core team https://github.com/angular/angular/issues/11716
@ThomasBurleson the original issue was https://github.com/angular/angular/issues/14114 which is the same that issue here.
@ghoullier - Thank you for the clarification.
Definitely seems to be a Angular issue: Refs https://github.com/angular/angular/issues/11716
Is there any update in this issue?
@Twois - this issue is not a flex-layout issue, but rather an Angular compiler issue.
@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
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

@javahaxxor - Your solution simply sets a single raw style... and can be problematic since it does not use the flex-layout API directives (which intelligently sets multiple flexbox css styles properties and values).
I understood that it sets raw style, but seeing my immediate problem go away I didn't think about the other stuff, thanks for pointing it out.
@ThomasBurleson
Is it possible to add some kind of marker (^) in front the fxLayout to tell Angular that it needs to $compile this attribute/directive?
It already recognises bindings with [], so it would be nice if you can activate the $compile only when required?
@Component( {
selector: 'auth',
host: {
'^fxLayout': 'column',
},
template: `
@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>
@ThomasBurleson Did angular fix this bug, and that's why this issue is now closed?
@ThomasBurleson i installed flexlayout modules, but its not working in my project can you help what i have to do,

Not generating inline style for flexlayout="column"
@dhanarajp
you need to follow the API...https://github.com/angular/flex-layout/wiki/API-Documentation
fxFlex
fxLayout
fxLayoutAlign etc
@ThomasBurleson Question (I hope not a silly one), is it possible that 2.0.0-beta.10 is automagically adding style="flex-direction: row; box-sizing: border-box; display: flex;" to the app-root element? I have no reference anywhere for adding this CSS, however it is added. I can't find anything in the docos about this either.
UPDATE
By adding fxFlex to the router-outlet, it added the inline style to my app-root. Is that expected behaviour?
Even if I wrap app.component.html in a <DIV> and add fxFlex to it, it will add the flex-direction: row.
<div fxLayout="column" fxFlex>
<pro-header *ngIf="!headless"></pro-header>
<router-outlet></router-outlet>
<pro-footer *ngIf="!headless"></pro-footer>
</div>

Very interesting :)
I am trying to stretch the router-outlet to get a sticky footer at the bottom.
I realise I shouldn't do it on the router-outlet since the real body of the component loaded is appended under the router-outlet. But I found the behaviour interesting.
However, its very hard to stretch the component between the header and footer, since I can't use @HostBindings and wrapping my component template in
<div fxLayout="column">
.... your original template content...
</div>
is also not going to stretch the component DOM element. The only way I can do it now is manually assigning a class via @HostBindings to apply the fxFlex behaviour. There must be another way?
I have the same problem.
I'm using resolveComponentFactory to create my component dynamic that is a child of parent and have fxFlexdirective. The problem is that the fxFlex not apply the correcdt width to my host component.
I have attached the result of my page.
I have this main component html
<div fxLayout="row" fxLayoutWrap fxLayoutAlign="start start">
<template #widgetContainer></template>
</div>
And in the js I fire the createComponent for its children.
This is the content of children HTML:
<div [fxFlex]="this.widget.options.columns">
<mat-card>
<mat-card-title>{{this.widget.options.title}}</mat-card-title>
<mat-card-content>
Grid {{this.widget.options.columns}}
</mat-card-content>
</mat-card>
</div>
And JS:
@Component({
selector: 'grid',
templateUrl: './grid.component.html'
})
export class GridComponent implements OnInit {
public widget: WidgetService;
public constructor(
public viewContainerRef: ViewContainerRef
) {
this.widget = new WidgetService({
title: "Tabella " + this.getIntNum(),
originalX: 1,
originalY: 1,
x: 1,
y: 1,
base_columns: 50,
base_rows: 2,
columns: this.getIntNum() % 2 == 0 ? 50 : 25,
rows: 2,
type: "grid",
resizable: true
});
}
private getIntNum() {
let n = Math.floor(+(Math.random()*100));
return n;
}
public ngOnInit(): void {
}
}
Page result

As you can see the card item not fit the correctly width of my container (container is a full browser page)
@ThomasBurleson
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.
@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.
Workaround will be to do it by hand, like this.
This is example for fxFlex, I dont want to always write fxFlex on div and use it as spacer, instead I created component and applied fxFlex to the component itself from inside.
This is handy because fxFlex automatically applies styles to the parent container also and there is no other way to do it.
export class SpacerComponent implements OnInit {
flexDirective: any;
constructor(
monitor: MediaMonitor,
elRef: ElementRef,
@Optional() @SkipSelf() protected _container: LayoutDirective,
@Optional() @SkipSelf() protected _wrapContainer: LayoutWrapDirective,
renderer: Renderer2,
) {
this.flexDirective = new FlexDirective(monitor, elRef, renderer, _container, _wrapContainer);
this.flexDirective.flex = '1 1 auto';
}
ngOnInit() {
this.flexDirective.ngOnInit();
}
}
@gogakoreli - that is twisted and creative. LOL.
@CaerusKaru - perhaps we should discuss possibilities (and risks) of @kylecordes suggestions above.
This has been delayed until post-ivy implementation in Angular core.
As an update to this issue, as alluded to by @mhevery in angular/angular#11716, this feature will not be implemented in Core.
The alternative that is being considered is here: https://github.com/angular/angular/issues/8785. Please follow that issue for future updates. I'm closing this issue and locking the conversation since it's very much not a Flex Layout issue.
Most helpful comment
@mcwebdev - until the Angular Compiler is fixed to address this issue, a reasonable work around is this:
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