Manu Chadha
Manu Chadha

Reputation: 16747

CSS Grid: 100% height of top level container doesn't center child elements

I have an angular css-grid SPA with 3 section, nav, content and footer

<div class="body__div--background"  >
  <div class="css-grid-container">
    <app-nav-component></app-nav-component>
    <app-content-component></app-content-component>
    <app-footer-component></app-footer-component>
  </div>
</div>

The nav is bootstrap navigation. In css-grid, I want that nav takes its usual space, content takes most of the remaining space and footer takes a small space at the bottom

.css-grid-container{
  height:100vh; /*height of the container is same ahs height of the view port.*/
  display: grid;
  grid-gap:20px;
  grid-template-columns: 1fr;  /* 1 columns*/
  grid-template-rows: auto 15fr 1fr; /* 3 rows. Auto takes height of navigation, remaining is divided into 2 rows, middle row is 15 times larger than the 3rd row.*/
}

app-nav-component {
  grid-column: 1 / -1;
  grid-row: 1 / 2;
}

app-footer-component{
  grid-column: 1 / -1;
  grid-row: 3 / -1;
}

app-content-component{
  grid-column: 1 / -1;
  grid-row: 2 / 3;
}

The content could have different types of Angular components. From layout perspective, I want all these to be centered w.r.t the content section. My issue is that if I have say 2 components, say home and signup (at any point only one of them would be visible inside content) then I have to specify height:100% in css of both of these. This would become an issue esp. as the list of my components grow.

.homepage-component-css-grid-container{
  height: 100%;
  display: grid;
  grid-gap:20px;
  grid-template-columns: 1fr 1fr;  /* 2 columns*/
}

.div__signup{
  height:100%;
  display:flex;
  align-items: center;
  justify-content: center;

}

Is there a way by which I specify height:100% only in one place and the components inside content take up the entire space and get centered. I tried to specify height:100% in content (and removed from home and signup) but I noticed that the home and content didn't centered properly i.e. not centered within the content area.

See pics below

height:100 in content area only

<div id="content-div">
  <router-outlet></router-outlet>
</div>

#content-div{
height:100%;
}

enter image description here

what I want is this (but for this I have to explicitly specify height:100 in all the components I want to place inside content. I will prefer not to do this to avoid code duplication)

enter image description here

Upvotes: 1

Views: 4993

Answers (2)

Arne
Arne

Reputation: 1135

If you only want to do it in CSS grid, I would do the following:

  1. Give the class .css-grid-container the grid property grid-template-rows: auto 1fr auto;
  2. Define your app-content-component as a display: grid;.
  3. Now all child elements form app-content-component are grid items and can be aligned with justify-self and align-self.
  4. In your case that would be now align-self: center; and justify-self: center;.

If you want, you should also have more flexibility in a "content grid" with this way. E.g. you can now give the element app-content-component the property grid-template-rows: 15fr;


Here's a look:

body {
  padding: 0;
  margin: 0;
}

.css-grid-container {
  height: 100vh;
  display: grid;
  grid-gap: 20px;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
}

app-nav-component {
  grid-column: 1;
  grid-row: 1 / 2;
  
  padding: 10px;
  background: gray;
}

app-content-component {
  grid-column: 1;
  grid-row: 2 / 3;
  display: grid;
}

login {
  align-self: center;
  justify-self: center;

  padding: 10px;
  background: red;
}

app-footer-component{
  grid-column: 1;
  grid-row: 3 / -1;
  
  padding: 10px;
  background: gray;
}
<div class="body__div--background">
  
  <div class="css-grid-container">
    
    <app-nav-component>

      {nav}    
    
    </app-nav-component>
    
    <app-content-component>
      
      <login>{login}</login>
        
    </app-content-component>
    
    <app-footer-component>
    
      {footer}
    
    </app-footer-component>
    
  </div>
  
</div>


I hope that could help :)

Upvotes: 1

Ricardo Aquino
Ricardo Aquino

Reputation: 31

It is not recommended to used as this... but if you are putting not as many elements inside content-div, you could use this:

#content-div > * {
height: 100%;
}

This should take care of all the children in content-div.

Upvotes: 0

Related Questions