Demonstrating how you can achieve a shrinking, sticky header on scroll without Javascript. Pure CSS, baby.
A Pen by Håvard Brynjulfsen on CodePen.
| <!-- Sticky header --> | |
| <header class="header-outer"> | |
| <div class="header-inner responsive-wrapper"> | |
| <div class="header-logo"> | |
| <img src="https://assets.codepen.io/285131/acme-2.svg" /> | |
| </div> | |
| <nav class="header-navigation"> | |
| <a href="#">Home</a> | |
| <a href="#">About</a> | |
| <a href="#">Blog</a> | |
| <a href="#">Contact Us</a> | |
| <button>Menu</button> | |
| </nav> | |
| </div> | |
| </header> | |
| <!-- Content --> | |
| <main class="main"> | |
| <div class="main-content responsive-wrapper"> | |
| <article class="widget"> | |
| <h2>How does it work without JS? 🤯</h2> | |
| <p>This sticky header consists of two elements: an <strong>outer</strong> and an <strong>inner</strong> container. The outer container is taller than the inner — and the inner is centered vertically. | |
| <p>By utilizing the <code>position: sticky</code> property <strong>twice</strong>, both on the header's <strong>outer container</strong> and <strong>inner container</strong> the outer container will stick to the <code>body</code>, while the inner container will stick to the outer container.</p> | |
| <p>Note that the outer container has a negative <code>top</code> value equal to the height difference between the two containers. This causes the outer container to stick <strong>above</strong> the <code>body</code>, making the inner container stick to the "ceiling" on scroll. | |
| <p></p> | |
| </article> | |
| </div> | |
| </main> |
| // No JS 🎉 |
Demonstrating how you can achieve a shrinking, sticky header on scroll without Javascript. Pure CSS, baby.
A Pen by Håvard Brynjulfsen on CodePen.
| @import url("https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap"); | |
| *, | |
| *:after, | |
| *:before { | |
| box-sizing: border-box; | |
| } | |
| :root { | |
| --header-outer-height: 110px; | |
| --header-inner-height: 70px; | |
| --header-height-difference: calc( | |
| var(--header-outer-height) - var(--header-inner-height) | |
| ); | |
| --header-bg: #fff; | |
| } | |
| body { | |
| font-family: "DM Sans", sans-serif; | |
| background-color: #f2f5f7; | |
| line-height: 1.5; | |
| min-height: 300vh; | |
| position: relative; | |
| } | |
| .responsive-wrapper { | |
| width: 90%; | |
| max-width: 1280px; | |
| margin-left: auto; | |
| margin-right: auto; | |
| } | |
| /* Sticky header */ | |
| .header-outer { | |
| /* Make it stick */ | |
| height: var(--header-outer-height); | |
| position: sticky; | |
| top: calc( | |
| var(--header-height-difference) * -1 | |
| ); /* Multiply by -1 to get a negative value */ | |
| display: flex; | |
| align-items: center; | |
| /* Other */ | |
| background-color: var(--header-bg); | |
| box-shadow: 0 2px 10px 0 rgba(0,0,0, 0.1); | |
| } | |
| .header-inner { | |
| /* Make it stick */ | |
| height: var(--header-inner-height); | |
| position: sticky; | |
| top: 0; | |
| /* Other */ | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| } | |
| /* Styling of other elements */ | |
| .header-logo img { | |
| display: block; | |
| height: calc(var(--header-inner-height) - 30px); | |
| } | |
| .header-navigation { | |
| display: flex; | |
| flex-wrap: wrap; | |
| } | |
| .header-navigation a, | |
| .header-navigation button { | |
| font-size: 1.125rem; | |
| color: inherit; | |
| margin-left: 1.75rem; | |
| position: relative; | |
| font-weight: 500; | |
| } | |
| .header-navigation a { | |
| display: none; | |
| font-size: 1.125rem; | |
| color: inherit; | |
| text-decoration: none; | |
| } | |
| .header-navigation button { | |
| border: 0; | |
| background-color: transparent; | |
| padding: 0; | |
| } | |
| .header-navigation a:hover:after, | |
| .header-navigation button:hover:after { | |
| transform: scalex(1); | |
| } | |
| .header-navigation a:after, | |
| .header-navigation button:after { | |
| transition: 0.25s ease; | |
| content: ""; | |
| display: block; | |
| width: 100%; | |
| height: 2px; | |
| background-color: currentcolor; | |
| transform: scalex(0); | |
| position: absolute; | |
| bottom: -2px; | |
| left: 0; | |
| } | |
| .main { | |
| margin-top: 3rem; | |
| } | |
| .widget { | |
| width: 100%; | |
| max-width: 600px; | |
| border-radius: 8px; | |
| box-shadow: 0 15px 30px 0 rgba(0,0,0, 0.1); | |
| background-color: #fff; | |
| padding: 2.5rem; | |
| margin-left: auto; | |
| margin-right: auto; | |
| margin-bottom: 2rem; | |
| font-size: 1.125rem; | |
| } | |
| .widget > * + * { | |
| margin-top: 1.25em; | |
| } | |
| .widget h2 { | |
| font-size: 1.5rem; | |
| font-weight: 700; | |
| line-height: 1.25; | |
| } | |
| .widget code { | |
| display: inline-block; | |
| padding: 0.125em 0.25em; | |
| border-radius: 2px; | |
| background-color: #bee5d3; | |
| } | |
| .widget strong { | |
| font-weight: 700; | |
| } | |
| @media (min-width: 800px) { | |
| .header-navigation a { | |
| display: inline-block; | |
| } | |
| .header-navigation button { | |
| display: none; | |
| } | |
| } |