user801347
user801347

Reputation: 1373

How best highlight (red border, outline, etc) a table cell. without taking up extra space

How can I best highlight a cell in a table, without taking up additional space. Just setting the background color is not good enough. (as it has to be a light color for the number/text to be readable).

CSS Outline would be OK if it could have rounded corners, but without them it doesn't have the same look/style as the rest of the document. The best I have so far is putting a border around an absolute element positioned over the cell. But this requires the extra element, AND it's positioned OVER, not UNDER, so the color needs to have opacity, in case it is over text in adjacent cells.

<style>
td {
    vertical-align:top; position:relative; text-align:right;
}
.bordered { 
position: absolute;width:calc(100% + 20px)!important;left:-10px;top:-5px;border:6px rgba(255,0,0,0.7)solid;border-radius:8px;width:200%;
}
</style>
<body>
<table style="width: 100%">
    <tr>
        <td><span class="bordered">&nbsp;&nbsp;&nbsp;</span>1&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td>12</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td><span class="bordered">&nbsp;&nbsp;&nbsp;</span>123</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>1234</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td><span class="bordered">&nbsp;&nbsp;&nbsp;</span>123456789</td>
    </tr>
</table>

a) Can Outline have rounded corners?

b) Can above be done without the extra element?

c) Can above be positioned Under, rather than Over the cell?

Background: I have an html app. that produces a 'Picking List' (for operatives to pick the right products for an Order. It has a 'Quantity' field which css highlights yellow when it's greater than ONE (but operatives don't notice it - and just despatch one (which is the usual qty). css highlights with a background Yellow - if we use Red - it's difficult to read the number (which is in black).

No cross-browser issues as operatives just use Chrome internally.

Upvotes: 1

Views: 2510

Answers (4)

Intervalia
Intervalia

Reputation: 10965

If you can not take up ANY space then try this:

var btn = document.querySelector('#toggle');
btn.addEventListener('click', () => {
  document.querySelectorAll('[a]').forEach(
    el => {
      el.classList.toggle('bordered');
    }
  );
});
td {
  vertical-align:top;
  text-align:right;
}

.bordered {
  position: relative;
  z-index: 1;
}

.bordered::before {
  border: 4px solid rgba(255,0,0,.5);
  border-radius: 4px;
  bottom: -2px;
  content: '';
  left: -4px;
  position: absolute;
  right: -4px;
  top: -2px;
  z-index: -1;
}
<table style="width: 100%">
  <tr>
    <td a class="bordered">&nbsp;&nbsp;&nbsp;1&nbsp;</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td>12</td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td a class="bordered">&nbsp;&nbsp;&nbsp;123</td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td>1234</td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td a class="bordered">&nbsp;&nbsp;&nbsp123456789</td>
  </tr>
</table>

<button id="toggle">Toggle</button>

I an using the pseudo-element ::before to show the border. Like your example it is position: absolute and then I tie the top, left, right and bottom to the cell.

Click on the toggle button to see the adding and removal of the borders.

UPDATED

Based on your question I changed top, left, right and bottom to negative numbers to avoid overlap

Upvotes: 1

Ben Viau
Ben Viau

Reputation: 106

In relation to Julie's answer, you can actually have the best of both worlds if you also apply a border-radius. For instance:

td {
  border: 0px solid transparent;
  box-shadow: 0 0 5px red;
  border-radius: 10px;
}

The border itself is invisible and takes no space, but the box-shadow will now follow the curve of the would-be border. You can adjust the box shadow params to make the outline hard or fuzzy.

Upvotes: 2

Julie
Julie

Reputation: 48

You could use a box shadow as a border.

 .bordered { 
  box-shadow: 0 0 5px red;
}

It's not rounded, but it doesn't look quite as boxy either.

Upvotes: 1

Intervalia
Intervalia

Reputation: 10965

Just make ALL of the TDs have a 1px transparent border, then on the selected ones set the color.

td {
  border: 1px solid transparent;
  vertical-align:top;
  text-align:right;
}

.bordered { 
  border-color: red;
  border-radius: 4px;
}
<table style="width: 100%">
  <tr>
    <td class="bordered">&nbsp;&nbsp;&nbsp;1&nbsp;</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td>12</td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td class="bordered">&nbsp;&nbsp;&nbsp;123</td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td>1234</td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td class="bordered">&nbsp;&nbsp;&nbsp123456789</td>
  </tr>
</table>

Upvotes: 1

Related Questions