smart123s
smart123s

Reputation: 17

CSS highlight all elements of col in a single row

I have a table with multiple col elements and some of them has a span of 3. If I hover over a cell, which is part of a 3 span col, I'd want all the 3 cells in that row to highlight.

Look at the table below for a better understanding of what I'm refering to by Menu A, etc. What I want to do is to highlight all the elements of Menu A on that day when I hover over it. I've tried to achieve it by using siblings, but there's no previous sibling selector, so it only highlights the hovered food, and the foods to its right.

For example, if I hover over MainA1, I'd like to have SoupA1 and GranishA1 highlighted too.

Is there a way to do this in CSS or should I use JavaScript to apply classes to them on hover?

This is what I've tried to do:

.selector .menu-a:hover, .selector .menu-a:hover~.menu-a {
  background: var(--color_hover);
}

This is my table:

:root {
  --color_unselected: #1ba1d6;
  --color_hover: #158ebe;
  --color_selected: #0a688d;
}

.selector {
  border: 1px solid var(--color_unselected);
  width: fit-content;
}

.selector a {
  display: block;
  color: white;
  text-align: center;
  padding: 4px;
  text-decoration: none;
  width: fit-content;
}

.selector {
  border-collapse: collapse;
}

.selector th,
.date-text,
.unselected {
  background: var(--color_unselected);
}


/*My question is about this part*/

.selector .menu-a:hover,
.selector .menu-a:hover~.menu-a {
  background: var(--color_hover);
}
<table id="selector" class="selector">
  <colgroup>
    <col span="1" class="date-text menu-day">
    <col span="3" class="menu-a">
    <col span="3" class="menu-b">
    <col span="1" class="menu-n">
  </colgroup>
  <tr>
    <th><a id="currMthText">2020-1</a></th>
    <th colspan="3"><a>Menu A</a></th>
    <th colspan="3"><a>Menu B</a></th>
    <th><a>Not eating</a></th>
  </tr>
  <!--Generated meals come here-->
  <tr id="line-1" class="line-1">
    <td class="unselected"><a id="day-1">1</a></td>
    <td id="1-a-soup" class="menu-a unselected" )><a>SoupA1</a></td>
    <td id="1-a-main" class="menu-a unselected"><a>MainA1</a></td>
    <td id="1-a-garnish" class="menu-a unselected"><a>GarnishA1</a></td>
    <td id="1-b-soup" class="menu-b unselected"><a>SoupB1</a></td>
    <td id="1-b-main" class="menu-b unselected"><a>MainB1</a></td>
    <td id="1-b-garnish" class="menu-b unselected"><a>GarnishB1</a></td>
    <td id="1-n" class="unselected menu-n">
      <a>Not eating</a>
    </td>
  </tr>
  <tr id="line-2" class="line-2">
    <td><a id="day-2">2</a></td>
    <td id="2-a-soup" class="unselected menu-a"><a>SoupA2</a></td>
    <td id="2-a-main" class="unselected menu-a"><a>MainA2</a></td>
    <td id="2-a-garnish" class="unselected menu-a"><a>GarnishA2</a></td>
    <td id="2-b-soup" class="unselected menu-b"><a>SoupB2</a></td>
    <td id="2-b-main" class="unselected menu-b"><a>MainB2</a></td>
    <td id="2-b-garnish" class="unselected menu-b"><a>GarnishB2</a></td>
    <td id="2-n" class="unselected menu-n">
      <a>Not eating</a>
    </td>
  </tr>
</table>

Upvotes: 1

Views: 153

Answers (1)

Temani Afif
Temani Afif

Reputation: 273004

Here is a trick that rely on pseudo element. The idea is to make a pseudo element on the first item of the menu and this element should overflow to cover all the other elements so that you always catch the hover effect on the first element.

:root {
  --color_unselected: #1ba1d6;
  --color_hover: #158ebe;
  --color_selected: #0a688d;
}

.selector {
  border: 1px solid var(--color_unselected);
  width: fit-content;
  overflow:hidden; /* added */
}

.selector a {
  display: block;
  color: white;
  text-align: center;
  padding: 4px;
  text-decoration: none;
  width: fit-content;
}

.selector {
  border-collapse: collapse;
}

.selector th,
.date-text,
.unselected {
  background: var(--color_unselected);
}


/*My question is about this part*/

.selector .menu-a:hover,
.selector .menu-a:hover~.menu-a {
  background: var(--color_hover);
}

.selector .menu-b:hover,
.selector .menu-b:hover~.menu-b {
  background: var(--color_hover);
}

/* The trick start here */
.selector a {
  position:relative;
}
.selector a::before {
  content:"";
  position:absolute;
  z-index:9;
  top:0;
  left:0;
  bottom:0;
  width:100vw;
  height: 100vw;
}
/* Remove the pseudo element on the next elements*/
.selector .menu-a ~ .menu-a a::before,
.selector .menu-b ~ .menu-b a::before{
    content:none;
}
/**/
<table id="selector" class="selector">
  <colgroup>
    <col span="1" class="date-text menu-day">
    <col span="3" class="menu-a">
    <col span="3" class="menu-b">
    <col span="1" class="menu-n">
  </colgroup>
  <tr>
    <th><a id="currMthText">2020-1</a></th>
    <th colspan="3"><a>Menu A</a></th>
    <th colspan="3"><a>Menu B</a></th>
    <th><a>Not eating</a></th>
  </tr>
  <!--Generated meals come here-->
  <tr id="line-1" class="line-1">
    <td class="unselected"><a id="day-1">1</a></td>
    <td id="1-a-soup" class="menu-a unselected"><a>SoupA1</a></td>
    <td id="1-a-main" class="menu-a unselected"><a>MainA1</a></td>
    <td id="1-a-garnish" class="menu-a unselected"><a>GarnishA1</a></td>
    <td id="1-b-soup" class="menu-b unselected"><a>SoupB1</a></td>
    <td id="1-b-main" class="menu-b unselected"><a>MainB1</a></td>
    <td id="1-b-garnish" class="menu-b unselected"><a>GarnishB1</a></td>
    <td id="1-n" class="unselected menu-n">
      <a>Not eating</a>
    </td>
  </tr>
  <tr id="line-2" class="line-2">
    <td><a id="day-2">2</a></td>
    <td id="2-a-soup" class="unselected menu-a"><a>SoupA2</a></td>
    <td id="2-a-main" class="unselected menu-a"><a>MainA2</a></td>
    <td id="2-a-garnish" class="unselected menu-a"><a>GarnishA2</a></td>
    <td id="2-b-soup" class="unselected menu-b"><a>SoupB2</a></td>
    <td id="2-b-main" class="unselected menu-b"><a>MainB2</a></td>
    <td id="2-b-garnish" class="unselected menu-b"><a>GarnishB2</a></td>
    <td id="2-n" class="unselected menu-n">
      <a>Not eating</a>
    </td>
  </tr>
</table>

Upvotes: 1

Related Questions