CSS position: sticky Property Value

CSS position Property


position: stickyIs a relatively new value in CSS positioning properties.Sticky PositioningYesRelative PositioningandFixed Positioningthe hybrid: when the element crosses the specifiedThresholdBefore that it behaves like relative positioning; after that it behaves like fixed positioning.

This is a modern solution for effects such as "sticky top navigation" and "fixed table headers".

Word Definitions:stickyMeaning "sticky", indicating that the element will "stick" at a certain position.


Basic Syntax

position: stickyrequires pairing with at least one direction (top、right、bottom、left) threshold to specify where the "sticky" effect takes effect.

/* 语法 */
position: sticky;

/* 常用组合:滚动到距离顶部 10px 时固定 */
.sticky-header {
    position: sticky;
    top: 10px;
}

How it works

stickyThe way this positioning works can be broken down into two phases:

Phase 1: Normal scrolling (relative positioning)

When the element is in the viewportNot ReachedWhen the specified threshold is reached, the element is laid out according to the normal document flow,will move with page scrollingAt this point, it is equivalent toposition: relative。

Phase 2: Fixed display (fixed positioning)

When the element scrolls toExceededwhen the specified threshold is reached, the elementFixedAt that position, it no longer scrolls with the page. At this point it is equivalent toposition: fixed。

Threshold Condition

Property Trigger Condition
top: 10px fixed when the element's top is > 10px from the viewport top
bottom: 10px fixed when the element's bottom is > 10px from the viewport bottom
left: 10px Fixed when the element's left edge is > 10px from the left edge of the viewport
right: 10px Fixed when the element's right edge is > 10px from the right edge of the viewport

Core features

Feature 1: Bidirectional behavior

sticky combines the characteristics of relative and fixed, making it a perfect combination of the two.

Feature 2: No need for the parent element to have positioning set

andabsolutedifferent, sticky elementsNot Requiredthe parent element sets any positioning property.

Feature 3: Restrictions from the parent container's overflow

if the parent element setsoverflow: hidden、overflow: autooroverflow: scroll, sticky positioning may fail.

Feature 4: Activates z-index

sticky positioning will activatez-indexProperty.


Example

Let's gain a deeper understanding through examplesposition: stickyCharacteristics.

Example 1: Sticky top navigation bar

This is the most common application of sticky positioning: implementing a sticky top navigation bar.

Example

<!DOCTYPE html>
<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            font-family: Arial, sans-serif;
        }

/* Large image area at the top of the page */
        .hero {
            height: 300px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 36px;
            font-weight: bold;
        }

/* Sticky navigation bar */
        .sticky-nav {
            position: sticky;
top: 0; /* Sticky when scrolled to top */
            background-color: #2c3e50;
            color: white;
            padding: 15px 30px;
            z-index: 100;
        }

        .sticky-nav ul {
            list-style: none;
            display: flex;
            gap: 30px;
            max-width: 800px;
            margin: 0 auto;
        }

        .sticky-nav a {
            color: white;
            text-decoration: none;
        }

/* Content area */
        .content {
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }

        .section {
            margin-bottom: 40px;
            padding: 20px;
            background-color: #f5f5f5;
            border-radius: 4px;
        }

        .tall-spacer {
            height: 1500px;
        }
    </style>
</head>
<body>
    <div class="hero">
EXAMPLE Tutorial
    </div>

    <nav class="sticky-nav">
        <ul>
            <li><a href="#">Home</a></li>
            <li><a href="#">Tutorial</a></li>
            <li><a href="#">Example</a></li>
            <li><a href="#">Tools</a></li>
            <li><a href="#">About</a></li>
        </ul>
    </nav>

    <div class="content">
        <div class="section">
            <h2>Chapter 1: Getting Started</h2>
            <p>This is the content of Chapter 1. Scroll down to see the sticky effect of the navigation bar.</p>
        </div>
        <div class="section">
            <h2>Chapter 2: Intermediate</h2>
            <p>This is the content of Chapter 2.</p>
        </div>
        <div class="section">
            <h2>Chapter 3: Advanced</h2>
            <p>This is the content of Chapter 3.</p>
        </div>
        <div class="section">
            <h2>Chapter 4: Practical</h2>
            <p>This is the content of Chapter 4.</p>
        </div>
        <div class="section">
            <h2>Chapter 5: Project</h2>
            <p>This is the content of Chapter 5.</p>
        </div>
        <div class="tall-spacer"></div>
    </div>
