Search code examples
javascripthtmlcsscss-grid

Fixed size button on css grid


document.getElementById("card-btn").onclick = function() {
  myFunction()
};

function myFunction() {
  document.getElementById("card-btn").innerHTML = "A little bit longer text";
}
.grid-container {
  display: grid;
  grid-gap: 1em;
  grid-template-columns: repeat(4, minmax(30px, auto));
  grid-template-rows: repeat(4, minmax(30px, auto));
  grid-auto-rows: minmax(50px, auto);
  height: 100vh;
  grid-template-areas: 
   "card1 card2 card3 . card4" 
   "card5 card5 card5 card5 card5" 
   "card6 . . . card7" 
   "card8 card8 card8 card8 card8";
}

.grid-container div {
  background-color: red;
}

#card1 {
  grid-area: card1;
}

#card-btn {
  width: 100%;
}

#card2 {
  grid-area: card2;
}

#card3 {
  grid-area: card3;
}

#card4 {
  grid-area: card4;
}

#card5 {
  grid-area: card5;
}

#card6 {
  grid-area: card6;
}

#card7 {
  grid-area: card7;
}

#card8 {
  grid-area: card8;
}
<!DOCTYPE html>
<html>

<head>
  <title>Page Title</title>
</head>

<body>

  <div class="grid-container">
    <div id="card1">
      <button type="button" id="card-btn">
      Short text
    </button>
    </div>
    <div id="card2">
      card2
    </div>
    <div id="card3">
      card3
    </div>
    <div id="card4">
      card4
    </div>
    <div id="card5">
      card5
    </div>
    <div id="card6">
      card6
    </div>
    <div id="card7">
      card7
    </div>
    <div id="card8">
      card8
    </div>
  </div>

</body>

</html>

I have created simple grid using -template-areas. In the "first cell" I've put a button. When button is clicked, the text on it is changing (to longer one), as well as its width-size. That is the problem for me.

Why the button changes its size, if there is enough space to fit the new text (after click) without expanding its width ?

I know that insted of width: 100% for the button, I could use some static value, like f.e. width: 250px. The reason I'm not interested in that solution is that, when I used ng-bootstrap: dropdown component, and set it width to 100%, it didn't change the button size when the text on it grew in width. That is the reason I think, that I am able to get the same result as they got, but obviously I'm missing something in my case, hence my question.

How to have a button with width: 100% on css grid cell that will not grow in width when text on it changes in length ?


Solution

  • You defined the columns to be minmax(30px, auto) and the auto is the culprit. Basically, you told the browser to automatically calculate the width of the column but not to make them all equal. The content will then define the width like you are facing.

    You can replace auto by 1fr to avoid this effect. You are also using 5 columns so you should correct this too:

    document.getElementById("card-btn").onclick = function() {myFunction()};
    
    function myFunction() {
      document.getElementById("card-btn").innerHTML = "A little bit longer text";
    }
    .grid-container {
      display: grid;
      grid-gap: 1em;
      grid-template-columns: repeat(5, minmax(30px, 1fr));
      grid-template-rows: repeat(4, minmax(30px, auto));
      grid-auto-rows: minmax(50px, auto);
      height: 100vh;
      grid-template-areas: 
        "card1 card2 card3 . card4" 
        "card5 card5 card5 card5 card5" 
        "card6 . . . card7" 
        "card8 card8 card8 card8 card8";
    }
    
    .grid-container div {
      background-color: red;
    }
    
    #card1 {
      grid-area: card1;
    }
    
    #card-btn {
      width: 100%;
    }
    
    #card2 {
      grid-area: card2;
    }
    
    #card3 {
      grid-area: card3;
    }
    
    #card4 {
      grid-area: card4;
    }
    
    #card5 {
      grid-area: card5;
    }
    
    #card6 {
      grid-area: card6;
    }
    
    #card7 {
      grid-area: card7;
    }
    
    #card8 {
      grid-area: card8;
    }
    <div class="grid-container">
        <div id="card1">
          <button type="button" id="card-btn">
          Short text
        </button>
        </div>
        <div id="card2">
          card2
        </div>
        <div id="card3">
          card3
        </div>
        <div id="card4">
          card4
        </div>
        <div id="card5">
          card5
        </div>
        <div id="card6">
          card6
        </div>
        <div id="card7">
          card7
        </div>
        <div id="card8">
          card8
        </div>
      </div>

    Related question to get an example of implicit calculation: Maintain ratio between column in CSS grid. How grid-column is calculated?