0

I am attempting to vertically center :before content within a table cell. The following is the only approach that I have found that actually vertically centers the pseudo-content. However, when I use this approach, the :before content hangs below the end of the table, which allows the user to scroll beyond the end of the table (my containing div must be scrollable, so I can't just do overflow: hidden). Is there a way to vertically center the :before content in all resizing conditions, without extending beyond the bottom of the table?

div {
  border: 1px solid #000;
  overflow: auto;
  resize: both;
  width: 250px;
}

table {
    border: 1px solid #0F0;
    vertical-align: middle;
}

td:first-child {
    padding-left: 20px;
    position: relative;
}

td:first-child::before {
    border: 1px solid #F00;
    content: ">";
    height: 100%;
    left: 0;
    position: absolute;
    top: -11px;
    transform: translate(0, 50%);
}
<div>
  <table>
    <tr><td>First element that can wrap to multiple lines</td><td>Nowrap</td></tr>
  </table>
</div>

I have tried everything I can think of. This includes pretty much all vertical-align settings, including percentages, but these are all ignored because the element isn't inline. Then I tried setting the display property of the :before content to inline, table-cell, inline-block, block; All settings seem to be ignored in this context, making vertical-align worthless. I have also tried to set both margin-top and padding-top to a percentage, neither of which worked, and also tried setting line-height thinking that may have an affect, which it doesn't.

Does anyone know how to adjust the provided code such that the caret is always vertically centered, without allowing scroll beyond the end of the table?

Jeff G
  • 4,470
  • 2
  • 41
  • 76
  • It's funny to me that of the three posts of which this is duplicate, only one of them actually asks how to vertically center content. Further, the first answer in that post that resolves the issue in this context is only the [7th most upvoted](https://stackoverflow.com/a/26356771/960115). Meanwhile, both of the questions asking how to horizontally center content includes the answer to how to vertically center content in the top 3 upvoted answers (in one, the question even contains the answer). I guess I need to start thoroughly reviewing seemingly unrelated questions before posting. – Jeff G May 09 '20 at 19:39

2 Answers2

2

You can use:

top: 50%;
transform: translateY(-50%);

It doesn't have this issues:

div {
  border: 1px solid #000;
  overflow: auto;
  resize: both;
  width: 250px;
}

table {
    border: 1px solid #0F0;
    vertical-align: middle;
}

td:first-child {
    padding-left: 20px;
    position: relative;
}

td:first-child::before {
    border: 1px solid #F00;
    content: ">";
    left: 0;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
<div>
  <table>
    <tr><td>First element that can wrap to multiple lines</td><td>Nowrap</td></tr>
  </table>
</div>
jeprubio
  • 17,312
  • 5
  • 45
  • 56
0

Using flex this is a standard procedure.

div {
  border: 1px solid #000;
  overflow: auto;
  resize: both;
  width: 250px;
}

table {
    border: 1px solid #0F0;
    vertical-align: middle;
}

td:first-child {
    display: flex;
    align-items: center;
    justify-content: center;
}

td:first-child::before {
    border: 1px solid #F00;
    content: ">";
    margin-right: 5px;
}
<div>
  <table>
    <tr><td>First element that can wrap to multiple lines</td><td>Nowrap</td></tr>
  </table>
</div>
Niloct
  • 9,491
  • 3
  • 44
  • 57