skip to Main Content

I need to create an HTML table with a sticky first column, that’s the easy part. The tricky part is, the sticky column should have a right border which would only be visible when we start scrolling horizontally. I need to implement this in my angular application.

I made the first column sticky but can’t figure out how to add a right border only when we start scrolling.

<div class="table">
  <table>
    <thead>
      <tr>
        <th class="sticky-column col">DATA1</th>
        <th class="col">DATA2</th>
        <th class="col">DATA3</th>
        <th class="col">DATA4</th>
      </tr>
    </thead>
    <tbody>
      <tr class="row">
        <td class="sticky-column data">Some values</td>
        <td class="data">Some values</td>
        <td class="data">Some values</td>
        <td class="data">Some values</td>
      </tr>
      <tr class="row">
        <td class="sticky-column data">Some values</td>
        <td class="data">Some values</td>
        <td class="data">Some values</td>
        <td class="data">Some values</td>
      </tr>
      <tr class="row">
        <td class="sticky-column data">Some values</td>
        <td class="data">Some values</td>
        <td class="data">Some values</td>
        <td class="data">Some values</td>
      </tr>
      <tr class="row">
        <td class="sticky-column data">Some values</td>
        <td class="data">Some values</td>
        <td class="data">Some values</td>
        <td class="data">Some values</td>
      </tr>
    </tbody>
  </table>
</div>
// ***** Table ***** //
.table {
  overflow-x: auto;
  h1 {
    grid-area: h;
  }
  table {
    border-collapse: collapse;
    td, th {
      background-color: #ffffff;
    }
  }
  .sort-table {
    width: 100%;
    tbody {
      border-top: 1px solid $primary-blue;
      border-bottom: 1px solid $primary-blue;
      tr + tr td {
        border-top: 1px solid $greyscale-light-grey;
      }
      td {
        padding-left: 10px !important;
        white-space: nowrap;
      }
    }
    .col {
      &:focus  {
        box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px $primary-blue;
      }
      padding: 20px 65px 20px 5px;
    }

    .row {
      padding: 20px;
      .data {
        padding: 20px;
        color: $primary-dark-blue;
      }
      &:hover {
        background-color: $primary-light-blue;
        .data {
          background-color: $primary-light-blue;
        }
      }
    }

    .sticky-column {
      position: sticky;
      left: 0;
      z-index: 2;
      border-right: 1px solid $primary-light-blue;
    }
  }
}

.hidden{
  visibility: hidden;
}

// ***** End of table ***** //

2

Answers


  1. If I understand the question correctly, you can detect the scroll event (the browser’s scroller or even a specific element’s scroller) and apply some logic to turn a flag on and off (eg, borderVisible – and for example turn it on when the "scrollY" exceeds a certain threshold) and bind this flag to your html wherein you can apply some ngStyle to do a dynamic styling. Does this answer your question?

    Login or Signup to reply.
  2. So I copied your code into a blank angular application and got it running. Since you did not provide a complete example I had to guess some things and am therefore not sure if the Solution will work out of the box for you.

    1. Add a scroll event handler to your div. In Angular:
    <div class="table" (scroll)="onTableScroll($event)" >
    
    1. In your component define a property that represents the scroll state of your table. Depending on your version that can be a signal or just a public property.
    public isTableScrolled = signal<boolean>(false);
    
    1. Handle the event in your component and set the value of the signal.
    onTableScroll(event: Event) {
        this.isTableScrolled.set((event.target as HTMLElement).scrollLeft > 0);
    }
    
    1. Add a css class to all your sticky columns based on the scroll state
    <th class="sticky-column col" [ngClass]="isTableScrolled() ? 'scrolled' : ''">DATA1</th>
    
    1. Move the border-right prop from the sticky column css class to a new scrolled class
    .scrolled {
     border-right: 1px solid $primary-light-blue;
    }
    

    Please Note that I also changed border-collapse: collapse to border-collapse: separate because otherwise the border sticks to the second column

    Here is a Stackblitz example https://stackblitz.com/edit/stackblitz-9uhybp

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search