Reputation: 2167
I am struggling with aligning items in Angular 4 w/ Angular Material using Flexbox. I want to accomplish a layout like the one shown in attachment #1 where the first card is at the top and the second card is at the bottom of the component's content. The component itself should take the rest of the space on the screen in height (device height minus toolbar height).
Attachment #2 shows what I've accomplished so far. The following HTML markup and CSS show the code behind attachment #2.
Can anyone tell me what's the correct way to do this? I don't want to mess around with fixed positions or whatever, I would like to implement a solution that is compatible with Angular Material and doesn't effect the layout of other components.
Thanks in advance!
Attachment #1:
Attachment #2:
HTML markup of HomeComponent:
<div id="home-content">
<mat-card id="title-card">
<mat-card-title>Lorem.</mat-card-title>
<mat-card-content>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Blanditiis magnam sint accusamus facere ducimus modi non voluptates consectetur exercitationem ullam.</mat-card-content>
</mat-card>
<mat-card>
<mat-card-header>
<img mat-card-avatar src="http://lorempixel.com/200/200" alt="">
<mat-card-title>Lorem, ipsum dolor.</mat-card-title>
<mat-card-subtitle>Lorem ipsum dolor sit amet consectetur adipisicing elit.</mat-card-subtitle>
</mat-card-header>
<mat-card-content>Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptate repellat animi reiciendis eius mollitia totam sint natus hic unde iusto.</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="primary">Challenge!</button>
</mat-card-actions>
</mat-card>
</div>
Corresponding CSS code:
div#home-content {
display: flex;
flex-direction: column;
height: 100%;
border: 3px solid black;
justify-content: space-between;
}
Upvotes: 0
Views: 11192
Reputation: 2167
@LGSon: thank you for your answer. I did it like you said and made the parent container a flex container too. Now it works, but I am not sure if it will affect other layouts in other components where this layouting is not needed.
For others who may have the same problem here is the CSS code that worked for me. In the screenshot #1 you can see the result with colored borders for all relevant elements. Thanks again to @LGSon for the tip:
html, body {
margin: 0;
height: 100%; // html and head must be 100% height in order to make that work
}
app-root {
height: 100%; // app-root needs to be 100% too
display: flex; // make the app-root a flex container
flex-direction: column; // flex-direction is column so that the toolbar is above the component's content
}
md-toolbar {
flex-grow: 0; // if there is more space in height than needed toolbar won't grow
}
app-root > *:nth-child(3) { // the third child of app-root contains the component's content. The first child is the toolbar, the second one is the empty router-outlet element. Perhaps this is different in your HTML structure.
border: 3px solid black;;
flex-grow: 1;
display: flex; // is also a flex container with just one item which is div#home-content
}
div#home-content {
align-self: stretch; // use the whole space available in height
border: 3px solid greenyellow;
display: flex; // is a flex-container too so that the cards can be aligned accordingly
flex-direction: column;
justify-content: space-between; // space-between is responsible for the first card to be at the top and the second card to be at the bottom
}
Screenshot #1:
Upvotes: 0
Reputation: 87191
When using percent for height
, also each parent, all the way to the html/body
, need one too.
One option is to use viewport units, so change from height: 100%
to height: 100vh
and the #home-content
will fill the viewport.
div#home-content {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100vh; /* changed */
border: 3px solid black;
box-sizing: border-box; /* added, to avoid scroll and make
border size be included in set height */
}
Another is to set its parent to display: flex; flex-direction: column
, and then remove height: 100%
and add flex-grow: 1
, and the #home-content
will fill its parent.
div#home-content {
flex-grow: 1; /* added */
display: flex;
flex-direction: column;
justify-content: space-between;
border: 3px solid black;
}
Upvotes: 1