CSS Grid break Angular - css

I am trying to implement CSS grid template which should behaves as follows:
with equal width of columns
1st and 3rd lines - 2 columns
2nd line - 3 columns
Order = [{
details:[
{
key: '1',
label: 'Name',
checked: true
},
{
key: '2',
label: 'Age',
checked: false
},
{
key: '3',
label: 'Valid From'
},
{
key: '4',
label: 'Valid To'
},
{
key: '5',
label: 'Product'
},
{
key: '6',
label: 'State'
},
{
key: '7',
label: 'Country'
}}]
As per the above Json I have create the css grid
<div class="order-container">
<div class="grid-item">
<div class="grid-header vds-type-copy-strong" *ngFor="let col of salesOrder1[0].details">
<div>{{col.label}}</div>
</div>
</div>
</div>
CSS
.order-container {
.grid-item {
padding: 5px;
max-height: 402px;
overflow-y: auto;
display: grid;
grid-gap: 4px;
grid-template-columns: 1fr 1fr 1fr;
.grid-header {
text-align: center;
div{
padding: 8px 8px;
margin-bottom: 4px;
min-height: 37px;
}
}
}
}
How to break the content after Age and then after product?

One idea is this way. I am not sure how toapply this in angular but just to give you some idea. maybe you can create a blank box see if that will will help you.. Let me know.
.wrapper {
background-color: gray;
display: grid;
grid-template-columns: auto auto auto;
justify-content: space-evenly;
grid-gap: 10px;
padding: 10px;}
.box {
width: 200px;
height: 80px;
border: 1px solid black;
background-color: white;
}
.hiddenbox {
background-color: transparent;
border:0px solid transparent;
}
<div class="wrapper">
<div class="box"></div>
<div class="box"></div>
<div class="hiddenbox box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>

Related

Grid layout but avoid space distribute equally

I'm trying to use the grid layout for two columns in one row which can be easily achieved by flex. I have to create one more div for flex but the grid doesn't need one more div.
The problem with the grid is that it will divide the width space by 2 (cannot align to start/left) and that's not what I want, please refer to the first example below and you will understand.
Is there any way to use the grid in this situation but we can align the items to the left like in the second example?
#main-1 {
display: grid;
gap: 30px;
grid-teplate-column: repeat(2, minmax(0, 1fr));
}
.test-1 {
background-color: orange;
grid-area: span 1 / span 2;
}
.test-2 {
background-color: gray;
width: 150px;
}
#main-2 {
display: flex;
gap: 30px;
margin-top: 30px;
}
.test-3 {
background-color: orange;
width: 100%;
}
.test-4 {
background-color: gray;
width: 150px;
}
.test-1,
.test-2,
.test-3,
.test-4 {
height: 60px;
}
<h1>Grid</h1>
<div id="main-1">
<div class="test-1"></div>
<div class="test-2"></div>
<div class="test-2"></div>
</div>
<h1 style="margin:30px 0 0 0;padding-top:15px;border-top: 3px solid #000;">Flex</h1>
<p style="margin:0 0 30px 0;">This is the desired layout but with one more extra div</p>
<div>
<div class="test-3"></div>
<div id="main-2">
<div class="test-4"></div>
<div class="test-4"></div>
</div>
</div>
Edited
Inline-block might work but we cannot control how many items should be on each row. Imagine the width of the first div .first is dynamic and we do not know how wide it would be(but I will make it 30px for illustration). Now the desired layout should be only one .first and one .second on each row.
By inline-block it would appear that now each row is one .first, one .second, and one .first. Check out the example below. Because we cannot control the amount like grid on each row.
#main {
width: 120px;
}
.first,
.second {
display: inline-block;
height: 60px;
}
.first {
background-color: orange;
width: 30px;
}
<div id="main">
<div class="first"></div>
<p class="second">hhhhhh</p>
<div class="first"></div>
<p class="second">hhhhhh</p>
<div class="first"></div>
<p class="second">hhhhhh</p>
</div>
Define the columns as auto and keep only one at 1fr then you can align to the left.
#main-1 {
display: grid;
gap: 30px;
/* update "5" based on your needs */
grid-template-columns: repeat(5,auto) 1fr;
justify-content: left; /* align to left */
}
.test-1 {
background-color: orange;
grid-column: 1/-1; /* take all the columns */
}
.test-2 {
background-color: gray;
width: 150px;
}
#main-2 {
display: flex;
gap: 30px;
margin-top: 30px;
}
.test-3 {
background-color: orange;
width: 100%;
}
.test-4 {
background-color: gray;
width: 150px;
}
.test-1,
.test-2,
.test-3,
.test-4 {
height: 60px;
}
<h1>Grid</h1>
<div id="main-1">
<div class="test-1"></div>
<div class="test-2"></div>
<div class="test-2"></div>
</div>
<h1 style="margin:30px 0 0 0;padding-top:15px;border-top: 3px solid #000;">Flex</h1>
<p style="margin:0 0 30px 0;">This is the desired layout but with one more extra div</p>
<div>
<div class="test-3"></div>
<div id="main-2">
<div class="test-4"></div>
<div class="test-4"></div>
</div>
</div>

