Making grid cell content fill the cell, without losing flow layout

61 Views Asked by At

I have this code for a grid:

  .cards {
  display: grid;
  grid-template-columns: repeat(2, 15em);
  padding: 0.5em;
  gap: 0.5em;
}

.cards>div {
  border: 1px solid blue;
}

h2 {
  margin: 0;
  border-bottom: 1px solid green;
}

.logo {
  float: right;
  border: 1px solid red;
}

p {
  margin: 0;
  background-color: yellow;
}
<div class="cards">
  <div>
    <h2>
      <div class="logo">LOGO<br>LOGO</div>Title</h2>
    <p>Some content made from some words</p>
  </div>
  <div>
    <h2>Title</h2>
    <p>Some content<br>Some more<br>Even more</p>
  </div>
</div>
Edited: div class=logo instead of aside

When you try this, you see:

  • the LOGO extends into the p element and displaces its content. That's good, I want that
  • the p element of the second card is higher and determines the height of the grid row. That's good, I want that
  • the p element of the first card does not reach the bottom of the card. That's normal, but I want to change that.

How to make the smaller p to fill the room under the heading? Flexbox is not an option, because flex items create block formatting contexts, causing the h2 height to increase. I do not want that!

I could use JavaScript to achieve this. But you shouldn't use JavaScript when pure CSS will do. But does it? I don't find a solution.

3

There are 3 best solutions below

2
Hoffmann On

Ok, I am not sure is it what u want but let's try.

So I thought why u can't use simple height:100% for p element?

But then I understand that height is starts stick out of div and that's because when you set height to 100%, it is calculated based on the height of its main container excluding the padding and you got 0.5em padding on .card

So I try to fit it just by changing the % of heigh and it's work pretty nice when I set it in something like 76%. But? But what if the content change? It's doesn't work good any more.

The solution for this is calc function. It can help subtract the padding from 100% height. You can try something like this:

height: calc(100% - 1.75em)

It's fill almost 100% of the div and it's works when height is changed by content.

The final CSS:

.cards {
display: grid;
grid-template-columns: repeat(2,15em);
padding: 0.5em;
gap: 0.5em;
}
.cards &gt; div {
border: 1px solid blue;
}
h2 {
margin: 0;
border-bottom: 1px solid green;
}
aside {
float:right;
border: 1px solid red;
}
p {
margin: 0;
background-color: yellow;
height: calc(100% - 1.75em)
}
3
Utkarsh Desai On

try this one

 <!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
          .cards {
  display: grid;
  grid-template-columns: repeat(2, 15em);
  padding: 0.5em;
  gap: 0.5em;
}

.cards>div {
  border: 1px solid blue;
}

h2 {
  margin: 0;
  border-bottom: 1px solid green;
}

.logo {
  float: right;
  border: 1px solid red;
}

p {
  margin: 0;
  background-color: yellow;
}
    </style>
</head>
<body>
    <div class="cards">
        <div>
          <h2>
            <div class="logo">LOGO<br>LOGO</div>Title</h2>
          <p>Some content <br> made from <br>some words</p>
        </div>
        <div>
          <h2>Title</h2>
          <p>Some content<br>Some more<br>Even more</p>
        </div>
      </div>
</body>
</html>
0
SioGabx On

The only solution i can think of with CSS is to set the height of p to 100% and set the card div overflow to hidden. It's seems to be ok (at least for this example)

.cards {
  display: grid;
  grid-template-columns: repeat(2, 15em);
  padding: 0.5em;
  gap: 0.5em;
}

.cards>div {
  overflow: hidden;
  border: 1px solid blue;
}

h2 {
  margin: 0;
  border-bottom: 1px solid green;
}

.logo {
  float: right;
  border: 1px solid red;
}

p {
  height: 100%;
  margin: 0;
  background-color: yellow;
}
<div class="cards">
  <div>
    <h2>
      <div class="logo">LOGO<br>LOGO</div>Title</h2>
    <p>Some content made from some words</p>
  </div>
  <div>
    <h2>Title</h2>
    <p>Some content<br>Some more<br>Even more</p>
  </div>
</div>

<div class="cards">
  <div>
    <h2>
      <div class="logo">LOGO<br>LOGO</div>Title</h2>
    <p>Some content made from some words</p>
  </div>
  <div>
    <h2>This is a very long title to test if it overflow</h2>
    <p>Some content<br>Some more<br>Even more<br>Even more<br>Even more<br>Last</p>
  </div>
</div>