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

              
                <a id=s1 title="Section 1 Anchor" class=s></a>
<a id=s2 title="Section 2 Anchor" class=s></a>
<a id=s3 title="Section 3 Anchor" class=s></a>
<a id=s4 title="Section 4 Anchor" class=s></a>
<a id=s5 title="Section 5 Anchor" class=s></a>
<a id=s6 title="Section 6 Anchor" class=s></a>
<a id=s7 title="Section 7 Anchor" class=s></a>

<div id=progress></div>
<div id=background></div>

<nav class=prevnext role=presentation>
  <ul>
    <li class=p2><a href=#s1 accesskey=1 title="Trigger Section 1: This Page Refuses to Use Javascript"></a></li>
    <li class="p3n1 starter"><a href=#s2 accesskey=2 title="Trigger Section 2: :target Pseudo Selector"></a></li>
    <li class=p4n2><a href=#s3 accesskey=3 title="Trigger Section 3: ~ Swinton"></a></li>
    <li class=p5n3><a href=#s4 accesskey=4 title="Trigger Section 4: Getting Cray / On Fleek"></a></li>
    <li class=p6n4><a href=#s5 accesskey=5 title="Trigger Section 5: Accesskeys"></a></li>
    <li class=p7n5><a href=#s6 accesskey=6 title="Trigger Section 6: Limitations"></a></li>
    <li class=n6><a href=#s7 accesskey=7 title="Trigger Section 7: Acceptable Use Cases"></a></li>
  </ul>
</nav>

<nav class=thumbs aria-label="table of contents">
  <ul>
    <li><a href=#s1 title="Thumbnail Trigger Section 1: This Page Refuses to Use Javascript"></a></li>
    <li><a href=#s2 title="Thumbnail Trigger Section 2: :target Pseudo Selector"></a></li>
    <li><a href=#s3 title="Thumbnail Trigger Section 3: ~ Swinton"></a></li>
    <li><a href=#s4 title="Thumbnail Trigger Section 4: Getting Cray / On Fleek"></a></li>
    <li><a href=#s5 title="Thumbnail Trigger Section 5: Accesskeys"></a></li>
    <li><a href=#s6 title="Thumbnail Trigger Section 6: Limitations"></a></li>
    <li><a href=#s7 title="Thumbnail Trigger Section 7: Acceptable Use Cases"></a></li>
  </ul>
</nav>

<main role=main>
  
  <section>
    <article>
      <h1>This pen refuses to use Javascript</h1>
      <p>To navigate, you can use the prev/next buttons or the thumbnails to the right. If you prefer to get crazy, you can also use <code>accesskey</code> to jump to sections by using the following keyboard shortcuts:</p>
<pre>
Mac:          alt + ctrl + [1-7]
PC Chrome/IE: alt + [1-7]
PC FF:        alt + shift + [1-7]</pre>
<p class=right><small><a href="https://www.w3schools.com/tags/att_global_accesskey.asp" target="blank">More on accesskeys</a></small></p>
    </article>
  </section>
  
  <section>
    <article>
      <h1>:target</h1>
      <p>This interface relies on the CSS <code>:target</code> selector. An element is a “target” when its <code>id</code> is hash-referenced in the url.</p>      
      <pre>&lt;a href="http://example.com#section-1"&gt;Section 1&lt;/a&gt;</pre>      
<pre>#section-1:target { 
  display: block; 
}</pre>
      <p>In the above example, whenever the link is clicked, the content with an <code>id</code> of <code>section-1</code> will be displayed.</p>
      <p>CodePen removes the hash from the visible url, but right now you are looking at this pen with <code>#s2</code> as the target. If you were to manually add <code>#s2</code> to the end of this url and reload this pen, you will be taken to this screen instead of the first.</p>      
    </article>
  </section>
  
  <section>
    <article>
      <h1>~ Swinton</h1>
      <p>In CSS, the tilde <code>~</code> is used as the “General sibling combinator”. In English, that means “any following sibling”.</p>
<pre>.a ~ .b {
  display: none;
}</pre>
      <p>This would hide any <code>.b</code> element that comes after an <code>.a</code> and is a sibling.</p>
<pre>
&lt;div class="b"&gt;All good&lt;/div&gt;

&lt;div class="a"&gt;All good&lt;/div&gt;

