CSS flex display acts differently with same flex items in Chrome

Viewed 300

I have several same flex items, containing a rectangle span with margin-right, and a text span scaled due to the font-size limitation of browsers like Chrome. I put them into a flex container but I figured that some of them are incorrect in Chrome, without margin-right of the rect span, but Firefox is fine.

#flex-container {
  display: flex;
  width: 50px;
}

.flex-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  align-content: space-around;
  margin-right: 2.1875px;
  position: relative;
  height: 7px;
}

.rect {
  width: 5px;
  height: 5px;
  display: inline-block;
  background: rgb(6, 74, 105);
  margin-right: 0.875px;
}

.text {
  position: relative;
  font-size: 12px;
  display: inline-block;
  vertical-align: middle;
  transform: scale(0.5);
  transform-origin: left center;
  width: 20.5px;
}
<div id="flex-container">
  <div class="flex-item">
    <span class="rect"></span>
    <span class="text">Mazda</span>
  </div>
  <div class="flex-item">
    <span class="rect"></span>
    <span class="text">Mazda</span>
  </div>
  <div class="flex-item">
    <span class="rect"></span>
    <span class="text">Mazda</span>
  </div>
  <div class="flex-item">
    <span class="rect"></span>
    <span class="text">Mazda</span>
  </div>
  <div class="flex-item">
    <span class="rect"></span>
    <span class="text">Mazda</span>
  </div>
</div>

The code snippet run result is correct, too. But not in https://jsfiddle.net/xgahLv3k/1/

Here is the demo image image, the second item's rectangle has no margin-right.

How can I fix this? Thank you!

2 Answers

If I understand correctly, pixels are the smallest unit that you can use. This means pixels smaller than 1 get rounded to either 0px or 1px depending on the rounding behavior on the browser. In your case, rect class has margin-right smaller than 1px. Just try to avoid using pixel that is smaller than 1px.

Every browser calculates the space in its own way, so when we are dealing with fractions of pixels there can be slight discrepancies. This can be further complicated by anything that causes further calculations, such as the use of flex, or scale transitions.

The best way to deal with this is to use full pixels - if you think about it, a pixels are theoretically the smallest unit for the screen display so fractions of pixels don't make sense, and the browser has to make compensations to deal with such values.

The below snippet uses whole pixels for .flex-item and .rect as follows:

.flex-item {
  margin-right: 2px;
  /* rest of CSS */
}

.rect {
  margin-right: 1px;
  /* rest of CSS */
}

They were 2.1875px + 0.875px so now it adds up to a nice round total of 3px

Working Snippet:

#flex-container {
  display: flex;
  width: 50px;
}

.flex-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  align-content: space-around;
  margin-right: 2px;
  position: relative;
  height: 7px;
}

.rect {
  width: 5px;
  height: 5px;
  display: inline-block;
  background: rgb(6, 74, 105);
  margin-right: 1px;
}
.text {
  position: relative;
  font-size: 12px;
  display: inline-block;
  vertical-align: middle;
  transform: scale(0.5);
  transform-origin: left center;
  width: 20px;
}
<div id="flex-container">
    <div class="flex-item">
      <span class="rect"></span>
      <span class="text">Mazda</span>
    </div>
    <div class="flex-item">
      <span class="rect"></span>
      <span class="text">Mazda</span>
    </div>
    <div class="flex-item">
      <span class="rect"></span>
      <span class="text">Mazda</span>
    </div>
    <div class="flex-item">
      <span class="rect"></span>
      <span class="text">Mazda</span>
    </div>
    <div class="flex-item">
      <span class="rect"></span>
      <span class="text">Mazda</span>
    </div>
  </div>

Related