GitHub

Sticky

Sticky tracks when a sticky element becomes pinned so it can be styled differently.

Overview

DaffStickyTrackerDirective applies the is-pinned CSS class when a sticky element is pinned to the top or bottom of its scroll container, and removes it when the element returns to its normal position.

The directive doesn't make an element sticky. Use position: sticky in your styles to do that.

Usage

Use daffStickyTracker as an attribute selector and set sticky to the edge the element sticks to:

import { DaffStickyTrackerDirective } from '@daffodil/design';

@Component({
  selector: 'custom-component',
  template: 'custom-component.html',
  imports: [
    DaffStickyTrackerDirective,
  ],
})
export class CustomComponent { }
<div daffStickyTracker sticky="top" class="custom-header">Header</div>
Value Description
top The element sticks to the top of its scroll container.
bottom The element sticks to the bottom of its scroll container.

Styling

Use position: sticky to make the element sticky, and the applied CSS class to style the pinned state:

.custom-header {
  position: sticky;
  top: 0;

  &.is-pinned {
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
  }
}

Example

Top Sticky Example

Scroll down to see the header stick to the top...

The header below will stick to the top when you scroll past it.

Notice how its appearance changes when it becomes "pinned".

Header - Sticks to TopPinned!

Keep scrolling to see the sticky behavior...

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.

Bottom Sticky Example

Scroll down to see the footer stick to the bottom...

The footer is positioned naturally in the content below.

Continue scrolling to see it enter the viewport and then stick!











Keep scrolling down...











Almost there...











You should see the footer appear below this text:

This content appears after the footer.

When you scroll past the footer, it should stick to the bottom.











The footer should remain pinned as you scroll through this content.











Keep scrolling to test the sticky behavior...











End of content.

Top Sticky (First Element in Container)

Header - Sticks to TopPinned!

Scroll down to see the header stick to the top...

The header below will stick to the top when you scroll past it.

Notice how its appearance changes when it becomes "pinned".

Keep scrolling to see the sticky behavior...

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.

Bottom Sticky (Last Element in Container)

Scroll down to see the footer stick to the bottom...

The footer is positioned naturally in the content below.

Continue scrolling to see it enter the viewport and then stick!











Keep scrolling down...











Almost there...











You should see the footer appear below this text:

This content appears after the footer.

When you scroll past the footer, it should stick to the bottom.











The footer should remain pinned as you scroll through this content.











Keep scrolling to test the sticky behavior...











End of content.

<div class="basic-sticky">
  <div class="basic-sticky__section">
    <h3>Top Sticky Example</h3>
    <div class="basic-sticky__container">
      <div class="basic-sticky__content-before">
        <p>Scroll down to see the header stick to the top...</p>
        <p>The header below will stick to the top when you scroll past it.</p>
        <p>Notice how its appearance changes when it becomes "pinned".</p>
      </div>

      <div daffStickyTracker sticky="top" class="basic-sticky__header">
        <span class="basic-sticky__text">Header - Sticks to Top</span>
        <span class="basic-sticky__indicator">Pinned!</span>
      </div>

      <div class="basic-sticky__content-middle">
        <p>Keep scrolling to see the sticky behavior...</p>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </p>
        <p>
          Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
          nisi ut aliquip ex ea commodo consequat.
        </p>
        <p>
          Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
          dolore eu fugiat nulla pariatur.
        </p>
        <p>
          Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
          officia deserunt mollit anim id est laborum.
        </p>
        <p>
          Sed ut perspiciatis unde omnis iste natus error sit voluptatem
          accusantium doloremque laudantium.
        </p>
      </div>
    </div>
  </div>

  <div class="basic-sticky__section">
    <h3>Bottom Sticky Example</h3>
    <div class="basic-sticky__container basic-sticky__container--bottom">
      <div class="basic-sticky__spacer">
        <p>Scroll down to see the footer stick to the bottom...</p>
        <p>The footer is positioned naturally in the content below.</p>
        <p>Continue scrolling to see it enter the viewport and then stick!</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>Keep scrolling down...</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>Almost there...</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>You should see the footer appear below this text:</p>
      </div>

      <div daffStickyTracker sticky="bottom" class="basic-sticky__footer">
        <span class="basic-sticky__text">Footer - Sticks to Bottom</span>
        <span class="basic-sticky__indicator">Pinned!</span>
      </div>

      <div class="basic-sticky__spacer-after">
        <p>This content appears after the footer.</p>
        <p>When you scroll past the footer, it should stick to the bottom.</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>
          The footer should remain pinned as you scroll through this content.
        </p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>Keep scrolling to test the sticky behavior...</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>End of content.</p>
      </div>
    </div>
  </div>

  <div class="basic-sticky__section">
    <h3>Top Sticky (First Element in Container)</h3>
    <div class="basic-sticky__container">
      <div daffStickyTracker sticky="top" class="basic-sticky__header">
        <span class="basic-sticky__text">Header - Sticks to Top</span>
        <span class="basic-sticky__indicator">Pinned!</span>
      </div>
      <div class="basic-sticky__content-before">
        <p>Scroll down to see the header stick to the top...</p>
        <p>The header below will stick to the top when you scroll past it.</p>
        <p>Notice how its appearance changes when it becomes "pinned".</p>
      </div>

      <div class="basic-sticky__content-middle">
        <p>Keep scrolling to see the sticky behavior...</p>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </p>
        <p>
          Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
          nisi ut aliquip ex ea commodo consequat.
        </p>
        <p>
          Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
          dolore eu fugiat nulla pariatur.
        </p>
        <p>
          Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
          officia deserunt mollit anim id est laborum.
        </p>
        <p>
          Sed ut perspiciatis unde omnis iste natus error sit voluptatem
          accusantium doloremque laudantium.
        </p>
      </div>
    </div>
  </div>

  <div class="basic-sticky__section">
    <h3>Bottom Sticky (Last Element in Container)</h3>
    <div class="basic-sticky__container basic-sticky__container--bottom">
      <div class="basic-sticky__spacer">
        <p>Scroll down to see the footer stick to the bottom...</p>
        <p>The footer is positioned naturally in the content below.</p>
        <p>Continue scrolling to see it enter the viewport and then stick!</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>Keep scrolling down...</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>Almost there...</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>You should see the footer appear below this text:</p>
      </div>

      <div class="basic-sticky__spacer-after">
        <p>This content appears after the footer.</p>
        <p>When you scroll past the footer, it should stick to the bottom.</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>
          The footer should remain pinned as you scroll through this content.
        </p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>Keep scrolling to test the sticky behavior...</p>
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
        <p>End of content.</p>
      </div>
      <div daffStickyTracker sticky="bottom" class="basic-sticky__footer">
        <span class="basic-sticky__text">Footer - Sticks to Bottom</span>
        <span class="basic-sticky__indicator">Pinned!</span>
      </div>
    </div>
  </div>
</div>