&lt;div class="x"&gt;
  &lt;div class="b"&gt;Still good&lt;/div&gt;
&lt;/div&gt;

&lt;div class="b"&gt;Hidden&lt;/div&gt;
</pre>
      <p>Only the last <code>.b</code> would be hidden. The first comes before the <code>.a</code>, and the second is not a direct sibling.</p>
    </article>      
  </section>
  
  <section>
    <article>
      <h1>Getting Cray / On Fleek</h1>
      <p>By using <code>:target</code> and <code>~</code> we can do some pretty ridiculous things without touching Javascript. In this pen, we are using <code>:target</code> to trigger different state-related styles.</p>
      <p>At the top of this pen, there are <code>&lt;a&gt;</code> elements. Their only purpose is being used as targets.</p>
<pre>
&lt;a id="s1" class="s"&gt;&lt;/a&gt;
&lt;a id="s2" class="s"&gt;&lt;/a&gt;
...
</pre>
      <p>Using their <code>:target</code> state, we can then select and style anything else on the page.</p>
      <p>Moving the main content area over <code>-300%</code> to reveal this fourth section.</p>
<pre>#s4:target ~ main {
  left: -300%;
}</pre>
      <p>Changing the background color and image:</p>
<pre>#s4:target ~ #background {
  background-image: url(http://lorempixel.com/g/400/150/city/4/);
  background-color: #265273;
}</pre>
      <p>Changing the progress bar width:</p>
<pre>#s4:target ~ #progress {
  width: 50%;
}</pre>
      <p>Styling the fourth thumbnail as active:</p>
<pre>#s4:target ~ .thumbs li:nth-child(4) a {
  opacity: 1;
  width: 80px;
  height: 60px;
  box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.1);
}</pre>
      <p>Showing the appropriate previous link and making it say the right thing:</p>
<pre>#s4:target ~ .prevnext li[class*="p4"] {
  display: block;
  float: left;
}
#s4:target ~ .prevnext li[class*="p4"] a:after {
  content: "Prev";
}</pre>
      <p>Showing the appropriate next link and making it say the right thing:</p>
<pre>#s4:target ~ .prevnext li[class*="n4"] {
  display: block;
  float: right;
}
#s4:target ~ .prevnext li[class*="n4"] a:after {
  content: "Next";
}</pre>
    </article>      
  </section>
  
  <section>
    <article>
      <h1>accesskeys</h1>
      <p>Each of the next/prev navigation items link to each of these spans and have an <code>accesskey</code> attribute. This allows them to be fired using the browser’s <code>accesskey</code> plus whatever key is provided. In this case, we are using the corresponding section number.</p>
<pre>
&lt;a href="#s1" accesskey="1"&gt;&lt;/a&gt;
&lt;a href="#s2" accesskey="2"&gt;&lt;/a&gt;
...
</pre>
      <p>Each browser and operating system use different keyboard shortcuts for <code>accesskey</code>, but the support is suprisingly universal.</p>
<pre>Mac:          alt + ctrl
PC Chrome/IE: alt
PC FF:        alt + shift</pre>
      <p>To switch to the next section, you can hold down your <code>accesskey</code> combination above and then press <code>6</code>.
      <p>There’s more to read about <code>accesskey</code> on <a href="https://www.w3schools.com/tags/att_global_accesskey.asp" target="blank">w3schools</a>.</p>
    </article>      
  </section>
  
  <section>
    <article>
      <h1>Limitations</h1>
      <p>As with any “Who needs JS?” approach, there are more than a few things to consider when doing something like this.</p>

      <h2>Accessibility</h2>
      <p>Confining yourself to CSS makes any interactive experience more inaccessible. There are a handful of ways one could optimize this for screen readers more than I (hardly) have, but it would be a lot of effort for a unsatisfactory result.</p>
      <p>Additionally, since the “prev/next” links are actually new links on each section change, the <code>:focus</code> that occurs when you have tabbed into them disappears because the link is actually disappearing. You need to re-tab in every time. Blech. No one likes excess tab unless we’re talking about <a href="https://en.wikipedia.org/wiki/Tab_(soft_drink)" title="Wikipedia: Tab Soda" target="blank">the soda</a>.</p>      
      
      <h2>History</h2>
      <p>Each hashchange is going to be recorded in the browser history without some Javascript intervention. This can go either way as a pro or con. For something like this, it may be a pro.</p>
      
      <h2>Scalability</h2>
      <p>All ths content is being dumped into the DOM at once. At a certain size, this approach might not make a lot of sense. In theory, you could get around some of this with some smart selectors and <code>display: none;</code>, but depending on the complexity of your content, you may still have some load time issues. Dynamically loading content with Javascript is a often a very, very good thing.</p>
    </article>      
  </section>
  
  <section>
    <article>
      <h1>Acceptable Use Cases</h1>
      <p>There are some cases where something this inaccessible is technically ok. This could make sense in an environment where it is only being used in a visual setting such as a live presentation or internal documentation tool.</p>
      <p>Most importantly, it can be used as a way to show that CSS is very powerful, but can also be very limiting—depending on the need.</p>
      <p>If you liked this, you may enjoy more of my bogus CSS in my <a href="https://codepen.io/collection/DzxNzN/" target="blank">No JS Collection</a>.</p>
    </article>      
  </section>
  
