The Power of CSS

@una

Filters & Blend Modes

"A Turing Complete system means a system in which a program can be written that will find an answer to any computational problem"

See the Pen CSS Only Accordion: youmightnotneedjs.com by Una Kravets (@una) on CodePen.

HTML

<div class="togglebox">
  <input id="toggle1" type="checkbox" name="toggle" />
  <label for="toggle1">Label 1</label>
  <section id="content1">
    <p>Content for the first accordion</p>
  </section>
  <input id="toggle2" type="checkbox" name="toggle" />
  <label for="toggle2">Label 2</label>
  <section id="content2">
    <p>Content for the second accordion</p>
  </section>
  <input id="toggle3" type="checkbox" name="toggle" />
  <label for="toggle3">Label 3</label>
  <section id="content3">
    <p>Content for the third accordion</p>
  </section>
</div>

CSS

// Visually hide checkbox buttons
input[type="checkbox"] {
  position: absolute;
  opacity: 0;
}
            
// Accordion section content gets hidden
section {
  height: 0;
  overflow: hidden;
  will-change: height; 
}

// Open content when clicking label
input[type="checkbox"]:checked ~ section {
  // Can also set height to auto, no transition
  height: 200px;
}

See the Pen CSS-Only Tabs: youmightnotneedjs.com by Una Kravets (@una) on CodePen.

HTML

<div class="tabs">
   <div class="tab">
       <input type="radio" name="tabgroup" id="tab-1" checked>
       <label for="tab-1">Label One</label>
       <div class="content">
          <p>Tab One Content</p>
       </div>
   </div>
   <div class="tab">
       <input type="radio" name="tabgroup" id="tab-2">
       <label for="tab-2">Label Two</label>
       <div class="content">
           <p>Tab Two Content</p>
       </div>
   </div>
    <div class="tab">
       <input type="radio" name="tabgroup" id="tab-3">
       <label for="tab-3">Label Three</label>
       <div class="content">
           <p>Tab Three Content</p>
       </div>
   </div>
</div>

CSS

// Tab container
.tabs {
  position: relative;
  height: 200px;
}

// Style tab itself to not have radio circle
.tab [type=radio] {
  position: absolute;
  clip: rect(0,0,0,0);

  &:focus + label {
    outline: 2px dotted #000;
  }
}

// Style content position to layer
.content {
  position: absolute;
  top: 2em; left: 0; right: 0; bottom:
}

// Label visual change
[type=radio]:checked ~ label {
  background: lightpink;
}

[type=radio]:checked ~ label ~ .content {
  z-index: 1;
}

See the Pen CSS Only Lightbox: youmightnotneedjs.com by Una Kravets (@una) on CodePen.

HTML

<!-- thumbnail image wrapped in a link -->
<a href="#img1">
  <img src="img.jpg" class="thumbnail">
</a>

<!-- lightbox container hidden with CSS -->
<a href="#" class="lightbox" id="img1">
  <img src="img.jpg">
</a>

CSS

//thumbnail style
.thumbnail {
  max-width: $thumbnail-size;
}

.lightbox {
  // Position/style of lightbox
  position: fixed;
  z-index: 10;
  width: 100%;
  height: 100%;
  text-align: center;
  top: 0; left: 0;
  background: darkgray;

  // Hide lightbox image
  display: none;
}

.lightbox img {
  /// Pad the lightbox image
  max-width: 90%;
  max-height: 80%;
  margin-top: 2%;
}

.lightbox:target {
  // Show lightbox on target
  display: block;
}

See the Pen CSS-Only Modal: youmightnotneedjs.com by Una Kravets (@una) on CodePen.

HTML

<a class="modalTrigger" id="modalTrigger"
   href="#modalDialog1">Open dialog</a>

<dialog class="modal" id="modalDialog1"
tabindex="-1" role="dialog">
  <div>
    <a href="#modalTrigger" aria-label="Close">
      &times;
      </a>
      <p>Hello Beautiful!</p>
  </div>
</dialog>

CSS

// Modal hidden until it matches an anchor target
.modal {
  opacity: 0;
  visibility: hidden;
}

#modalDialog:target {
  opacity: 1;
  visibility: visible;
}

See the Pen CSS Tooltips: youmightnotneedjs.com by Una Kravets (@una) on CodePen.

HTML

<span class="tooltip"
            data-tip="I am a tooltip"
            tabindex="0">tooltip text</span>

CSS

.tooltip {
  position: relative;
  cursor: help;
  border-bottom: 2px dotted #c69;

  &::before,
  &::after {
    position: absolute;
    left: 50%;
    opacity: 0;
    z-index: 0;
    transition: opacity .5s;
    color: white;
  }

  &:hover::before, &:focus::before,
  &:hover::after, &:focus::after {
    opacity: 1;
    z-index: 10;
  }

  /* tooltip balloon */
  &::before {
    background: #c69;
    bottom: 185%;
    width: 14em;
    padding: 0.5em;
    margin-left: -8em;
    content: attr(data-tip);
  }

  /* triangle part overflow: hidden; tooltip */
  &::after {
    content: "";
    border-style: solid;
    border-width: 1em .75em 0 .75em;
    border-color: #c69 transparent transparent transparent;
    bottom: 100%;
    margin-left: -1em;
  }
}

See the Pen CSS Only Scroll Indicator: youmightnotneedjs.com by Una Kravets (@una) on CodePen.

HTML

<body>
content must be longer than 100vh
</main>
</body>

CSS

body {
  background: linear-gradient(to right top,
  $scroller-color 50%,
  $scroller-background 50%);
  background-size: 100%
              calc(100% - 100vh + #{$scroller-height});
  background-repeat: no-repeat;
}

body:before {
  content:'';
  position: fixed;
  top: $scroller-height;
  bottom: 0;
  width: 100%;
  z-index: -1;
  background: $body-background;
}

@supports

Hello World

Other Content Here

This presentation is made
entirely in HTML + CSS

Keyboard Navgation

<a accesskey="slide1" title="Slide 1"></a>
  Mac:                 alt + ctrl + {key}
  PC Chrome/Safari/IE: alt + {key}
  PC FireFox:          alt + shift + {key}
  

Live Code Editing

The real power of CSS is that it creates a common language for designers and developers.

CSS is Awesome

Thank You | una.im/power-of-css

People Who Inspired This/Me

Projects Mentioned

Resources

Tools