1

I have a table with two columns and multiple rows.

HTML

<table cellspacing="0">
<tr class="title">
    <th>Column 1</th>
    <th>Column 2</th>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr class="title">
    <th>Column 1</th>
    <th>Column 2</th>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
</table>
<p style="background-color: #EEE;
background-image: linear-gradient(#F7F7F7, #EEE); padding: 2em; display: block; border: 1px solid #C3C3C3; font-family: Arial, sans-serif;">
The background should actually be like this
</p>

CSS

table {
margin-right: 1px;
font-family: Arial, sans-serif;
}
table td {
    width:auto;
    padding: 1em 2em;
    text-align:center;
    background: gray;
    /* Old browsers */
    background:
    -webkit-linear-gradient(right, transparent 50%, #1F7DE2 50%), linear-gradient(#F7f7f7, #EEE);
    background:
    -moz-linear-gradient(right, transparent 50%, #1F7DE2 50%), linear-gradient(#F7f7f7, #EEE);
    background:
    -o-linear-gradient(right, transparent 50%, #1F7DE2 50%), linear-gradient(#F7f7f7, #EEE);
    background:
    linear-gradient(to left, transparent 50%, #1F7DE2 50%), linear-gradient(#F7f7f7, #EEE);
    background-size: 200% 100%;
    background-position:right bottom;
    margin-left:10px;
    transition:all 0.3s ease-in;
}

table td:active {
    background-position: left bottom;
    color: white;
}

Clicking on a cell (and not header) "changes" its background color. It transitions from left to right, from a gradient (two colors) gray to a solid (monochromatic) blue.

The cells (and not the headers) have two linear backgrounds. The first one (linear-gradient(right, transparent 50%, #1F7DE2 50%)) is the "solid" blue one (activated when the cell has a state of :active, i.e. clicked). The second one (linear-gradient(#F7f7f7, #EEE)) is the two-gray-tones background.

The reason for using two linear background per cell is because when you click on them, the background doesn't really change, but instead the position: the gradient gray background is pushed by the solid blue background.

However, what I want is when you click on any cell (row's children), the whole corresponding row changes its color. So when you click on any cell, the whole row starts to change its color, from left to right.

Maybe instead of changing the whole row, we could make in a manner where the left cell changes first, and then the second, but I believe that'd use JavaScript, plus it'd be more complicated.

Thank you everybody in advance, and for those with questions don't hesitate to ask.

alejnavab
  • 1,136
  • 1
  • 12
  • 30
  • You'll need Javascript as there is no way to select up the DOM with CSS. – Paulie_D Sep 27 '16 at 21:05
  • 1
    Use javascript like jquery and use `closest()` .. example here: http://www.w3schools.com/jquery/traversing_closest.asp – Daniel Sep 27 '16 at 21:06

2 Answers2

2

I think this is what you're after. As someone mentioned you have to use javascript to do this. I used jQuery to make it a little simpler to throw together. It could probably be cleaned up somewhat, but basically it's going to loop thru each td in the row of the td you clicked on, and add the class to it with the CSS animation. There is a setTimeout handling the class and the delay matches the delay in your css animation, so that they happen one after the other in order to make it look like it's transitioning across the row.

The only issue with this is, that I changed your ease-in to linear because with two of them easing, there was a slight 'bump' between cells. You can probably play around with it a bit to make it more seamless. I wrote this so it accommodates any number of cells in a row, but if you know its' always going to be 2, you could do ease-in on the first child and ease out on the second and it would be a nice effect.

Also you'll need to modify the method a bit to handle the 'reverse' animation, as right now it would be backwards. If you can't figure it out, just comment, and I'll see if I can do that later. Gotta run right now.

$("table td").on("click",function() {
  var $row = $(this).closest("tr");
  var $numColumns = $row.children().length;
  for (var $i = 0; $i <= $numColumns; $i++) {
      handleClass($i);
  }
  function handleClass($i) {
    $("table td").css('transition','all 0.3s linear');  
    if($i < $numColumns) {
      setTimeout(function() { 
         $row.children().eq($i).toggleClass('active'); 
      }, $i*300);
    } else {
        setTimeout(function() { 
         $("table td").css('transition','none');  
         $("table td").removeClass('active');  
      }, $i*300);
    }
  }
});
table {
margin-right: 1px;
font-family: Arial, sans-serif;
}
table td {
    width:auto;
    padding: 1em 2em;
    text-align:center;
    background: gray;
    /* Old browsers */
    background:
    -webkit-linear-gradient(right, transparent 50%, #1F7DE2 50%), linear-gradient(#F7f7f7, #EEE);
    background:
    -moz-linear-gradient(right, transparent 50%, #1F7DE2 50%), linear-gradient(#F7f7f7, #EEE);
    background:
    -o-linear-gradient(right, transparent 50%, #1F7DE2 50%), linear-gradient(#F7f7f7, #EEE);
    background:
    linear-gradient(to left, transparent 50%, #1F7DE2 50%), linear-gradient(#F7f7f7, #EEE);
    background-size: 200% 100%;
    background-position:right bottom;
    margin-left:10px;
    transition:all 0.3s linear;
}

table td.active {
    background-position: left bottom;
    color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table cellspacing="0">
<tr class="title">
    <th>Column 1</th>
    <th>Column 2</th>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr class="title">
    <th>Column 1</th>
    <th>Column 2</th>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
<tr>
  <td>Content 1</td>
  <td>Content 2</td>
</tr>
</table>
Robert Wade
  • 4,918
  • 1
  • 16
  • 35
  • [link](https://jsfiddle.net/alej27/5dwagebn/). Thank you a lot @Robert. There's the code. One more thing I'd like to do is, when the transition is finished (both cells have changed their background colors to blue), instead of having to click again to return to initial color (gray), I want it to go straight (in 0 seconds, or 0.1 if not possible) to gray (so it gives the illusion of a blue bar, that when reaches to the right it restarts). – alejnavab Sep 27 '16 at 22:41
  • Ok, there you go. This gets a little tricky because you have to remove and re-apply the css transition properties with javascript in order to accomplish this. A little hacky, but it works. – Robert Wade Sep 28 '16 at 12:47
1

table {
    margin-right: 1px;
    font-family: Arial, sans-serif;
    border-collapse: collapse;
}

td {
    padding: 1em 2em;
    text-align: center;
    margin-left: 10px;
    background: linear-gradient(to left, transparent 50%, #1F7DE2 50%), linear-gradient(#F7f7f7, #EEE);
    background-size: 200% 100%;
    background-position: right bottom;
    transition: all 0.6s ease-in;
}

tr:not(.title):active td {
    background-position: left bottom;
    color: white;
}

tr:not(.title):active td:nth-child(odd), tr:not(.title) td:nth-child(even) {
  transition-delay: 0s;
}

tr:not(.title) td:nth-child(odd), tr:not(.title):active td:nth-child(even) {
  transition-delay: 0.6s;
}
<table cellspacing="0">
    <tr class="title">
        <th>Column 1</th>
        <th>Column 2</th>
    </tr>
    <tr>
      <td>Content 1</td>
      <td>Content 2</td>
    </tr>
    <tr>
      <td>Content 1</td>
      <td>Content 2</td>
    </tr>
    <tr>
      <td>Content 1</td>
      <td>Content 2</td>
    </tr>
    <tr class="title">
        <th>Column 1</th>
        <th>Column 2</th>
    </tr>
    <tr>
      <td>Content 1</td>
      <td>Content 2</td>
    </tr>
    <tr>
      <td>Content 1</td>
      <td>Content 2</td>
    </tr>
    <tr>
      <td>Content 1</td>
      <td>Content 2</td>
    </tr>
</table>

<p style="background-color: #EEE;
 background-image: linear-gradient(#F7F7F7, #EEE); padding: 2em; display: block; border: 1px solid #C3C3C3; font-family: Arial, sans-serif;">
The background should actually be like this
</p>

Does this work for you? I used this and this to help find a way to do this with CSS alone.

StardustGogeta
  • 3,331
  • 2
  • 18
  • 32