</body>
</html>

Example 2: Fixed table header row

sticky positioning is very suitable for fixing table headers:

Example

<!DOCTYPE html>
<html>
<head>
    <style>
        .table-container {
            max-width: 600px;
            max-height: 300px;
overflow-y: auto; /* Overflow must be set to see the sticky effect */
            border: 2px solid #ddd;
        }

        table {
            width: 100%;
            border-collapse: collapse;
        }

/* Use sticky positioning for the table header */
        th {
            position: sticky;
            top: 0;
            background-color: #3498db;
            color: white;
            padding: 12px;
            text-align: left;
        }

        td {
            padding: 10px 12px;
            border-bottom: 1px solid #eee;
        }

        tr:nth-child(even) {
            background-color: #f9f9f9;
        }
    </style>
</head>
<body>
    <h2>Student Score Table</h2>
    <p>Scroll down to see the fixed table header effect:</p>

    <div class="table-container">
        <table>
            <thead>
                <tr>
                    <th>Student ID</th>
                    <th>Name</th>
                    <th>Chinese</th>
                    <th>Mathematics</th>
                    <th>English</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>001</td>
                    <td>Zhang San</td>
                    <td>85</td>
                    <td>92</td>
                    <td>88</td>
                </tr>
                <tr>
                    <td>002</td>
                    <td>Li Si</td>
                    <td>90</td>
                    <td>87</td>
                    <td>95</td>
                </tr>
                <tr>
                    <td>003</td>
                    <td>Wang Wu</td>
                    <td>78</td>
                    <td>85</td>
                    <td>82</td>
                </tr>
                <tr>
                    <td>004</td>
                    <td>Zhao Liu</td>
                    <td>92</td>
                    <td>88</td>
                    <td>90</td>
                </tr>
                <tr>
                    <td>005</td>
                    <td>Qian Qi</td>
                    <td>88</td>
                    <td>91</td>
                    <td>87</td>
                </tr>
                <tr>
                    <td>006</td>
                    <td>Sun Ba</td>
                    <td>85</td>
                    <td>89</td>
                    <td>93</td>
                </tr>
                <tr>
                    <td>007</td>
                    <td>Zhou Jiu</td>
                    <td>80</td>
                    <td>86</td>
                    <td>84</td>
                </tr>
                <tr>
                    <td>008</td>
                    <td>Wu Shi</td>
                    <td>91</td>
                    <td>93</td>
                    <td>89</td>
                </tr>
                <tr>
                    <td>009</td>
                    <td>Zheng Shiyi</td>
                    <td>87</td>
                    <td>85</td>
                    <td>88</td>
                </tr>
                <tr>
                    <td>010</td>
                    <td>Chen Shier</td>
                    <td>89</td>
                    <td>90</td>
                    <td>91</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

Example 3: Sidebar sticky effect

When page content is very long, it allows the sidebar to become fixed after scrolling to a certain position:

Example

<!DOCTYPE html>
<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: Arial, sans-serif;
        }

        .container {
            display: grid;
            grid-template-columns: 1fr 200px;
            max-width: 900px;
            margin: 0 auto;
        }

        .main-content {
            padding: 20px;
        }

