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 !
Related
I have a split screen, with a fixed right side. Left hand side will be a markdown editor, but with different configurations and styles to add to the output text.
Whereas the right hand side will basically be a preview. Left hand side is scrollable, and right hand side isn't.
After completing the form, users will be able to print out whatever they create basically. So to preview this, I created a content div (that will be printed out) with 210mm x 297mm dimensions to mimic A4 format.
What I want to do is to shrink it down using scale, to show the entire preview of the page to the user, but I want to have it vertically centered.
Here is the sandbox for it:
https://codesandbox.io/s/silly-cloud-cgsnd0?file=/index.html
And to see the actual issue, just uncomment width, height and scale, within content class.
I agree with Paulie_D.
Always give direct code snippets, in this case scale doesn't matter for you, flexbox is a responsive tool, and question is actually just how do you center that div in your setup.
To give others context this is the setup:
<div class="main-col second">
<header>...</header>
<main>
<div class="content">...</div>
</main>
<footer>...</footer>
</div>
.main-col.second {
display: flex;
align-items: center;
flex-direction: column;
background-color: #cccccc;
height: 100vh;
position: fixed;
right: 0;
top: 0;
}
.main-col.second main {
flex-grow: 1;
}
You have two options:
Apply flex-box to the main element inside the .second div.
.main-col.second main {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
Or remove the entire styling for the selector .main-col.second main and add justify-content: space-between to your .main-col.second selector.
I need to create a web layout with a header and a main area. The header's height will grow with its content and the main area will fill the remaining vertical space. Cool, this is easily done either with flex or grid. BUT! Inside the main area I need another element (let's call him badboy) which can have a lot of content and I need it to scroll, not to stretch my main area beyond the lower border of my page.
For the main area I have tried flex with flex-grow: 1 or grid row with size auto. But since such elements do not have a specific height, the badboy always stretches the main element so no overflow happens anywhere.
My HTML:
<div class="app">
<header></header>
<main>
<div class="badboy"></div>
</main>
</div>
The Layout:
If only I could fix the height of the header to a specific height, I could use calc to set the main area's height exactly and problem solved. But my header needs to grow with content. There already is a similar question here saying its impossible, but it is 5 years old and CSS has come long way since then.
Ok, so by digging around some more I have come up with this solution with CSS grid. I don't know if this is hacky or just regular stuff, but it seems to work.
.app {
width: 100vw;
height: 100vh;
grid-template-columns: 100%;
grid-template-rows: fit-content(1px) minmax(1px, auto);
display: grid;
}
header {
background: lightgray;
}
main {
background: gray;
}
.badboy {
max-width: 40rem;
margin: 0 auto;
max-height: 100%;
overflow-y: auto;
background-color: white;
}
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.
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.
I'm creating an internal app so browser compatibility restrictions aren't a massive concern. I am using a div container that is using jquery ui resizable and therefore the size is unknown for any given div. I am also using a chart library (amCharts) which needs the parent div to have a height in order to render the chart.
The issue I'm facing is 100% within a div (with other elements in said div) means whilst the child div accepts 100% as verbatim and makes itself 100% of the parent div this isn't actually the intention - I want it to use the remaining space available in the div, rather than 100%.
I've tried table-row however that doesn't provide a height and therefore amcharts doesn't work well with any resizing (as it has no height/width to base itself on).
So I guess my question is, based on height, what is the best method of making a div use 100% of the remaining space, without JS and without using table/table-cell/table-row styles?
Edit: Here's a JSFiddle of the issue:
https://jsfiddle.net/2c8n1y04/
And the HTML:
<div class="a">
<div class="b"><h3>Header</h3></div>
<div class="c">
<div id="chartdiv"></div>
</div>
</div>
Styles:
html,body,.c,#chartdiv
{
height:100%
}
.a {
height:300px;
background-color: grey;
}
.b {
background-color: yellow;
}
h3 {
margin:0;
}
There is also a chart added in the JSFiddle using the amcharts library, this library is dependent on a height (otherwise it renders to 0 height). Also in the code base i'm using jquery-ui resizable ui (via gridstack) which means I am unable to define a height as the chart height simply has to stretch to the full remaining height within the div.
Any love for Does your engine support flex?
That would in my eyes be the easiest and cleanest solution.
Apply to the parent:
flex-direction: column;
display: flex;
/* or, if a prefixed version is supported, one of: */
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
and to the child to be stretched:
flex: 1;
And you should be good to go.
Demo, if your browser supports it (click on "Full page" to see the effect)
html, body {
height: 100%;
margin: 0;
}
div {
border: solid 1px #333;
padding: 5px;
}
#a {
margin: 10px;
height: calc(100% - 40px);
flex-direction: column;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
#b {
height: 100px;
background: #FFE;
}
#c {
flex: 1;
background: #EFE;
}
<div id="a">
<div id="b">Fixed</div>
<div id="c">Flexible</div>
</div>
But may I ask why you want a no-JS solution, since you're already using jQuery?