CSS Flex item spanning two rows without fixed height

I am trying to create a flex container layout whereby one of the flex items should span two rows. See image below for a better explanation:
Here is my markup:
<div class="container">
<div class="item item-1">ITEM 1</div>
<div class="item item-2">ITEM 2</div>
<div class="item item-3">ITEM 3</div>
</div>
I cannot seem to achieve this, I have tried using flex-wrap and different combinations of the flex property.
I was able to achieve this by putting ITEM 1 & ITEM 2 in a separate <div>, but this presents a problem on a smaller screen, whereby ITEM 3 needs to appear BETWEEN ITEM 1 & ITEM 2. So I would rather keep the markup as is and use the order property to move things around as necessary.
You can use display: contents on your extra div to achieve what you want:
* {
box-sizing: border-box;
}
.container {
display: flex;
width: 100%;
}
.holder {
width: 67%;
}
.item {
border: 1px solid black;
}
.item-1 {
margin-bottom: 40px;
}
.item-3 {
width: 33%;
}
#media screen and (max-width: 700px) {
.container {
flex-direction: column;
}
.item {
margin-bottom: 20px;
}
.item-1 {
order: 1;
}
.item-2 {
order: 3;
}
.item-3 {
order: 2;
width: 100%;
}
.holder {
width: 100%;
display: contents;
}
}
<div class="container">
<div class="holder">
<div class="item item-1">ITEM 1</div>
<div class="item item-2">ITEM 2</div>
</div>
<div class="item item-3">ITEM 3</div>
</div>
You can't achieve it using flexbox. Instead, you should have two parents which are better.
Use Css-grid. Actually, css-grid is the best option in this case.
Flex-Box
* {
color: #fff;
}
.flex {
display: flex;
justify-content: center;
align-items: center;
}
.child {
border-radius: 10px;
}
.container {
display: flex;
width: 500px;
height: 200px;
border: 1px solid #ff0000;
}
.container .first-item {
flex-direction: column;
justify-content: space-between;
align-items: start;
width: 50%;
height: 100%;
margin-right: 10px;
}
.first-item .child {
width: 100%;
height: 50%;
background-color: blue;
}
.first-item .child:first-child {
margin-bottom: 10px;
}
.container .second-item {
width: 50%;
height: 100%;
}
.second-item .child {
width: 100%;
height: 100%;
background-color: blue;
}
<div class="container">
<div class="first-item flex">
<div class="child flex">Item 1</div>
<div class="child flex">Item 2</div>
</div>
<div class="second-item flex">
<div class="child flex">Item 3</div>
</div>
</div>
Grid
.flex {
display: flex;
justify-content: center;
align-items: center;
}
.child {
background-color: blue;
border-radius: 10px;
}
.container {
display: grid;
grid-template-columns: 1fr 10px 1fr;
grid-template-rows: 1fr 10px 1fr;
grid-template-areas: "c1 . c3"
". . c3"
"c2 . c3";
width: 500px;
height: 300px;
border: 1px solid red;
}
.container .child {
border: 1px solid blue;
}
.child1 {
grid-area: c1;
}
.child2 {
grid-area: c2;
}
.child3 {
grid-area: c3;
}
<div class="container">
<div class="child child1 flex">Item 1</div>
<div class="child child3 flex">Item 3</div>
<div class="child child2 flex">Item 2</div>
</div>
i dont know if its a good solution but
put two item3 codes one in the individual div (item1&2) and one outside then put the one in the div to display none in non-small screens and switch between them with mediaquery
#media (max-width: 40rem) {
.item3 {
display: none;
}
.mobile-item3{
display: block;
}
}