/* Sticky sidebar */
        .sidebar {
            position: sticky;
top: 20px; /* Sticks at 20px from the top */
            height: fit-content;
            background-color: #3498db;
            color: white;
            padding: 15px;
            border-radius: 4px;
        }

        .content-block {
            background-color: #f5f5f5;
            padding: 20px;
            margin-bottom: 20px;
            border-radius: 4px;
        }

        .tall-block {
            height: 800px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="main-content">
            <h1>Main content area</h1>
            <p>Scroll down to see the sticky effect of the sidebar.</p>

            <div class="content-block">
                <h2>Content Area 1</h2>
                <p>This is the first paragraph of content.</p>
            </div>
            <div class="content-block">
                <h2>Content Area 2</h2>
                <p>This is the second paragraph of content.</p>
            </div>
            <div class="content-block">
                <h2>Content Area 3</h2>
                <p>This is the third paragraph of content.</p>
            </div>
            <div class="content-block tall-block">
                <h2>Long content area</h2>
                <p>This is a relatively long content area used to demonstrate the sticky effect of the sidebar.</p>
                <p>Continue scrolling down...</p>
            </div>
            <div class="content-block">
                <h2>Content Area 4</h2>
                <p>This is the content of area 4.</p>
            </div>
            <div class="content-block">
                <h2>Content Area 5</h2>
                <p>This is the content of area 5.</p>
            </div>
        </div>

        <aside class="sidebar">
            <h3>Sidebar</h3>
            <p>I will stick to the right side</p>
            <p>until scrolled out of viewport</p>
        </aside>
    </div>
</body>
</html>

Example 4: Fixed section headings

sticky positioning is very suitable for fixing segmented headings in articles:

Example

<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 0 auto;
            padding: 20px;
        }

/* Sticky section title */
        .chapter-title {
            position: sticky;
            top: 0;
            background-color: #2c3e50;
            color: white;
            padding: 15px;
            margin: 20px 0 10px;
            border-radius: 4px;
        }

        .content {
            padding: 0 15px;
            line-height: 1.8;
            margin-bottom: 30px;
        }

        .tall-content {
            height: 600px;
        }
    </style>
</head>
<body>
    <h1>Book chapter example</h1>

    <div class="chapter-title">Chapter 1: Introduction to Programming</div>
    <div class="content">
        <p>Programming is a creative art. This chapter will introduce you to what programming is and why learning programming is so important.</p>
    </div>

    <div class="chapter-title">Chapter 2: Setting Up the Environment</div>
    <div class="content tall-content">
        <p>Before we start writing code, we need to set up the development environment. This chapter describes how to install the necessary tools and configure the development environment.</p>
        <p>The content area is long enough to produce a scrolling effect.</p>
    </div>

    <div class="chapter-title">Chapter 3: Basic Syntax</div>
    <div class="content">
        <p>This chapter introduces the basic syntax of programming languages, including core concepts such as variables, data types, and operators.</p>
    </div>

    <div class="chapter-title">Chapter 4: Control Structures</div>
    <div class="content tall-content">
        <p>Control structures determine the execution order of a program. This section introduces how to use conditional statements and loop statements.</p>
    </div>

    <div class="chapter-title">Chapter 5: Functions</div>
    <div class="content">
        <p>Functions are the basic unit of organizing code. This chapter explains how to define and call functions.</p>
    </div>
</body>
</html>

Example 5: Bidirectional sticky positioning

You can set sticky positioning in both horizontal and vertical directions at the same time:

Example

<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: Arial, sans-serif;
        }

        .calendar {
            width: 350px;
            border: 2px solid #ddd;
        }

/* Weekday header row - sticky at top */
        .weekday {
            position: sticky;
            top: 0;
            background-color: #3498db;
            color: white;
            padding: 10px;
            text-align: center;
        }

/* Time column - sticky on left */
        .time-label {
            position: sticky;
            left: 0;
            background-color: #ecf0f1;
            padding: 20px 10px;
            border-right: 1px solid #ddd;
            font-weight: bold;
        }

/* Date cell */
        .day-cell {
            padding: 20px;
            border: 1px solid #eee;
            text-align: center;
        }

        .day-cell:nth-child(2) {
            position: sticky;
left: 50px; /* time column width + border */
            background-color: white;
        }

