Star Flow
Star Flow

Reputation: 91

web page rendering mystery: button too wide

I have a document that contains HTML and CSS. It is being rendered in a way that I don't understand.

I have observed this with 3 different browsers (Firefox, Chromium, and Opera), so it is unlikely to be a browser bug.

The following image shows what I expect to see. (Before taking this screenshot, I used my browser's zoom function to zoom in.)

enter image description here

The following image shows what I actually see. (Again, I zoomed in before capturing this image.)

enter image description here

The upper group of buttons is as I expect. However, in the lower group of buttons, the "y" button is wider than I expect.

I'll show the markup of the document in a moment, but first I want to talk about it. The difference between the two "y" buttons is that the upper one has the class button-wider-1, whereas the lower one has the class button-wider-2.

In the CSS, each of these classes sets a width, using a calc expression. The difference between the two expressions is that the expression for button-wider-2 adds the width of an "x" button, which means that I expect the right-hand border of the "y" button to align with the right-hand border of the right-hand "x" button. However, as you can see from the second image above, that doesn't happen. My question is: why?

Here is the document (which is completely self-contained):

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>CSS Question</title>

    <style type="text/css">
      .mystery,
      .mystery *
      {
        padding: 0;
        border: 0;
        margin: 0;
      }

      .button-container
      {
        background-color: #f77;
        padding: 1rem;
        margin: 1rem;
      }

      .button
      {
        float: left;
        font-family: 'Courier', monospace;
        width: 3.1rem;
        height: 2rem;
        border: solid black 2px;
        margin-right: 0.7rem;
      }

      .button-wider-1
      {
        /*
          The following 'calc' expression adds up:

            * the standard width of a button (i.e. the width
            of an element with class "button");
            * the width of a button's border;
            * the horizontal margin (i.e. the value of margin-right for a
            button);
            * the width of a button's border;
        */
        width: calc(
          3.1rem +
          2px +
          0.7rem +
          2px
        );
      }

      .button-wider-2
      {
        /*
          The following 'calc' expression is the same as the previous,
          except that there is an extra term at the end, the standard width
          of a button.
        */
        width: calc(
          3.1rem +
          2px +
          0.7rem +
          2px +
          3.1rem
        );
      }
    </style>
  </head>

  <body>
    <div class="mystery">
      <div class="button-container">
        <button type="button" class="button">x</button>
        <button type="button" class="button">x</button>
        <div style="clear: both"></div>
        <button type="button" class="button button-wider-1">y</button>
        <div style="clear: both"></div>
      </div>

      <div class="button-container">
        <button type="button" class="button">x</button>
        <button type="button" class="button">x</button>
        <div style="clear: both"></div>
        <button type="button" class="button button-wider-2">y</button>
        <div style="clear: both"></div>
      </div>
    </div>
  </body>
</html>

I have observed this unexpected rendering in the following 3 browsers (all on Linux):

Upvotes: 1

Views: 1015

Answers (1)

kLabz
kLabz

Reputation: 1847

You are calculating the width of your buttons by adding their width and their border-width. However, now browsers default to border-box for property box-sizing on buttons. https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing

A quick fix is to add box-sizing: content-box; to .button so that reality matches what you expect about calculating widths.

Another fix would be to remove the two +2px from the second calc(); borders being part of the width of a button, you only want your second button to be "2 buttons + 1 margin". The first button is unchanged because you actually want it to be "1 button + 1 margin + 2 borders" so it'll work with both border-box and content-box.

Upvotes: 2

Related Questions