Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <body class="background">
  <main>
    <h1>Scrolling Gradient</h1>

    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi error
      fugit in inventore minus reiciendis repellendus temporibus vitae
      voluptas, voluptate! Asperiores cum enim esse fuga hic quos rem
      repudiandae vel?
    </p>

    <p>
      Aliquam aut autem, culpa deserunt eligendi, facere fugit harum illum
      ipsa ipsum laboriosam magnam odit quaerat quos repudiandae, tempore
      ullam? Facilis magni nam neque nobis perspiciatis quos sit tempore
      veritatis?
    </p>

    <p>
      Accusamus asperiores earum illo illum itaque, necessitatibus nemo nihil
      praesentium quia quod sed sunt vitae. Ab aperiam nemo quo sed suscipit.
      Aliquid animi deleniti ex quod reiciendis sed tempora voluptatibus!
    </p>

    <p>
      Asperiores autem dolorum error, excepturi ipsam, iure magni nihil nobis
      nostrum nulla obcaecati odio porro qui, sapiente suscipit tempore vitae?
      Accusamus adipisci aliquam delectus earum eius facere ipsam officia
      provident.
    </p>

    <p>
      At blanditiis, cum delectus et facere fugit libero. Amet eaque est
      maxime minima odio perferendis? A culpa deleniti dicta, dolorum illo
      inventore modi nihil nisi, pariatur porro quasi quibusdam, quidem?
    </p>

    <p>
      Ad aut cumque dolorem expedita iusto mollitia perferendis repellendus.
      Aperiam aut consequatur deserunt dignissimos fugiat harum ipsum
      laboriosam laudantium libero odio possimus praesentium quo repellendus
      sed, veritatis vero voluptates voluptatibus!
    </p>

    <p>
      Harum ipsam molestiae quibusdam repudiandae ullam! Cupiditate est
      excepturi illo nihil reiciendis voluptatum! Aperiam blanditiis deleniti
      fugiat illo in quidem sed? Accusantium beatae consequuntur delectus
      error esse excepturi maxime nulla?
    </p>

    <p>
      Beatae consequuntur culpa delectus dignissimos harum iure quasi rerum
      tempora! Commodi exercitationem fugiat illum nobis optio sapiente! Aut
      dolor, eius error et ipsam labore nesciunt, nisi odit omnis, quas quasi.
    </p>

    <p>
      At blanditiis consequatur cumque, dolorum et facilis illum magni minima
      molestias omnis, pariatur quibusdam, quidem quisquam recusandae
      similique sint vero voluptates voluptatibus? Architecto aspernatur,
      officiis. Aperiam corporis ducimus impedit sequi.
    </p>

    <p>
      Aliquid aperiam asperiores earum enim, error illum numquam obcaecati
      vero. Ab adipisci aliquid autem deserunt dolorem dolorum error impedit
      itaque libero nemo non praesentium quasi quis, quo sunt suscipit totam?
    </p>
  </main>

  <div id="scrollObserver"></div>
</body>
              
            
!

CSS

              
                @property --scroll-percentage {
  syntax: "<length-percentage>";
  inherits: false;
  initial-value: 0;
}

:root {
  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;
  color-scheme: light dark;
  color: rgb(255 255 255 / 87%);
  font-synthesis: none;
  text-rendering: optimizelegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  min-height: 100vh;
  margin: 0;
}

main {
  max-width: 60ch;
  margin: 0 auto;
  padding: 1rem;
  color: lightgray;
}

.background {
  background: radial-gradient(
      circle at var(--scroll-percentage) var(--scroll-percentage),
      hsl(0deg 100% 10%),
      transparent 50%
    ),
    radial-gradient(
      circle at calc(100% - var(--scroll-percentage)) var(--scroll-percentage),
      hsl(90deg 100% 10%),
      transparent 50%
    ),
    radial-gradient(
      circle at calc(100% - var(--scroll-percentage))
        calc(100% - var(--scroll-percentage)),
      hsl(180deg 100% 10%),
      transparent 50%
    ),
    radial-gradient(
      circle at var(--scroll-percentage) calc(100% - var(--scroll-percentage)),
      hsl(270deg 100% 10%),
      transparent 50%
    );
  animation: background-position-diagonal;
  animation-duration: 15s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-timing-function: cubic-bezier(0, 0.25, 1, 0.75);
}

body.scrollable {
  animation-duration: 1ms; /* Firefox requires this to apply the animation */
  animation-timeline: scroll(y root);
  animation-iteration-count: unset;
}

@keyframes background-position-diagonal {
  from {
    --scroll-percentage: 0%;
  }

  to {
    --scroll-percentage: 125%;
  }
}

              
            
!

JS

              
                import lodash from "https://esm.sh/lodash";

let className = "scrollable";
let observer = new ResizeObserver(
  lodash.debounce((entries) => {
    entries.forEach(() => {
      if (document.body.scrollHeight > window.innerHeight * 1.5) {
        document.body.classList.add(className);
      } else {
        document.body.classList.remove(className);
      }
    });
  }, 400)
);
observer.observe(document.querySelector("#scrollObserver"));

              
            
!
999px

Console