Who is this guy?

Plenty got #moreawesome

css

#moreawesome

media

#moreawesome

Legend

Specification link

HTML5Rocks content

Old, broke, & busted way of doing something

New hotness way of doing it

No longer need JavaScript to achieve the same effect

Performance tip

css

#moreawesome

media

#moreawesome

Don't need JS?

Viewport-percentage units

vw, vh, vmin, vmax

The size of rem/em units are dependent on parent elements

The size of viewport units are based purely on viewport size!

Value is equal to 1% (1/100th) of width/height:

1vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = min(1vw, 1vh)
1vmax = max(1vw, 1vh)
Need fewer @media query breakpoints for adjusting sizes

no need for JS to determine viewport size

no need for JS resize handlers to make adjustments

Example

viewport: 1000 x 700px

h1 {
  font-size: 4vw; /* 4 × 1000px * 0.01 = 40px */
}
div {
  width: 15vmin; /* 15 * 700px * 0.01 = 105px */
}

Viewport units

browser support

Intrinsic sizing

.red-div {
  display: flex;
  justify-content: center;
  align-items: center;
  width: ;  /* vendor prefixed */
  height: ; /* vendor prefixed */
}
Hello World

Intrinsic sizing

browser support

CSS Variables

Made commonplace by CSS preprocessors.

body {
  var-fontColor: red;
  color: var(fontColor);
}
  • Custom property concepts

    1. Define variable name prefixed with "var-". Use by passing it to var()
    2. Names are case-sensitive
    3. Scoped to the rule they're defined in but cascade to children
    4. Allows fallback values: color:var(fontColor, blue);

Example

:root { /* "global variables" */
  var-textColor: yellow;
  var-backgroundColor: pink;
}
footer {
  var-backgroundColor: black;
  background-color: var(backgroundColor); /* black */
  color: var(textColor); /* inherited yellow */
}
footer > span {
  var-textColor: white;
  color: var(textColor); /* white */
  background-color: var(backgroundColor); /* inherited black */
}
I am yellow text and white span on a black background

CSS Variables

browser support

chromestatus.com

CSS feature detection...in CSS!

Native CSS feature detection using @supports at-rule

@supports (display: flex) {
  body {
    display: flex;
  }
}
  • Browsers that don't understand @supports ignore the block
  • Keywords for complex testing: not, and, or

Provide alternate styling when feature isn't available:

@supports not (display: flex) {
  body { /* alternative layout using floats/columns/grid */ }
}

CSS feature detection in JS

  • CSS.supports() provides CSS feature detection in JS
  • Returns true if the UA supports the property and the value would be parsed successfully as a supported value
if (!window.CSS.supports('width', 'calc(50% - 10px)')) {
  // Calculate element's width in JS.
}

or as a conditional string:

window.CSS.supports('(width: calc(50% - 10px)) and (display: flex)');

native replacement for Modernizr

@supports

browser support

The Internet is littered with examples...

All achieved with JS scroll handlers

<style>
  .fixed { position: fixed; top: 0; width: 100%; }
</style>
<p style="margin-bottom:100px;">Scroll this page.</p>
<div class="sticky"><h3>Super amazing header</h3></div>
<script>
var sticky = document.querySelector('.sticky');
var origOffsetY = sticky.offsetTop;
document.addEventListener('scroll', function(e) {
  window.scrollY >= origOffsetY ? sticky.classList.add('fixed') :
                                  sticky.classList.remove('fixed')
});
</script>

Examples: Google News (left nav), Yelp (map results), TechCrunch (header)

Sticky positioned elements

position: sticky

.sticky {
  position: sticky;
  top: 10px; /* When the element reaches top: 10px, it becomes fixed. */
  z-index: 100;
}

Behavior:

  1. Element(s) is initially position: relative in their parent
  2. Parent scrolls partially outside of viewport: element → position: fixed
  3. Parent scrolls fully outside of viewport: element scrolls with

eliminate JS scroll handlers to achieve this effect!

position: sticky

browser support

Clipping DOM elements

img, div {
  position: absolute;
  clip: rect(97px, 250px, 340px, 65px);
}

CSS clip:

Only supports rect()

DOM element needs to be position:absolute

Clip path

CSS clip-path removes the position:absolute restriction

Use any basic shape from SVG or reference complex <clipPath> element

div {
  clip-path: circle(50%, 50%, 50px);
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam magna justo, viverra in volutpat quis, tristique non eros. Duis dignissim congue ligula a posuere. Sed lorem odio, dictum at cursus sed, semper in nisl. Sed eu porta sapien. Integer sagittis nisl imperdiet mi luctus sodales. Phasellus quis scelerisque nulla. Curabitur ornare purus at quam placerat suscipit. Nunc fermentum luctus tortor quis cursus. Nullam enim velit, sodales at ullamcorper in, convallis non nisl. Nulla enim leo, ullamcorper quis convallis ac, mollis nec lorem. Nulla volutpat pulvinar sapien ac consequat. Etiam molestie, risus consectetur faucibus lobortis, metus lectus ultrices erat, at ultrices enim libero a metus.
  • Do
  • Re
  • Mi
  • Fa
  • So
  • La
  • Ti
  • Do

Referencing a <clipPath>

<style>
  img, div {
     clip-path: url(#myClip);
  }
</style>

<img src="images/background-home.jpg">
<div>...</div>

<svg width="0" height="0" hidden>
  <defs>
    <clipPath id="myClip">
      <circle cx="150" cy="150" r="100"/>
      <circle cx="70" cy="70" r="20"/>
      ...
    </clipPath>
  </defs>
</svg>

clip-path

browser support

css

#moreawesome

media

#moreawesome

Screen sharing

Enable screen capture support in getUserMedia() in about:flags

navigator.getUserMedia({
  video: {
    mandatory: {
      chromeMediaSource: 'screen'
      // maxWidth: 640, maxHeight: 480
    }
  }
}, onStream, onError);
  • Page needs to be on HTTPS (for now).
  • Permission prompt is not sticky (for now).
  • Combining with WebRTC DataChannel API yields interesting use cases: remote desktop assistance, "browser the web together".

Demo

WebRTC screen sharing

browser support

Live microphone input

Web Audio API

navigator.getUserMedia({audio: true}, function(stream) {
  var audioCtx = new window.AudioContext();

  // Create an AudioNode from the stream.
  var source = audioCtx.createMediaStreamSource(stream);

  // TODO: create and connect up filter/analyser/javascript node(s) for processing.

  // Connect it to the destination to hear yourself.
  source.connect(audioCtx.destination);
}, function(e) {
  console.log(e);
});

Demos

Live input to Web Audio API

browser support

Speech-enabled web apps?

Web Speech API

Speech recognition and synthesis for web apps.

var recognizer = new speechRecognition();
recognizer.continuous = true;
recognizer.interimResults = true;
recognizer.onresult = function(e) {
  if (e.results.length) {
    var lastResultIdx = e.results.resultIndex;
    console.log(e.results[lastResultIdx][0].transcript);
  }
};
recognizer.start();
  • Continuous dictation. interim results, alternative results
  • Repeated permission prompt for pages not hosted on HTTPS.

Web Speech API

browser support

The web got way more #moreawesome

css

  • @supports, window.CSS.supports()
  • New units: intrinsic units, viewport units
  • CSS Variables
  • position: sticky

media

  • Live mic → Web Audio API
  • WebRTC screen sharing
  • Web Speech API

Things to look forward to

chromestatus.com