How to horizontally centre a div using CSS Grid instead of margin: 0 auto

I want to horizontally centre a div on the page, I don't want its width to ever be wider than 400px, when the page is wider than 400 there will be equal space to the left and the right of the div and the div will be 400px wide, when the page is less than 400px the div will take up the full width of the screen.
I have gotten used to doing this with margin: 0 auto and max-width: 400px, but I want to know if there's a way the same can be achieved with css grid.
.fullwidth {
width: 100%;
background: red;
}
.maxwidth {
max-width: 400px;
margin: 0 auto;
background: blue;
color: white;
padding: 10px;
}
<div class="fullwidth">
<div class="maxwidth">
I'm 400 pix wide :)
<div/>
<div/>
Here you can see the attempt in grid
.fullwidth {
width: 100%;
display: grid;
grid-auto-flow: column;
justify-content: center;
background: red;
}
.maxwidth {
max-width: 400px;
width: 100%;
background: blue;
color: white;
padding: 10px;
}
<div class="fullwidth">
<div class="maxwidth">
I'm not 400px wide :(
</div>
</div>
You need a 3 column grid on the parent.
The outside columns expand to take up any remaining side space and so margin is not required.
.fullwidth {
background: red;
display: grid;
grid-template-columns: 1fr minmax(0, 400px) 1fr;
}
.maxwidth {
background: blue;
color: white;
padding: 10px;
grid-column: 2;
text-align: center;
}
<div class="fullwidth">
<div class="maxwidth">
I'm in the center with a max width
</div>
</div>
You have two options:
justify-items: center; on the parent, which sets
justify-self: center; on the grid cells.
.fullwidth {
display: grid;
grid-template-columns: 1fr;
justify-items: center;
background: red;
}
.maxwidth {
max-width: 400px;
background: blue;
color: white;
padding: 10px;
}
<div class="fullwidth">
<div class="maxwidth">
I'm in the center with a max width
</div>
</div>
You can also do without defining any template too:
.fullwidth {
background: red;
display: grid;
justify-content:center;
grid-auto-columns:min(400px,100%);
}
.maxwidth {
background: blue;
color: white;
padding: 10px;
text-align: center;
}
<div class="fullwidth">
<div class="maxwidth">
I'm in the center with a max width
</div>
</div>
Also like below:
.fullwidth {
background: red;
display: grid;
justify-items:center; /* it's "items" not "content" */
}
.maxwidth {
background: blue;
color: white;
padding: 10px;
text-align: center;
width:min(400px,100%); /* or width:100% max-width:400px */
box-sizing:border-box;
}
<div class="fullwidth">
<div class="maxwidth">
I'm in the center with a max width
</div>
</div>
Try the following
const fullWidth = {
width: "100%",
height: "100%",
display: "grid",
gridAutoFlow: "column",
alignContent: "center", // vertically centered
justifyContent: "center", // horizontally centered
};
const maxWidth = {
};
export default function Header({ title }) {
return (
<div style={fullWidth}>
<div style={maxWidth}>{title}</div>
</div>
);
}

