Flexbox-Layout with Angular-Components - html

I currently have a simple header, main, footer structure in my angular project and would like to make the main-component a flex-box in order to arrange all given components horizontally with equal width. Additionally I want to change the flex-direction, when the screen width is lower than 700px to column.
Since I already achieved this with pure HTML + CSS (see jsfiddle: http://jsfiddle.net/aJPw7/443/) I have the feeling that this has something to do with angular parent components.
Expected behaviour: The two <app-content-section> elements each take 50% width of the <app-main-component> and 100% height. When I change the flex-direction to column they should have 100% width and 50% height:
Currrent behaviour: The <app-content-section> elements align when I use "justify-content" but are not influenced by any hight or width attributes.
Style.css
html, body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
app-root HTML:
<app-main-component>
<app-content-section></app-content-section>
<app-content-section></app-content-section>
</app-main-component>
app-main-component HTML:
<div class="main-component">
<ng-content></ng-content>
</div>
app-main-component CSS:
.main-component {
display: flex;
flex-direction: row;
height: 100%;
}
#media screen and (max-width: 700px) {
.main-component {
flex-direction: column;
}
}
app-content-section HTML:
<div class="content-section">
<a>Test</a>
</div>
app-content-section CSS:
.content-section {
width: 100%;
height: 100%;
}
Edit1: I also tried :host{ } but still no luck.
Edit2: I created another jsfiddle where I achieved the correct width, by styling the host-element and adding flex: 1, but elements still won´t use the whole height. https://jsfiddle.net/1c15q243/19/

So the correct answer is adding a :host{ flex: 1; } in the "app-content-section CSS" in order to give its hosting-component <app-content-section> the correct flex-sizing.
I figured it out in the fiddle of my second edit, but #karthikaruna pointed out that I forgot to add HTML- tag in the stylig file.

Set 100% height to html. Here is the updated fiddle.

Related

Setting flex-grow: 1 causes div height to go beyond available space

I have some html like this:
.container {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
padding: 10px;
background-color: aqua;
}
.box {
width: 100%;
height: 100%;
flex-grow: 1;
background-color: cadetblue;
display: flex;
flex-direction: column;
}
.fill {
flex-grow: 1;
background-color: antiquewhite;
}
.middle {
height: fit-content;
background-color: azure;
justify-self: flex-end;
}
.bottom {
height: fit-content;
background-color: darkgray;
justify-self: flex-end;
}
<div class="container">
<h3>Title</h3>
<div>Some Stuff</div>
<div class="box">
<div class="fill">Fill</div>
<div class="middle">Middle</div>
<div class="bottom">Bottom</div>
</div>
</div>
I want the divs middle and bottom to stack at the bottom of the screen, and for the div fill to, as the name suggests, fill the remaining space without pushing the middle/bottom divs off the screen or creating a scrollbar, however it doesn't display like that:
Note that the middle and bottom divs are not visible and the scrollbar created by the fill div expanding beyond the available height.
See this StackBlitz for a demo: https://stackblitz.com/edit/angular-ivy-mwtwdg?file=src/app/hello.component.scss
I had to update a lot of CSS but feel free to take a look.
The right approach to any angular project is to have clean from the very first component (app component), and cascade it down to any other component.
Demo stackblitz
EDIT : comment explanation
"The right approach" can be explained quickly like this :
html and body should be at 100% of the page
App component should be at 100% and in display block
Any component that requires some specific layout (flex, grid), should be constrained by its parent or an absolute size, and display block.
The issue with Angular is that when you create a component, it is not set to display: block. This means the component is kind of free in the DOM flow, and this results in the kind of issues you have encountered.
When you set display: block to EVERY component (you can use angular.json to make it automatic), then you have a more deterministic approach to the CSS, where what you expect is what you get.
In your case, since the components were not display:block, they could not be constrained by height, width, or their parents.
Added to that, the fact that you wrote some probelmatic CSS (for instance, the sidenav-container being 100% of the height of its parent : what about the toolbar ?), this resulted in your issue.
As a final word, when it comes to CSS in Angular, be sure to have clean CSS from the top, and when you have any issue like you did, crawl back component by component, to find and correct the unclean ones !

Fix the size of 'html' and 'body' elements to be exactly those of the screen

I often need that html and body elements have the size of the screen. Typically, in the case when I want to have a svg element fit the whole screen.
To achieve that, I saw that it was possible to use CSS code as follow.
html,body{margin:0;padding:0;height:100%;}
The code that I personnaly use is the following one.
html {
height: 100%;
display: flex;
}
body {
flex-grow: 1;
display: flex;
flex-direction: column;
}
Both seem to work well, but I recently had the following remark.
html { height: 100%; display: flex; } is a useless declaration. html height will always be calculated to fit content. Also 100% means 100% of the parent. html has no parent... also applying flexbox to html is useless as it only has 1 child element that is visible: body.
Actually:
I put 100% of html height in order to have it fit the screen height.
I apply flexbox to html in order to be able to use flex-glow: 1 on its child, and have this child filling its parent.
Is there any better to solution than mine?
I personally use this:
html {
display: grid;
min-height: 100%;
}
This will make your body full height by default and will also respect default margin
html {
display: grid;
min-height: 100%;
background: blue;
}
body {
background: red;
}
And you can easily use height:100% on an inner element without issue:
html {
display: grid;
min-height: 100%;
background: blue;
}
body {
background: red;
}
.box {
height: 100%;
border: 5px solid green;
box-sizing: border-box;
}
<div class="box"></div>
I find that whenever working with elements that need to be the full height of the screen height: 100vh is usually a good place to start. VH = viewport height. I use it over height: 100% as depending on the layout 100% doesn't always equal the page height, so with VH you know exactly what you are getting!
With VH you can also then use a calc() in your CSS, so if you needed your body to fill the whole height of the page, but subtract the height of a header for example you could do something like this:
<header style="height: 64px">
<section style="height: calc(100vh - 64px)"