/* Simulated calendar grid */
        .calendar-grid {
            display: grid;
            grid-template-columns: 50px repeat(5, 1fr);
        }
    </style>
</head>
<body>
    <h2>Schedule (two-way sticky)</h2>
    <p>Scroll down and right to see the effect:</p>

    <div class="calendar">
        <div class="calendar-grid">
            <!-- Weekday header row -->
            <div></div>  <!-- Time column blank -->
            <div class="weekday">Monday</div>
            <div class="weekday">Tuesday</div>
            <div class="weekday">Wednesday</div>
            <div class="weekday">Thursday</div>
            <div class="weekday">Friday</div>

            <!-- Time row 1 -->
            <div class="time-label">8:00</div>
            <div class="day-cell">Mathematics</div>
            <div class="day-cell">Chinese</div>
            <div class="day-cell">English</div>
            <div class="day-cell">Physics</div>
            <div class="day-cell">Chemistry</div>

            <!-- Time row 2 -->
            <div class="time-label">9:00</div>
            <div class="day-cell">English</div>
            <div class="day-cell">Mathematics</div>
            <div class="day-cell">Chemistry</div>
            <div class="day-cell">Chinese</div>
            <div class="day-cell">Physics</div>

            <!-- Time row 3 -->
            <div class="time-label">10:00</div>
            <div class="day-cell">Physics</div>
            <div class="day-cell">Chemistry</div>
            <div class="day-cell">Mathematics</div>
            <div class="day-cell">English</div>
            <div class="day-cell">Chinese</div>

            <!-- Time row 4 -->
            <div class="time-label">11:00</div>
            <div class="day-cell">Chinese</div>
            <div class="day-cell">Physics</div>
            <div class="day-cell">Mathematics</div>
            <div class="day-cell">Chemistry</div>
            <div class="day-cell">English</div>
        </div>
    </div>
</body>
</html>

Notes

Browser compatibility:position: stickyIt is well supported in modern browsers, but completely unsupported in IE. If IE support is needed, JavaScript or other polyfill solutions must be used as a fallback.

Effect of parent element's overflow

If the parent element has any of the following properties set, sticky positioning willFails:

overflow: hidden
overflow: auto
overflow: scroll

The threshold must be set

At least need to settop、right、bottomorleftina, otherwise sticky will not take effect (the element will be laid out according to normal document flow).

Threshold calculation

the threshold for sticky positioning isRelative to the viewportcalculated, not the parent element.


Comparison with other positioning values

position value Whether it is taken out of the document flow Fixing condition Compatibility
static no None All browsers
relative no None All browsers
absolute Yes None All browsers
fixed Yes Always fixed All browsers
sticky No before threshold, yes after threshold Scroll exceeds the threshold Modern browsers (IE not supported)

Common application scenarios

Scenario 1: Sticky top navigation

.nav {
    position: sticky;
    top: 0;
}

Scenario 2: Fixed table header

th {
    position: sticky;
    top: 0;
}

Scenario 3: Fixed sidebar

.sidebar {
    position: sticky;
    top: 20px;
}

Scenario 4: Article section titles

.chapter-header {
    position: sticky;
    top: 0;
    background: white;  /* 固定时显示背景 */
}

Summary

position: stickyIs a very practical technique in modern web layout:

  • YesRelative PositioningandFixed Positioninga combination of
  • You need to set a threshold in at least one direction (top/right/bottom/left)
  • Before scrolling past the threshold: follow normal document flow layout (relative positioning)
  • After scrolling past the threshold: fixed at the current position (fixed positioning)
  • No need for the parent element to set any positioning
  • Setting overflow on the parent element will cause sticky to fail
  • Well supported in modern browsers, not supported in IE
  • Commonly used for sticky top navigation, fixed table headers, fixed sidebars, and fixed segmented headings

CSS position Property

other extensions