Google IO 2023

New in Web

Baseline

Web Platform Baseline gives you clear information about which web platform features are safe to use in your projects today.

Features become part of Baseline when they are supported in the current and previous version of all major browsers—Chrome, Edge, Firefox, and Safari. 

  • The dialog element
  • Individual CSS transform properties
  • New viewport units
  • Deep copy in JavaScript
  • The :focus-visible pseudo-class
  • The TransformStream interface
  • Import ES modules

Baseline features

The dialog element

Individual CSS transform properties

.target {
  translate: 50% 0;
  rotate: 30deg;
  scale: 1.2;
  /* transform: translate (50%,0) rotate(30deg) scale(1.2); */
}

New viewport units

To size something as tall as the viewport, you can use the vw and vh units.

  • vw = 1% of the width of the viewport size.
  • vh = 1% of the height of the viewport size.

Give an element a width of 100vw and a height of 100vh, and it will cover the viewport entirely.

Additional units: vi,vb,vmin,vmax

  • Large viewport: The viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be retracted.
  • Small Viewport: The viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be expanded.
  • Units representing the large viewport have the lv prefix. The units are lvw, lvh, lvi, lvb, lvmin, and lvmax.
  • Units representing the small viewport have the sv prefix. The units are svw, svh, svi, svb, svmin, and svmax.

Its accompanied units have the dv prefix: dvw, dvh, dvi, dvb, dvmin, and dvmax.

Deep copy in JavaScript

const original = {id: 0, prop: {name: "Tom"}}

/* Old hack */
const deepCopy = JSON.parse(JSON.stringify(original));

/* New way */
const deepCopy = structuredClone(original);

The :focus-visible pseudo-class

/* focus with tab key */
:focus-visible {
    outline: 5px solid pink;
}

/* mouse click */
:focus:not(:focus-visible) {
    outline: none;
}

The TransformStream interface

The TransformStream interface of the Streams API makes it possible to pipe streams into one another.

Import ES modules

<script type="importmap">
    {
        "imports": {
            "lodash": "https://unpkg.com/[email protected]/lodash.js",
            "utils": "./modules/utils.js"
        }
    }
</script>

<script type="module">
    import _ from 'lodash';
    console.log(_.map([1,2,3], (n) => n * 2));
</script>

New in web animations

Showcase

Simple customization

Transitioning multiple elements

Handling changes in aspect ratio

CSS only

@keyframes fade-in {
  from { opacity: 0; }
}
@keyframes fade-out {
  to { opacity: 0; }
}
@keyframes slide-from-right {
  from { transform: translateX(30px); }
}
@keyframes slide-to-left {
  to { transform: translateX(-30px); }
}
::view-transition-old(root) {
  animation: 90ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
    300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
}
::view-transition-new(root) {
  animation: 210ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
    300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
}

Animating with JavaScript

let lastClick;
addEventListener('click', event => (lastClick = event));

function spaNavigate(data) {
  // Fallback for browsers that don't support this API:
  if (!document.startViewTransition) {
    updateTheDOMSomehow(data);
    return;
  }

  // Get the click position, or fallback to the middle of the screen
  const x = lastClick?.clientX ?? innerWidth / 2;
  const y = lastClick?.clientY ?? innerHeight / 2;
  // Get the distance to the furthest corner
  const endRadius = Math.hypot(
    Math.max(x, innerWidth - x),
    Math.max(y, innerHeight - y)
  );

  // With a transition:
  const transition = document.startViewTransition(() => {
    updateTheDOMSomehow(data);
  });

  // Wait for the pseudo-elements to be created:
  transition.ready.then(() => {
    // Animate the root's new view
    document.documentElement.animate(
      {
        clipPath: [
          `circle(0 at ${x}px ${y}px)`,
          `circle(${endRadius}px at ${x}px ${y}px)`,
        ],
      },
      {
        duration: 500,
        easing: 'ease-in',
        // Specify which pseudo-element to animate
        pseudoElement: '::view-transition-new(root)',
      }
    );
  });
}

Preparing for the end of third-party cookies

First-Party Sets (FPS) is a way for a company to declare relationships among sites, so that browsers allow limited third-party cookie access for specific purposes.

First-Party Sets

First-Party Sets

// primary.com/.well-known/first-party-set.json
{
  "primary": "https://primary.com",
  "associatedSites": ["https://associate1.com", "https://associate2.com", "https://associate3.com"]
}
// associate1.com/.well-known/first-party-set.json
{
  "primary":"https://primary.com"
}

Allow developers to opt-in a cookie to "partitioned" storage, with a separate cookie jar per top-level site.

Cookies Having Independent Partitioned State (CHIPS)

Why do we need it

Set-Cookie: __Host-example=34d8g; SameSite=None; Secure; Path=/; Partitioned;

Advanced web APIs in real world apps

Project Fugu

Thank You!

Questions?