Apply height 100% to all parent elements

I'm trying to get a div in the homepage to fill 100% of the height it can occupy.
I've tried different solutions like applying height: 100% to the body or all the divs etc. but none of it worked.
A solution would be appreciated.
Thanks in advance.
[EDIT]
I applied height: 100% to #__docusaurus and that solved the height but now it does this: https://i.stack.imgur.com/TohTP.png
This is a padding in the Home Page.
Navigate to ./src/components/ and open the HomepageFeatures.js.
Inside this file, look for .features { and remove the line padding: 2rem 0;.
Solved.
I didn't use the height 100% but I applied the following css:
.parent { // For docusaurus/me its .main-wrapper
display: flex;
flex-direction: column;
}
.child { // For me its the feature section that can be seen in the images posted
flex-grow: 1
}
I also removed the height: 100% from the child and parent

Make inner container in flex layout fit screen size

I have the following html and css code:
JSFiddle
/** CSS Framework: START **/
html {
display: flex;
}
.flexbox {
display: flex;
}
/** CSS Framework: END**/
.inner-box {
width: 100%;
overflow-x: scroll;
}
.very-big-container {
width: 4000px;
}
<div class="flexbox">
<!-- I can change everything starting from here -->
<div class="inner-box">
<div class="very-big-container">
Foobar
</div>
</div>
</div>
You see that there is a very big container which doesn't fit a normal screen size. That's why I am using inner-box for setting the max width to 100% and for enabling a horizontal scrollbar. The problem is that the scrollbar for the container inner-box does not appear. I only have a scrollbar for the whole window. I know that I can fix my problem by removing display: flex from html and flexbox, but unfortunately these properties are coming from a css framework and I cannot change anything about that. So do you have any other ideas to enable the scrollbar for inner-box?
Reason
display: flex declaration in the html element enables the flex context for all the direct children of html.
As no flex-direction and flex-wrap properties declared, their default values would get applied on html.
html {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
Solutions
Solution 1
Add flex-direction: column declaration to html element
Solution 2
Add width: 100% declaration to body element
You can use width: 100vw;
See example

Flexbox login page

Well i am not a great designer but i am loving this flexbox.
I am making a small login form demo with flexbox using angular 5 material.
I wish to divide my login form into 2 parts.
I am trying to make it responsive fully .
here is what i am looking for : my login image
So far i have done only this:
login.component.html
<div class="login-container">
<mat-card class="mat-elevation-z12">
<mat-card-content>
</mat-card-content>
</mat-card>
</div>
login.component.scss
.login-container {
height: 100vh;
width: 100%;
position: fixed;
top: 0px;
background: #3f51b5;
padding: 10px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
mat-card {
height: 500px;
width: 900px;
}
mat-card-content {
}
}
Can anybody tell me how I divide this form into 2 parts with the image on the left side block and username/password field on right side of the block?
At the same time how do I make it responsive?
I am not looking for full design but any help would be much appreciated.
It seems like you'd like to use the <mat-card> element to wrap both the image and the form contents. There are many ways to structure this, but the simplest way might be to include two child elements inside <mat-card> – one for the form contents (perhaps your current <mat-card-content> element), and another for the image. You would then want to apply the flexbox properties to <mat-card> rather than .login-container.
Here's one possible approach (assuming you want the two child divs to stretch full-width on screens smaller than 600px wide):
First, in your markup:
<div class="login-container">
<mat-card class="mat-elevation-z12">
<mat-card-image>
<!-- card image here -->
</mat-card-image
<mat-card-content>
<!-- login form contents here -->
</mat-card-content>
</mat-card>
</div>
And in your SCSS:
.login-container {
mat-card {
height: 500px;
width: 900px;
max-width: 100%; // prevents extending beyond screen width
display: flex;
justify-content: center;
align-items: center;
}
mat-card-image,
mat-card-content {
flex: 0 1 50%; // sets flex-basis to 50%
}
}
// media query for responsiveness (adjust 600px as necessary)
#media only screen and (max-width: 600px) {
.login-container {
mat-card-image,
mat-card-content {
flex: 1 1 100%; // sets flex-basis to 100%
}
}
}
The flex: 1 1 100% properties I'm using are the flex shorthand notation. You can find a thorough explanation of that property here: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
I made a quick pen here as a demo:
https://codepen.io/anon/pen/zRMqvx
Make a flexbox container by adding a div block or section and setting it to Display: Flex.
By default, the layout direction will be horizontal and children will stretch vertically
Add 2 div blocks to the flexbox container and give them the same class.
Set Sizing: Expand on both divs to make them evenly fill their parent's widths.