What's new in Safari 9

I’m at­tend­ing WWDC 2015, and dur­ing the web de­vel­op­ment ses­sion, Apple’s Safari team showed off what’s new in Safari 9. It in­cludes iOS style ef­fects, such as back­drop fil­ters and scroll snap­ping with CSS, ES6 up­dates, other CSS niceties.

Backdrop fil­ters

You know the fancy dy­namic blur back­ground ef­fects that ar­rived with iOS7? Where the con­tent below” a panel would be blurred with a semi trans­par­ent mask, but the ac­tual el­e­ments in the panel would be as orig­i­nal.

Currently, the be­hav­iour can be em­u­lated with var­i­ous tech­niques. Most com­mon would be to cre­ate a copy of the con­tent in the back, add a mask, blur some area, and over­lay it on the orig­i­nal con­tent. This is te­dious — a main­te­nance night­mare — even when us­ing it for im­ages only.

So for Safari 9 (OS X and iOS), Apple has added the backdrop-filter prop­erty. It ac­cepts val­ues from the reg­u­lar CSS Filters spec­i­fi­ca­tion. should be a ap­plied to the el­e­ment you would nor­mally ap­ply a semi trans­par­ent back­ground too. You can com­bine sev­eral fil­ters, as you’d do with the filter prop­erty. This is also sub­mit­ted to be a W3C stan­dard.

// Styles for a top bar
.site-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
// Will blur and saturate any content below this top bar
// as you scroll.
backdrop-filter: blur(10px) saturate(100%);

This even works for video and other dy­namic con­tent as you scroll! But have in mind that ren­der­ing can be ex­pen­sive, to be sure to test it be­fore ship­ping.

Scroll snap points

When do­ing gal­leries, carousels, and such for touch de­vices, we’ve tra­di­tion­ally re­sorted to use Javascript to han­dle the scrolling when you want con­trol over where the scrolling should snap. Take the in iOS as an ex­am­ple: when you flip through im­ages, they’ll snap to the edge of the screen when the scroll mo­men­tum stops, in­stead of over­lap­ping. Apple has sim­pli­fied this by adding sup­port for scroll snap­ping di­rectly in CSS (for iOS and OS X).

#viewport {
// Turn it on.
-webkit-scroll-snap-type: mandatory;
// Set a snap point every 300px on the X axis.
// Use -webkit-scroll-snap-points-y for Y axis.
-webkit-scroll-snap-points-x: repeat(300px);

By us­ing the -webkit-scroll-snap-points-x and -webkit-scroll-snap-points-y prop­er­ties, we can set a re­peat­ing point with the repeat func­tion, or use a reg­u­lar value, such as:

  • per­cent­ages and pix­els
  • view­port units
  • cal­cu­lated val­ues with calc()

This is cool and all, but what if you’ve got dy­namic con­tent in this view­port? I.e. ir­reg­u­lar sized blocks, such as non-cropped im­ages, where you would­n’t hard­core a repeat(300px) value.

tldr; Set both des­ti­na­tion and co­or­di­nate prop­er­ties to 50% 50% to make ir­reg­u­lar el­e­ments snap its cen­ter to the cen­ter point of the view­port.

Safari solves this with the -webkit-scroll-snap-destination and -webkit-scroll-snap-coordinate prop­er­ties. These prop­er­ties con­trols the co­or­di­nates of where Safari should po­si­tion your scrolling con­tent in a view­port.

#viewport {
-webkit-scroll-snap-type: mandatory;
// Destination for snapping. 50% 50% denotes the center.
// Defaults to 0 (left or top).
-webkit-scroll-snap-destination: 50% 50%;
// How to align the snap coordinate of an element.
// 50% 50% denotes the center.
-webkit-scroll-snap-coordinate: 50% 50%;

These styles are avail­able from Javascript with:


Note that this may con­flict with pro­gram­matic scroll, if you’re us­ing that.

CSS en­hance­ments

Safari now sup­ports these un­pre­fixed CSS prop­er­ties:

  • Transitions
  • Animations
  • Transforms
  • Flexbox
  • Columns
  • … and more

Feature de­tec­tion

In Safari 9, it’s pos­si­ble to de­tect sup­port for CSS prop­er­ties and write con­di­tional rules in a block:

@supports(condition) {
// Styles for condition
@supports(-webkit-initial-letter: 3) {
// Use fancy initial letter styles.

CSS4 :matches se­lec­tor

The :matches pseudo se­lec­tor helps you mash a bunch of se­lec­tors to­gether like this:

// Before
.default .foo,
.default .bar,
.default .baz {
color: red;
// With :matches
.default :matches(.foo, .bar, .baz) {
color: red;

This groups all the de­noted chil­dren of .default to­gether.

Force Touch API

Apple’s also added a Javascript API for the Force Touch tech­nol­ogy in­tro­duced in their lat­est Macbook.

Firstly, the webkitForce prop­erty is avail­abel on all Mouse Events. This is a num­ber, which is the force of the cur­rent press on the track pad.

There are also events on a DOM el­e­ment for lis­ten­ing to force touch events, which be­haves like mouseup/mousedown:

  • webkitmouseforcechanged - any change in force.
  • webkitmouseforcewillbegin fires just be­fore the mousedown event. Ideal for pre­vent­ing de­fault be­hav­ior.
  • webkitmouseforcedown fires af­ter mousedown, if the press is a force press.
  • webkitmouseforceup fires af­ter the above, if it’s a force press.

The con­stants MouseEvent.WEBKIT_FORCE_AT_MOUSE_DOWN and MouseEvent.WEBKIT_FORCE_AT_FORCE_MOUSE_DOWN rep­re­sents the amount of force re­quired for a reg­u­lar and force click, re­spec­tively.

See ex­am­ple app for a sam­ple im­ple­men­ta­tion.

Javascript up­dates

And lastly, we’ve got some new ES6 fea­tures:

  • Class syn­tax
  • Template lit­er­als
  • Symbols
  • Computer prop­er­ties
  • … and more

Pinned tabs icon

Last but not least. Remember the Safari pinned tabs in­tro­duced at the WWDC keynote? You can use a cus­tom icon shown when you site is pinned:

<link rel="icon" sizes="any" mask href="icon.svg">

The SVG icon should, ac­cord­ing to Apple, have 100% black shapes and trans­par­ent back­ground.

You can how­ever set the color of the icon with:

<meta name="theme-color" content="red">

I re­ally like the snap and back­drop CSS sup­port. I’ve missed the for­mer for a while, but did­n’t see the lat­ter com­ing. Hope they land in Chrome and the oth­ers soon.

Complete re­lease notes and links to sam­ple code.