</main>
              
            
!

CSS

              
                @import url(https://fonts.googleapis.com/css?family=Merriweather:300,300italic|Inconsolata);

$border-color: rgba(#FFF,0.1);

$mobile-w: 600px;
$large-w: 1200px;

$thumb-w: 80px;
$thumb-h: 60px;
$thumb-pad: 10px;
$s-count: 7;

main {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 100%;
  transition: left 500ms;
}

//
// each section
section {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 100%;
  margin: 0;
  opacity: 0;
  box-sizing: border-box;
  overflow: auto;
  -webkit-overflow-scrolling: touch;  
  
  &:first-child {
    opacity: 1;
  }
  
  transition: opacity 250ms ease-in-out;
  
  article {
    width: calc(90% - #{$thumb-w + $thumb-pad});
    max-width: 800px; 
    padding: 4rem 0 4rem 5%;
    color: #fff;
  } 
  
  code, pre {
    background: rgba(#000,0.5);
    border: 1px solid $border-color;
    border-radius: 4px;
    box-sizing: border-box;
  }
  
  code {
    padding: 0.25rem 0.5rem;
  }

  pre {
    padding: 1rem;
    margin: 1rem auto;
  }
}

// main nav ids
.s {
  position: absolute;
}



// 
// navigation mixin styles

@mixin active-next() {
  display: block;
  float: right;
  a:after { content: "Next"; }  
}

@mixin active-prev() {
  display: block;  
  float: left;
  a:after { content: "Prev"; }  
}

@mixin active-thumb {
  opacity: 1;
  width: $thumb-w;
  height: $thumb-h;
  box-shadow: 0px 0px 0px 1px $border-color;
}

@mixin inactive-thumb {
  opacity: 0.5;
  width: $thumb-w / 2;
  height: $thumb-h / 2;
  box-shadow: 0px 0px 0px 1px rgba(#FFF,0);
}

//
// navigation thumbs and buttons
nav {
  position: fixed;
  z-index: 1;
  width: 100%;
  user-select: none;
  
  &.thumbs {
    right: $thumb-pad;
    top: 50%;
    transform: translateY(-50%);
    width: $thumb-w + $thumb-pad;
    display: block;
        
    ul {
      margin: 0; padding: 0;
    }
    
    li {
      display: block;
      margin: 0 auto 0.5rem;
      
      &:first-child a {
        @include active-thumb();
      }
      
      a { 
        &:hover {
          opacity: 1;
        }
        @include inactive-thumb();
        margin: 0 auto;
        display: block;
        background-blend-mode: multiply;
        background-position: center;
        background-size: cover;
        border-radius: 2px;
        position: relative;
        transition: 
          height 250ms ease-in-out,
          width 250ms ease-in-out,
          opacity 250ms ease-in-out,          
          box-shadow 250ms ease-in-out;
        &:active {
          transform: translateY(1px);
        }
      }
    }
  }
  
  &.prevnext {
    left: 0;
    top: 1rem;
    ul {
      list-style: none;
      margin: 0.5rem auto;
      padding: 0;
      width: 220px;
      position: relative;
      &:after {
        content: "";
        display: table;
        clear: both;
      }
      li {
        display: none;
        width: 100px;
        &.starter {
          @include active-next();
        }
      }
      a {
        display: block;
        width: 100%;
        box-sizing: border-box;
        padding: 0.5rem 1rem;
        border-radius: 4px;
        text-align: center;
        box-shadow: 0px 0px 0px 0px $border-color;
        border: 1px solid $border-color;
        color: #FFFFFF;
        background-color: rgba(#000,0.4);
        transition: background 200ms ease-in-out 200ms,
          box-shadow 200ms ease-in-out;
        &:hover, &:active {
          background-color: rgba(#000,0.5);
        }
        &:hover {
          box-shadow: 0px -2px 0px 0px $border-color;
        }          
        &:active {
          box-shadow: 0px 0px 0px 0px $border-color;
          transform: translateY(1px);
        }
      }
    }
  }
  
  a {
    text-decoration: none;
  }
  
}


//
// slider experience on non mobile
@media (min-width: $mobile-w) {
  main {
    height: 100%;
  }
}

//
// content position on large
@media (min-width: $large-w) {
  main article {
    padding-left: 0;
    margin: 0 auto;
  }
}

//
// prevnext buttons on non mobile
@media (min-width: $mobile-w) {
  nav.prevnext {
    top: auto;
    bottom: 1rem;
  }  
}


//
// progress indicator at top of page
#progress {
  position: fixed;
  z-index: 9;  
  top: 0;
  left: 0;
  width: 0%;
  border-bottom: 12px solid rgba(#FFF,0.2);
  transition: width 1250ms linear;
}


//
// :target and other iterative styles
@for $i from 1 through $s-count {
  
  //
  // adjusting section opacity on all screens
  #s#{$i}:target ~ main section {
    opacity: 0;
    &:nth-child(#{$i}) {
      opacity: 1;
    }
  }
  
  //
  // adjusting section position on mobile screens
  @media (max-width: $mobile-w - 1) {
    #s#{$i}:target ~ main section {
      top: 50%;      
      &:nth-child(#{$i}) {
        top: 0;
      }
    }
  }
  
  //
  // adjusting left position on big screens
  @media (min-width: $mobile-w) {
    // parent shift on target
    #s#{$i}:target ~ main {
      left: -100% * ($i - 1);
    }
    // individual
    section:nth-child(#{$i}) {
      left: 100% * ($i - 1);
    }
  }  
  
  .thumbs li:nth-child(#{$i}) a {
    background-image: url(https://picsum.photos/400/150?a=#{$i}/);
    background-color: hsl($i / $s-count * 360, 50, 30);
  }
  
  #s#{$i}:target ~ #background {
    background-image: url(https://picsum.photos/400/150?a=#{$i}/);
    background-color: hsl($i / $s-count * 360, 50, 30);
  }
  
  #s#{$i}:target ~ #progress {
    width: ($i - 1) / ($s-count - 1) * 100%;    
  }
  
  #s#{$i}:target ~ .thumbs li:first-child a {
    @include inactive-thumb();
  }
  #s#{$i}:target ~ .thumbs li:nth-child(#{$i}) a {
    @include active-thumb();
  }
  #s#{$i}:target ~ .prevnext li.starter {
    display: none;
  }
  #s#{$i}:target ~ .prevnext li[class*="p#{$i}"] {
    @include active-prev();
  }
  #s#{$i}:target ~ .prevnext li[class*="n#{$i}"] {
    @include active-next();
  }
}


//
// background image
#background {
  background-image: url(https://picsum.photos/400/150?a=1/);
  background-color: hsl(1 / 5 * 360, 50, 30);  
  background-blend-mode: multiply;
  background-position: center;
  background-size: cover;
  $blur: 10px;
  filter: blur($blur);
  position: fixed;
  z-index: -1;
  transition: 
    background-image 500ms ease-in-out 500ms,
    background-color 500ms ease-in-out 1000ms;
  top: $blur * -2; right: $blur * -2; bottom: $blur * -2; left: $blur * -2;
}


//
// global non-essential styles
html, body {
  height: 100%;
  width: 100%;
  overflow: hidden;
  color: #FFF;
  font-family: Merriweather, Georgia, serif;  
  font-weight: 300;
}

pre, code {
  font-family: Inconsolata, monospace;
}

a {
  color: #EEE;
}

h1, p {
  font-weight: 300;
}
p, ul {
  line-height: 1.6;
}
.right { text-align: right; }   
              
            
!

JS

              
                
              
            
!
999px

Console