How to add/remove shadows from an element with "position: Sticky" as scrolled?

Asked

Viewed 122 times

3

I made a table with the header and the last fixed column using position: sticky. To give an impression that it is above other columns/rows, I used box-shadow, but it gets weird to leave the box-shadow when the row or column is in position relative (visually speaking, the behaviour of a position: sticky varies between fixed and relative).

Simply put, I want to take the shadows off the last column when the scroll bar is horizontally at the end, and take the shadows off the header when the scroll bar is vertically at the beginning. I imagine you can’t do that with CSS, at least not with an imaginary dial :stuck and :not(:stuck), so I added the Javascript tag.

Antdesign has an example of the desired result, but in this case the table has shadows only in the fixed columns, not in the header.

Although I don’t want solutions with Scroll Event Listener for reasons of performance (see Scroll-Linked effects), if someone solves this way, can share to have as reference and help other people :)

The code is also available on Codesandbox.

main {
  display: flex;
  max-height: 20rem;
  overflow: auto;
}

table {
  border-spacing: 0;
}

th {
  text-align: left;
}

th,
td {
  border-bottom: 1px solid #c6c6c6;
  height: 5rem;
  white-space: nowrap;
  padding-right: 2rem;
}

.fixed {
  background-color: white;
  position: sticky;
}

.fixed-top {
  box-shadow: 4px 3px 5px 0px rgba(0, 0, 0, 0.2);
  top: 0;
  z-index: 1;
}

.fixed-right {
  border-left: 1px solid #c6c6c6;
  box-shadow: -5px 0px 5px 0px rgba(0, 0, 0, 0.2);
  padding-left: 1rem;
  right: 0;
  z-index: 1;
}

.fixed-top.fixed-right {
  box-shadow: 4px 3px 5px 0px rgba(0, 0, 0, 0.2),
    -5px 0px 5px 0px rgba(0, 0, 0, 0.2);
  z-index: 2;
}
<main>
      <table>
        <thead>
          <tr>
            <th class="fixed fixed-top">Nome</th>
            <th class="fixed fixed-top">Idade</th>
            <th class="fixed fixed-top">Cidade</th>
            <th class="fixed fixed-top">Estado</th>
            <th class="fixed fixed-top">País</th>
            <th class="fixed fixed-top fixed-right">Linguagem Favorita</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>João da Silva Marques</td>
            <td>15 anos</td>
            <td>São Valentin</td>
            <td>SP</td>
            <td>Brasil</td>
            <td class="fixed fixed-right">Kotlin</td>
          </tr>
          <tr>
            <td>Maria Bernardino de Campos</td>
            <td>35 anos</td>
            <td>Honolulu</td>
            <td>Havaí</td>
            <td>Estados Unidos</td>
            <td class="fixed fixed-right">Swift</td>
          </tr>
          <tr>
            <td>Beatriz Camargo de Albuquerque</td>
            <td>42 anos</td>
            <td>Rio do Sul</td>
            <td>SC</td>
            <td>Brasil</td>
            <td class="fixed fixed-right">JavaScript</td>
          </tr>
          <tr>
            <td>Marquinho Gomes da Silva</td>
            <td>17 anos</td>
            <td>Manaus</td>
            <td>AM</td>
            <td>Brasil</td>
            <td class="fixed fixed-right">Python</td>
          </tr>
        </tbody>
      </table>
    </main>

  • 1

    I was even working out a response based on in this text, but the fact that you apply position: sticky in the cells and not in the line it got in the way a little. As I’m running out of time, I gave up trying to solve it. : D But maybe the linked article will give you a direction. :-)

  • Thanks, I’ll give a read. I think, regarding the header, I applied to the cells and not the line because it was giving some problem when I tried. However, as far as I can see, to fix the last column would have to be in the same cells...

  • 1

    The problem of applying in the cell is that you will have to apply the observer N times, being N the number of cells, which can bring performance problems (or not, who knows). Another option is to try using the parentElement, applying the observer only in the first cell - or something like.

  • 2

    I even played with CSS here and it was almost... https://imgur.com/QNIMCuq but I’ll let you try... With JS vc you can try with the Intersection Observer it is sometimes the right https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.