0

I have this code. Despite of being inside a td, and having specified this CSS:

.day {
    text-align: right;
    padding: 5px;
    vertical-align: middle;
    border: 1px solid black;
}

.day--hole {
    color: lightgray;
}

.day--today {
    background: pink;
}
<table>
  <tbody>
    <tr>
      <td class="day day--hole">30</td>
      <td class="day day--hole">31</td>
      <td class="day">1</td>
      <td class="day">2</td>
      <td class="day">3</td>
      <td class="day">4</td>
      <td class="day">5</td>
    </tr>
    <tr>
      <td class="day">6</td>
      <td class="day">7</td>
      <td class="day">8</td>
      <td class="day">9</td>
      <td class="day">10</td>
      <td class="day">11</td>
      <td class="day">12</td>
    </tr>
    <tr>
      <td class="day">13</td>
      <td class="day">14</td>
      <td class="day">15</td>
      <td class="day">16</td>
      <td class="day">17</td>
      <td class="day">18</td>
      <td class="day">19</td>
    </tr>
    <tr>
      <td class="day">20</td>
      <td class="day day--today">21</td>
      <td class="day">22</td>
      <td class="day">23</td>
      <td class="day">24</td>
      <td class="day">25</td>
      <td class="day">26</td>
    </tr>
    <tr>
      <td class="day">27</td>
      <td class="day">28</td>
      <td class="day">29</td>
      <td class="day">30</td>
      <td class="day">31</td>
      <td class="day day--hole">1</td>
      <td class="day day--hole">2</td>
    </tr>
  </tbody>
</table>

There's a visible gap between the position where the text should be centered and the current position of the text. It looks "upper" than it should and not totally centered. Why does this happen and how can I solve it without recurring to change the HTML or use flexbox?

Johannes
  • 64,305
  • 18
  • 73
  • 130
amedina
  • 2,838
  • 3
  • 19
  • 40
  • 2
    I guess your best bet is to set a height on the row and use that as a line-height. Vertical align in my experience usually works when aligning elements to text not text to elements – SuperDJ Aug 21 '18 at 19:24
  • you can reset line-height to 1/0.8em to decrease height. but padding (px)+ unknown(px) font-size will give an average result. try : `.day { line-height:0.8em; text-align: right; padding: 5px; vertical-align: middle; border: 1px solid black; background: linear-gradient(to top, transparent 5px, rgba(0,0,0,0.2) 5px, rgba(0,0,0,0.2) calc(100% - 5px), transparent calc(100% - 5px) );` to see that no gap is showing vertically, but, best, if you want squares. use `width` in `em` and `line-height` in `em` of same value without `padding`. – G-Cyrillus Aug 21 '18 at 19:45
  • 1
    I see no *litlle spacing* underneath the text. what browser do you use to test and how big is that *little spacing* you talk about ? feed back is only usefull to you BTW. – G-Cyrillus Aug 21 '18 at 20:04

3 Answers3

4

That's because these numbers technically are text, and text - when using letters - has letters like g, j, p etc. which extend below the baseline. That's part of the line-height, and the vertical centering centers that line-height, regardless if there are letters like g, j, p in the text or not. So it looks a bit vertically offset as you describe it.

To compensate that, you could apply a vertical offset, as I did it in the first and last row of this snippet, using a wrapper for the numbers and applying position: relative and transform: translateY(1px); (or any value you like) to it:

.day {
    text-align: right;
    padding: 5px;
    vertical-align: middle;
    border: 1px solid black;
}

.day--hole {
    color: lightgray;
}

.day--today {
    background: pink;
}
.offset {
position: relative;
transform: translateY(1px);
}
<table>
  <tbody>
    <tr>
      <td class="day day--hole"><div class="offset">30</div></td>
      <td class="day day--hole"><div class="offset">31</div></td>
      <td class="day"><div class="offset">1</div></td>
      <td class="day"><div class="offset">2</div></td>
      <td class="day"><div class="offset">3</div></td>
      <td class="day"><div class="offset">4</div></td>
      <td class="day"><div class="offset">5</div></td>
    </tr>
    <tr>
      <td class="day">6</td>
      <td class="day">7</td>
      <td class="day">8</td>
      <td class="day">9</td>
      <td class="day">10</td>
      <td class="day">11</td>
      <td class="day">12</td>
    </tr>
    <tr>
      <td class="day">13</td>
      <td class="day">14</td>
      <td class="day">15</td>
      <td class="day">16</td>
      <td class="day">17</td>
      <td class="day">18</td>
      <td class="day">19</td>
    </tr>
    <tr>
      <td class="day">20</td>
      <td class="day day--today">21</td>
      <td class="day">22</td>
      <td class="day">23</td>
      <td class="day">24</td>
      <td class="day">25</td>
      <td class="day">26</td>
    </tr>
    <tr>
      <td class="day"><div class="offset">27</div></td>
      <td class="day"><div class="offset">28</div></td>
      <td class="day"><div class="offset">29</div></td>
      <td class="day"><div class="offset">30</div></td>
      <td class="day"><div class="offset">31</div></td>
      <td class="day day--hole"><div class="offset">1</div></td>
      <td class="day day--hole"><div class="offset">2</div></td>
    </tr>
  </tbody>
</table>
Johannes
  • 64,305
  • 18
  • 73
  • 130
3

As an example I made the height higher than needed. But give the example below a try. The height and line-height should be equal to center the text.

let height = document.getElementById('height');
let days = Array.from( document.querySelectorAll('.day') );

height.addEventListener('input', () => {
  days.forEach( day => {
    day.style.setProperty( '--height', `${height.value}px` );
  });
});
.day {
    text-align: right;
    padding: 5px;
    height: var(--height);
    line-height: var(--height);
    border: 1px solid black;
}

.day--hole {
    color: lightgray;
}

.day--today {
    background: pink;
}

:root {
  --height: 40px;
}
<form>
  <label for="height">Height (play with it to say that the text remains centered)</label>
  <input type="number" id="height" min="1" value="40">
</form>

<table>
  <tbody>
    <tr>
      <td class="day day--hole">30</td>
      <td class="day day--hole">31</td>
      <td class="day">1</td>
      <td class="day">2</td>
      <td class="day">3</td>
      <td class="day">4</td>
      <td class="day">5</td>
    </tr>
    <tr>
      <td class="day">6</td>
      <td class="day">7</td>
      <td class="day">8</td>
      <td class="day">9</td>
      <td class="day">10</td>
      <td class="day">11</td>
      <td class="day">12</td>
    </tr>
    <tr>
      <td class="day">13</td>
      <td class="day">14</td>
      <td class="day">15</td>
      <td class="day">16</td>
      <td class="day">17</td>
      <td class="day">18</td>
      <td class="day">19</td>
    </tr>
    <tr>
      <td class="day">20</td>
      <td class="day day--today">21</td>
      <td class="day">22</td>
      <td class="day">23</td>
      <td class="day">24</td>
      <td class="day">25</td>
      <td class="day">26</td>
    </tr>
    <tr>
      <td class="day">27</td>
      <td class="day">28</td>
      <td class="day">29</td>
      <td class="day">30</td>
      <td class="day">31</td>
      <td class="day day--hole">1</td>
      <td class="day day--hole">2</td>
    </tr>
  </tbody>
</table>
SuperDJ
  • 7,488
  • 11
  • 40
  • 74
-1

.day has text-align: right; on it. Set that to text-align: center;

TaterOfTots
  • 148
  • 5
  • 1
    I guess the OP knows this as he explicitly set it to `right`. Also the OP talks about being too high up or "upper" in the `td` element – SuperDJ Aug 21 '18 at 19:50