Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: Why aren't these responsive squares totally square? [duplicate]

I'm trying to make a grid of resizable squares with some text inside them. Here's the code:

/* Dirty quick CSS reset */
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  display: flex;
  flex-flow: column;
  flex: 1;
  background: aliceblue;
}

.row {
  display: flex;
  flex: 1;
}

.square {
  border: 1px solid black;
    
  width: 14.2857%; /* 100% / 7 */
  font-size: 18px;
  padding: 8px;
  
  /* square-width - font-size - padding-top */
  padding-bottom: calc(14.2857% - 18px - 8px);
}
<div class="container">
  <div class="row">
    <div class="square">1</div>
    <div class="square">2</div>
    <div class="square">3</div>
    <div class="square">4</div>
    <div class="square">5</div>
    <div class="square">6</div>
    <div class="square">7</div>
  </div>
</div>

As we can see, there's a row of squares that adapt to the size of the window. The problem is that if we inspect them, we see that they aren't totally squares (they are about 3px taller than wide). It gets worse if we increase the font-size, and as far as I know, the maths is correct.

What's going on here? Why am I getting those extra pixels?

like image 804
amedina Avatar asked Aug 22 '18 18:08

amedina


People also ask

How do you make a responsive square in CSS?

By making use of the :after pseudo-element and 'padding-bottom' , we can create our responsive square using only CSS. The solution relies on the somewhat counterintuitive fact that padding is calculated as a percentage of its parent element's width, not height.

How do you make a square in Flexbox?

Making square tiles with flexbox is simple! Just add flex-wrap and width , and everything will magically work as together!

What does it mean when someone says that CSS grid is 2 dimensional and Flexbox is 1 dimensional?

One Vs Two Dimension:Grid is made for two-dimensional layout while Flexbox is for one. This means Flexbox can work on either row or columns at a time, but Grids can work on both. Flexbox, gives you more flexibility while working on either element (row or column).


2 Answers

I encountered this problem a while ago, and was able to solve it through this solution by using Pseudo element

/* Dirty quick CSS reset */

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

.container {
  display: flex;
  flex-flow: column;
  flex: 1;
  background: aliceblue;
}

.row {
  display: flex;
  flex: 1;
}

.square {
  border: 1px solid black;
  width: 14.2857%;
  /* 100% / 7 */
  font-size: 18px;
  padding: 8px;
}

.square:before {
  content: '';
  float: left;
  padding-top: 100%;
}
<div class="container">
  <div class="row">
    <div class="square">1</div>
    <div class="square">2</div>
    <div class="square">3</div>
    <div class="square">4</div>
    <div class="square">5</div>
    <div class="square">6</div>
    <div class="square">7</div>
  </div>
</div>
like image 159
Dhaval Jardosh Avatar answered Oct 19 '22 02:10

Dhaval Jardosh


The exact calculation should be (14.2857% - 8px - 2px - Lpx) we remove the padding-top and the border and the line-height (not the font-size), so you should know the value of the line-height or you set it:

/* Dirty quick CSS reset */
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  display: flex;
  flex-flow: column;
  flex: 1;
  background: aliceblue;
}

.row {
  display: flex;
  flex: 1;
}

.square {
  border: 1px solid black;
    
  width: 14.2857%; /* 100% / 7 */
  font-size: 18px; 
  line-height:1em; /*equal to font-size*/
  padding: 8px;
  
  /* square-width - font-size - padding-top */
  padding-bottom: calc(14.2857% - 8px - 2px - 18px);
}
<div class="container">
  <div class="row">
    <div class="square">1</div>
    <div class="square">2</div>
    <div class="square">3</div>
    <div class="square">4</div>
    <div class="square">5</div>
    <div class="square">6</div>
    <div class="square">7</div>
  </div>
</div>

If we refer to the documentation the line-height is the value that define the height of the lines and the default value is set to normal:

The line-height CSS property sets the amount of space used for lines, such as in text.

And

normal

Depends on the user agent. Desktop browsers (including Firefox) use a default value of roughly 1.2, depending on the element's font-family.

As you can see the line-height is not necessarily equal to font-size

like image 27
Temani Afif Avatar answered Oct 19 '22 02:10

Temani Afif