Is it possible to set a td with display flex to be full height, or have different CSS to achieve the same effect?
Asked Answered
H

3

6

I have inherited a project where someone decided to set the display for a td to flex. One of the consequences of this is that when there are other tds in the row that span multiple lines, the td with display: flex does not stretch to the height of the other tds.

The correct way to fix this (I think) would be to remove the display: flex from the td and have it on an inner div, but I currently only have permissions to modify the CSS, so I'm wondering if there is any way to fix it with CSS only (while preserving the layout within the td as shown in the made-up code snippet below)?

EDIT: The desired layout is to have a left and right side within the td, the right side being a span that is a colored dot. The colored dot needs to always be on the right and top aligned even on a mobile device when the td is very narrow and the left side ends up wrapping.

table td {
  border: 1px solid black;
}

td.flex {
  display: flex;
  justify-content: space-between;
}

span.right {
  display: inline-block;
  margin-left: 1em;
  width: 1em;
  border-radius: 50%
}

span.red {
  background-color: red;
}

span.green {
  background-color: green;
}
<table>
  <tbody>
    <tr>
      <td class="flex"><span>Left </span><span class="right red">&nbsp;</span></td>
      <td>td with<br>multiple rows<br>blah blah blah</td>
    </tr>
    <tr>
      <td class="flex"><span>Left side longer </span><span class="right red">&nbsp;</span></td>
      <td>td with<br>multiple rows<br>blah blah blah</td>
    </tr>
    <tr>
      <td>
        <div class="flex"><span>The right way to do it </span><span class="right green">&nbsp;</span></div>
      </td>
      <td>td with<br>multiple rows<br>blah blah blah</td>
    </tr>
</table>
Hadst answered 8/3, 2022 at 13:31 Comment(6)
The whole point of a table is to act like a table. Applying flexbox will negate this in many respects.Trice
I'm aware of that, I'm just wondering if there's a workaround with CSS so I can provide a quick fix until I get permissions to modify the code that generates the table and do it properly.Hadst
I'd suggest you to write valid HTML before trying to apply any fix. 1) You opened tbody but never closed it. Also, your first 2 td tags are not wrapped in tr, however after them you included a </tr>.Coenosarc
Why do you need the flex display at all in there? What's wrong/unwanted if you simply remove it?Hagiology
@Coenosarc - the missing tr and tbody are typos, I've added them. As per my post, I currently only have access to the CSS. I'm trying to determine if I can provide a CSS fix while I'm waiting for access to the HTML to do it properly.Hadst
@Hagiology - If I remove the display: flex I lose the right alignment of the colored dot. I would love to remove it if I can find a different way to achieve the layout without changing the HTML.Hadst
F
1

Set the widths so that the right <span> takes up 2.3rem (width: 1.15rem; margin-left: 1.15rem) and the left <span> takes up the rest of the <td> width. Note the em are replaced by rem because they are not affected by casscading styles and inheritance:

span:first-of-type {
  width: calc(100% - 2.3rem);
}

In the example, all <td> and <span> are the same to demonstrate how the styles behave with different lengths of text in the left <span>. Tested it in moblie dimensions and it is always centered vertically and the dots always at the far right never shifting. The shape is always round as well due to changing em to rem and adding height: 1.15rem;. This is much better than flexbox.

:root {
  font: 2ch/1 'Segoe UI';
}

table td {
  border: 1px solid black;
}

span {
  display: inline-block;
  border: 0;
  vertical-align: middle;
}

span:first-of-type {
  width: calc(100% - 2.3rem);
}

span.right {
  width: 1.15rem;
  height: 1.15rem;
  margin-left: 1.15rem;
  border-radius: 50%;
}

span.red {
  background-color: red;
}

span.green {
  background-color: green;
}
<table>
  <tbody>
    <tr>
      <td class="flex"><span>Left </span><span class="right red">&nbsp;</span></td>
      <td>td with<br>multiple rows<br>blah blah blah</td>
    </tr>
    <tr>
      <td class="flex"><span>Left side longer </span><span class="right red">&nbsp;</span></td>
      <td>td with<br>multiple rows<br>blah blah blah</td>
    </tr>
    <tr>
      <td class="flex"><span>The right way to do it </span><span class="right green">&nbsp;</span>
      </td>
      <td>td with<br>multiple rows<br>blah blah blah</td>
    </tr>
</table>
Feoff answered 8/3, 2022 at 15:41 Comment(1)
Use the calc(100% - 2.3rem) was the key, this got me where I needed without the HTML needing to be changed. Thanks!Hadst
H
0

I don't know what the real code contains instead of the red/green dot, but if it's an image or something similar, you can simply use float: right on it and remove the display: flex from the td:

table td {
  border: 1px solid black;
}

td.flex {
  /* removed */
}

span.right {
  display: inline-block;
  margin-left: 1em;
  width: 1em;
  border-radius: 50%
}

span.red {
  background-color: red;
  float: right;
}

span.green {
  background-color: green;
}
<table>
  <tbody>
    <tr>
      <td class="flex"><span>Left </span><span class="right red">&nbsp;</span></td>
      <td>td with<br>multiple rows<br>blah blah blah</td>
    </tr>
    <tr>
      <td class="flex"><span>Left side longer </span><span class="right red">&nbsp;</span></td>
      <td>td with<br>multiple rows<br>blah blah blah</td>
    </tr>
    <tr>
      <td>
        <div class="flex"><span>The right way to do it </span><span class="right green">&nbsp;</span></div>
      </td>
      <td>td with<br>multiple rows<br>blah blah blah</td>
    </tr>
</table>
Hagiology answered 8/3, 2022 at 13:41 Comment(2)
This doesn't work when the first td is narrow for example on a mobile device - the color dot ends up lower than the text instead of directly to the right of it.Hadst
(The real code contains a span for the colored dot just like the example I made up)Hadst
P
0

so I'm wondering if there is any way to fix it with CSS only

Yes, use something like this to get the original/intended behaviour:

td {
  display: table-cell !important;
}

If I remove the display: flex I lose the right alignment of the colored dot

Add one more CSS rule to align that to the right, for example, using float: right

span.right {
  float: right;
}

table td {
  border: 1px solid black;
}
td.flex {
  display: flex;
  justify-content: space-between;
}

span.right {
  float: right;
  display: inline-block;
  margin-left: 1em;
  width: 1em;
  border-radius: 50%
}
span.red {
  background-color: red;
}
span.green {
  background-color: green;
}

td {
  display: table-cell !important;
}
<table><tbody><td class="flex"><span>Left </span><span class="right red">&nbsp;</span></td><td>td with<br>multiple rows<br>blah blah blah</td></tr>
<tr><td class="flex"><span>Left side longer </span><span class="right red">&nbsp;</span></td><td>td with<br>multiple rows<br>blah blah blah</td></tr>
<tr><td><div class="flex"><span>The right way to do it </span><span class="right green">&nbsp;</span></div></td><td>td with<br>multiple rows<br>blah blah blah</td></tr>
</table>

Pentastyle answered 8/3, 2022 at 13:41 Comment(1)
This doesn't work when the first td is narrow for example on a mobile device - the color dot ends up lower than the text instead of directly to the right of it.Hadst

© 2022 - 2024 — McMap. All rights reserved.