How do I keep content centered in CSS Grid Layout?

Viewed 162

Using CSS Grid Layout, I create a site whose layout changes a little with screen size.

Here, in order to keep the content (pink area) in the CSS Grid Layout central, I did the following styling.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.text {
  color: #fff;
}

.bg {
  background-color: #6c757d;
}

footer {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(20%, 1fr) auto minmax(20%, 1fr);
  grid-template-rows: repeat(3, auto);
}

h1,
dl {
  grid-column: 2;
  background-color: pink;
}

p.h6 {
  grid-row: 3;
  grid-column: 3;
  overflow-wrap: break-word;
}

@media (max-width: 800px) {
  p.h6 {
    grid-column: 2;
  }
}

body>p {
  text-align: center;
}
<footer class="bg text">
  <h1>
    heading
  </h1>
  <dl class="h6">
    <dt>word1</dt>
    <dd>desc1</dd>
    <dt>word2</dt>
    <dd>desc2</dd>
  </dl>
  <p class="h6">COPYRIGHT(C)loooooooooooooooooooooooooongtext</p>
</footer>
<p>&#8593;<br>true center</p>

This seems to work well when the width is wide, but when the width is smaller, the pink area deviates from the "true center".

This also shows that minmax (20%, 1fr) does not work well.

How can I keep this pink area centered? Also, is there a better way than the one I thought above? (With CSS Grid Layout)

2 Answers

You can use grid-template-columns: 1fr auto 1fr for centering the middle column. Now add min-width: 0 on the p.h6 so that you override the default min-width: auto of grid items to allow it to shrink past content size (overflow value other than visible also works) - this allows overflow-wrap: break-word to take effect. See demo below:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.text {
  color: #fff;
}

.bg {
  background-color: #6c757d;
}

footer {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr auto 1fr; /* changed */
  /*grid-template-rows: repeat(3, auto); <-- redundant */
}

h1,
dl {
  grid-column: 2;
  background-color: pink;
}

p.h6 {
  grid-row: 3;
  grid-column: 3;
  overflow-wrap: break-word;
  min-width: 0; /* added */
}

@media (max-width: 800px) {
  p.h6 {
    grid-column: 2;
  }
}

body>p {
  text-align: center;
}
<footer class="bg text">
  <h1>
    heading
  </h1>
  <dl class="h6">
    <dt>word1</dt>
    <dd>desc1</dd>
    <dt>word2</dt>
    <dd>desc2</dd>
  </dl>
  <p class="h6">COPYRIGHT(C)loooooooooooooooooooooooooongtext</p>
</footer>
<p>&#8593;<br>true center</p>

Look at this rule:

p.h6 { grid-column: 3; }

When the width of the viewport is over 800px, the text in the p.h6 element, i.e. this: "COPYRIGHT(C)loooooooooooooooooooooooooongtext"

takes up the far right column, grid-column 3. The pink box in the center then can be very small. This is because you have set grid-template-columns for the footer element to this:

grid-template-columns: minmax(20%, 1fr) auto minmax(20%, 1fr);

In other words, the columns surrounding the pink box should be as big as possible (1fr), while the pink box should be as small as possible (auto, or the width of the text inside).

Now, when the viewport is less than 800px, the copyright text moves to the 2nd, or middle column:

@media (max-width: 800px) { p.h6 { grid-column: 2; } }

This forces the auto width of that column to be the entire width of the "loooooooongtext." That's why it overflows the viewport when you shrink it too small.

You can fix this by adding two property values to the direct children of the footer:

footer > *{ overflow-wrap: break-word; overflow: hidden; }

Both go in the max-width: 800px media query. Demo:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.text {
  color: #fff;
}

.bg {
  background-color: #6c757d;
}

footer {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(20%, 1fr) auto minmax(20%, 1fr);
  grid-template-rows: repeat(3, auto);
}

h1,
dl {
  grid-column: 2;
  background-color: pink;
}

p.h6 {
  grid-row: 3;
  grid-column: 3;
  overflow-wrap: break-word;
}

@media (max-width: 800px) {
  p.h6 {
    grid-column: 2;
  }
  
  footer{
    grid-template-columns: 1fr 1fr 1fr;
  }
  footer > *{
    overflow-wrap: break-word;
    overflow: hidden;
  }
}

body>p {
  text-align: center;
}
<footer class="bg text">
  <h1>
    heading
  </h1>
  <dl class="h6">
    <dt>word1</dt>
    <dd>desc1</dd>
    <dt>word2</dt>
    <dd>desc2</dd>
  </dl>
  <p class="h6">COPYRIGHT(C)loooooooooooooooooooooooooongtext</p>
</footer>
<p>&#8593;<br>true center</p>

Related