Wait!

Web could do that!?

Prashant Palikhe (@prashantpalikhe)  - FrontMen

CSS

@support

Stage 4 - CR- 93%

@supports (display: flex) {
    div {
        display: flex;
    }
}
@supports not (display: flex) {
    div {
        float: right;
    }
}
@supports (--foo: green) {
    div {
        color: var(--foo);
    }
}
@supports (display: table-cell) and (display: list-item)
    


}
CSS.supports("display", "flex");
CSS.supports("display: flex");

:focus-within

Stage 4 - WD - 69%

input:focus {
    border: 1px solid black;
}

input:focus {
    border: 1px solid black;
}

.parent:focus-within {
    background-color: lightgray;
}

font-display

Unoff - 53%

@font-face {
  font-family: SomeFont;
  src: url(/path/to/some/font.woff2) format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: SomeFont;
  src: url(/path/to/some/font.woff2) format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: SomeFont;
  src: url(/path/to/some/font.woff2) format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: optional;
}

--custom-properties

Stage 4 - CR - 76%

:root {
    --base-color: #fff;
    --base-spacing: 1rem;
}
:root {
    --base-color: #fff;
    --base-spacing: 1rem;
}

.app {
    background-color: var(--base-color);
    padding: calc(var(--base-spacing) * 2);
}

document.documentElement.style.setProperty('--base-spacing', '12px');

object-fit: cover

Stage 4 - CR- 90%

.img {
    width: 200px;
    height: 250px;

}
.img {
    width: 200px;
    height: 250px;
    object-fit: cover;
}

pointer-events: none

Stage 5 - REC- 94%

.cant-click-this {
    pointer-events: none;
}
.click-this {
    pointer-events: auto;
}

will-change: transform

Stage 3 - WD- 86%

.backdrop {

    opacity: 0;
    transition: opacity 0.2s ease;
}

.backdrop.is-animating {
    opacity: 1;
}
.backdrop {
    will-change: opacity;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.backdrop.is-animating {
    opacity: 1;
}

HTML

[rel="noopener"]

<a href="http://some-website.com" target="_blank">Open link</a>

one.com

two.com

href="two.com"  target="_blank"

window.opener

.location

window object of one.com

.href = "malicious-clone-of-one.com"

rel="noopener"

[rel="preconnect"]

64%

Eagerly connect to a domain

<link href="https://some-domain.com" rel="preconnect" crossorigin />
<html>
<head>
    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">

    <style>
        p {
            font-family: Roboto;
        }
    </style>
</head>
<body>
    <p>Hello world!</p>
</body>
</html>
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  src: local('Roboto'), local('Roboto-Regular'),     
      url(https://fonts.gstatic.com/s/roboto/v16/font.woff2) format('woff2');
}
<html>
<head>
    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">

    <style>
        p {
            font-family: Roboto;
        }
    </style>
</head>
<body>
    <p>Hello world!</p>
</body>
</html>
<html>
<head>
    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
    <link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
    <style>
        p {
            font-family: Roboto;
        }
    </style>
</head>
<body>
    <p>Hello world!</p>
</body>
</html>

[rel="preload"]

57%

<link href="/some-font-file" rel="preload" as="font" type="font/woff2" crossorigin="anonymous">
<html>
<head>
    <link rel="stylesheet" href="./style1.css">

    <script src="./script1.js"></script>
</head>
<body>
    <div>Some div with HERO image</div>
</body>
</html>
<html>
<head>
    <link rel="stylesheet" href="./style1.css">

    <script async src="./script1.js"></script>
</head>
<body>
    <div>Some div with HERO image</div>
</body>
</html>
<html>
<head>
    <link rel="stylesheet" href="./style1.css" />
    <link rel="preload" href="http://lorempixel.com/1200/800/sports/" as="image" />
    <script async src="./script1.js"></script>
</head>
<body>
    <div>Some div with HERO image</div>
</body>
</html>

JavaScript

Bind once

element.addEventListener('click', function onClick() {
    
}, false);
element.addEventListener('click', function onClick() {
    element.removeEventListener('click', onClick);
}, false);
element.addEventListener('click', function onClick() {
    element.removeEventListener('click', onClick);
}, {once: true});
element.addEventListener('click', function onClick() {

}, {once: true});

Intersection observer

58%

Detect when elements enter the viewport

or any other containing element

const observer = new IntersectionObserver();
const observer = new IntersectionObserver(onChange);
const observer = new IntersectionObserver(onChange);

function onChange(changes) {
	




}

const observer = new IntersectionObserver(onChange);

function onChange(changes) {
	




}

const imgs = [ ...document.querySelectorAll('.lazy') ]; // <img class="lazy" data-src="image.jpeg" src="" />
const observer = new IntersectionObserver(onChange);

function onChange(changes) {

	



}

const imgs = [ ...document.querySelectorAll('.lazy') ]; // <img class="lazy" data-src="image.jpeg" src="" />

imgs.forEach(img => observer.observe(img));
const observer = new IntersectionObserver(onChange);

function onChange(changes) {
	changes.forEach(change => {
	    change.target.src = change.target.dataset.src;


  	});
}

const imgs = [ ...document.querySelectorAll('.lazy') ]; // <img class="lazy" data-src="image.jpeg" src="" />

imgs.forEach(img => observer.observe(img));
const observer = new IntersectionObserver(onChange);

function onChange(changes) {
	changes.forEach(change => {
	    change.target.src = change.target.dataset.src;

	    observer.unobserve(change.target);
  	});
}

const imgs = [ ...document.querySelectorAll('.lazy') ]; // <img class="lazy" data-src="image.jpeg" src="" />

imgs.forEach(img => observer.observe(img));

requestIdleCallback()

59%

Do stuff during idle time

Input

rAF

Recalc styles

Layout

Paint

Composite

Ship frame

rIC

rIC

Vsync

Vsync

window.requestIdleCallback(function () {
   









});
window.requestIdleCallback(function sendLogs(deadline) {
    while (deadline.timeRemaining() > 0 && logs.length > 0) {
        const log = logs.pop();

        sendLog(log);
    }





});
window.requestIdleCallback(function sendLogs() {
    sendLogs(logs);    









});
window.requestIdleCallback(function sendLogs(deadline) {
    while (deadline.timeRemaining() > 0 && logs.length > 0) {
        const log = logs.pop();

        sendLog(log);
    }


    if (logs.length > 0) {
        requestIdleCallback(sendLogs);
    }
});

Orientation

92%

Info about physical orientation of the device

window.addEventListener('deviceorientation', (event) => {




    
});
window.addEventListener('deviceorientation', (event) => {
    if (isDisplayDown) {
        video.pause();
    } else {
        video.play();
    }
});
window.addEventListener('deviceorientation', (event) => {
    if (event.alpha === 0 && event.beta === 180 && event.gamma === 0) {
        video.pause();
    } else {
        video.play();
    }
});

DevTools

Staying on the bleeding edge

chrome://flags

Developer Tools Experiment

6 x Shift for some extra bleeding edge

Network

Block URLs

Replay XHRs

✨Network Overrides

Editor

Debugger & Console APIs

NodeJS debugging

Real-time monitoring

Thanks! 

Web could do that!? - UpFront

By Prashant Palikhe

Web could do that!? - UpFront

  • 988