How to adjust angular components from router-module with an existing css grid

I have this angular reactive-form project. I have done everything but routing. I specified all the routes I need in an app.module.ts file and after that all went bonkers.
In my basic form I had a responsive css grid with two colums that fit the form neatly, before I add an there.
It seems that router outlet adds itself as an item to the grid. and my component that should be rendered creates an additional grid-row, which brakes the whole layout.
How can I fix that?
Here is my template:
<div class="container">
<div class="wrapper">
<app-form-slider></app-form-slider>
<router-outlet></router-outlet>
</div>
</div>
Here is my app.module:
const routes: Routes = [
{path: '', redirectTo: '/form', pathMatch: 'full'},
{path: 'form', component: FormComponent},
{path: 'logined-user', component: FormLoginedUserComponent}
];
#NgModule({
declarations: [
AppComponent,
FormComponent,
FormLoginedUserComponent,
FormSliderComponent
],
imports: [
BrowserModule,
ReactiveFormsModule,
IMaskModule,
RouterModule.forRoot(routes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
And this is my scss template:
.container {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.wrapper {
margin-right: auto;
margin-left: auto;
display: grid;
height: 100vh;
width: 95vw;
#media (min-width: 700px) {
display: grid;
grid-template-columns: 160px 2fr;
width: 1000px;
height: 95vh;
}
}
app-form {
background-color: #fff;
grid-column: 1 / 3;
#media screen and (min-width: 700px){
grid-column: 2/3;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
}
&-slider {
grid-column: 1 / 3;
background-color: #48a5ea;
#media screen and (min-width: 700px){
grid-column: 1/2;
height: 100%;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
height: 20vh;
}
}
If wrap it you can control the space available for it
<div class="container">
<div class="wrapper">
<div class="col-5">
<app-form-slider></app-form-slider>
</div>
<div class="col-7">
<router-outlet></router-outlet>
</div>
</div>
</div>
here I'm using bootstrap as example but you get what I did. Now app-form-slider has 5 columns and anything you throw using your routes router-outlet will have to fit in 7 cols.

How do I do a single row, vertically centered, layout in CSS grid?

I am trying to do a single row, vertically centered layout using CSS grid. Here's a rough sketch:
Note:
I have a single row of items
The items are (probably) going to be the same width
I do not know many items I have (so I don't want to have to say '200px' eighty times)
The items are of different heights, but need to be vertically centered
HTML:
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
</div>
CSS:
.wrapper {
display: grid;
grid-gap: 10px;
grid-auto-columns: 200px;
background-color: #fff;
color: #444;
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
}
I've tried this ibut it really wants to do multiple rows instead of multiple columns on one row.
Can I do a single row, vertically centered layout in CSS grid? If so, how?
Here's a working example. It works just as well as the other answer, but uses different CSS to avoid setting the grid row explicitly. Click 'Run' below:
grid-auto-flow: column; makes items flow across columns, ie into a single row
align-self: center; does vertical centering
.wrapper {
display: grid;
grid-auto-flow: column;
}
.box {
align-self: center;
}
/* Additional styles below */
.wrapper {
grid-gap: 10px;
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
body {
margin: 40px;
}
.box.a {
height: 200px;
}
.box.b {
height: 20px;
}
.box.c {
height: 120px;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box c">D</div>
</div>
To force all items into a single row, set them to grid-row: 1.
To center the items, set the container to align-items: center, or each item to align-self: center. (align-self inherits the align-items value by default).
.wrapper {
display: grid;
align-items: center; /* new */
}
.box {
grid-row: 1; /* new */
}
.box.a { height: 200px; }
.box.b { height: 20px; }
.box.c { height: 120px; }
.box.d { height: 50px; }
/* non-essential decorative styles */
.wrapper {
grid-gap: 10px;
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
body {
margin: 40px;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
</div>

Resources