arcol
arcol

Reputation: 1648

Vertical align inside CSS grid

I would like to have a giant progressbar which is vertically aligned inside a CSS grid.

The problem is, vertical alignment inside CSS grid is not working for me. I tried on Firefox, and also on Chrome.

I tried vertical-align: middle, but it is not working. I have put a Flexbox inside the grid item, but still it is not working.

Here is my minimal example:

.wrapper {
  display: grid;
  border-style: solid;
  border-color: red;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(4, 1fr);
  grid-gap: 10px;
  width: 100vw;
  height: 100vh;
}

.one {
  border-style: solid;
  border-color: blue;
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}

.two {
  border-style: solid;
  border-color: yellow;
  grid-column: 1 / 3;
  grid-row: 2 / 4;
}

.three {
  border-style: solid;
  border-color: violet;
  grid-column: 1;
  grid-row: 4 / 5;
}

.four {
  border-style: solid;
  border-color: aqua;
  grid-column: 2;
  grid-row: 4 / 5;
}

progress {
  width: 100%;
  background-color: #f3f3f3;
  border: 0;
  height: 2em;
}
<div class="wrapper">
  <div class="one">One</div>
  <div class="two">
    <div class="vertical">
      <progress max="100" value="80">
            <div class="progress-bar">
              <span style="width: 80%;">Progress: 80%</span>
            </div>
          </progress>
    </div>
  </div>
  <div class="three"> Three</div>
  <div class="four">Four</div>
</div>

A demo: https://codepen.io/anon/pen/OOpdPW

How do I align the progressbar vertically (inside its grid item) of the above demo project?

Upvotes: 13

Views: 27641

Answers (4)

VXp
VXp

Reputation: 12058

Add display: grid and align-items: center to the .two div, but you could also use the align-self: center on the .vertical div if the usage of the align-items: center on the parent is avoided:

.wrapper {
  display: grid;
  border-style: solid;
  border-color: red;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(4, 1fr);
  grid-gap: 10px;
  width: 100vw;
  height: 100vh;
}

.one {
  border-style: solid;
  border-color: blue;
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}

.two {
  display: grid; /* Added */
  align-items: center; /* Added */
  border-style: solid;
  border-color: yellow;
  grid-column: 1 / 3;
  grid-row: 2 / 4   ;
}

.three {
  border-style: solid;
  border-color: violet;
  grid-column: 1;
  grid-row: 4 / 5;
}

.four {
  border-style: solid;
  border-color: aqua;
  grid-column: 2;
  grid-row: 4 / 5;
}

progress {
  width: 100%;
  background-color: #f3f3f3;
  border: 0;
  height: 2em;
}

/* Optional, without the usage of the align-items: center; on the .two div
.vertical {
  align-self: center;
}
*/
<div class="wrapper">
  <div class="one">One</div>
  <div class="two">
    <div class="vertical">
      <progress max="100" value="80">
        <div class="progress-bar">
          <span style="width: 80%;">Progress: 80%</span>
        </div>
      </progress>
    </div>
  </div>
  <div class="three"> Three</div>
  <div class="four">Four</div>
</div>

Upvotes: 2

Andre Ramadhan
Andre Ramadhan

Reputation: 427

Give the progress extra style. position absolute, top, and transform: translate.

Don’t forget to add position:relative to the parent of progress:

progress {
  width: 100%;
  background-color: #f3f3f3;
  border: 0;
  position: absolute;
  top: 50%;
  transform: translate(0, -50%);
  height: 2em;
}

Upvotes: 0

Temani Afif
Temani Afif

Reputation: 272744

For the Flexbox solution, you have to add display:flex and align-items: center to .two, so the CSS becomes like this:

.two {
    border-style: solid;
    border-color: yellow;
    grid-column: 1 / 3;
    grid-row: 2 / 4;
    display: flex;
    align-items: center;
}

Then add flex: 1 to .vertical:

.vertical {
    flex: 1
}

Here is the full code:

.wrapper {
  display: grid;
  border-style: solid;
  border-color: red;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(4, 1fr);
  grid-gap: 10px;
  /* width: 100vw; not needed */
  height: 100vh;
}

.one {
  border-style: solid;
  border-color: blue;
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}

.two {
  border-style: solid;
  border-color: yellow;
  grid-column: 1 / 3;
  grid-row: 2 / 4;
  display: flex;
  align-items: center;
}

.vertical {
  flex: 1;
}

.three {
  border-style: solid;
  border-color: violet;
  grid-column: 1;
  grid-row: 4 / 5;
}

.four {
  border-style: solid;
  border-color: aqua;
  grid-column: 2;
  grid-row: 4 / 5;
}

progress {
  width: 100%;
  background-color: #f3f3f3;
  border: 0;
  height: 2em;
}
<div class="wrapper">
  <div class="one">One</div>
  <div class="two">
    <div class="vertical">
      <progress max="100" value="80">
        <div class="progress-bar">
          <span style="width: 80%;">Progress: 80%</span>
        </div>
      </progress>
    </div>
  </div>
  <div class="three"> Three</div>
  <div class="four">Four</div>
</div>

Upvotes: 9

Doug Wilhelm
Doug Wilhelm

Reputation: 796

Do you always forget how to vertically-align elements within a div, using CSS Grid? Don't feel alone, because I do too and I always end up here. Essentially, these two properties can be applied to the div containing elements that need to be vertically-centered:

.some-class {
  display: grid;
  align-items: center;
}

Here is a JSFiddle example for anyone curious on how these properties work.

Resources

Upvotes: 17

Related Questions