BRENT FULGHAM: Hello and welcome to "What's New In Web Development and WebKit and Safari."
My name's Brent Fulgham and I will be taking you on a guided tour of some of the advances we've made this year.
This is an especially exciting time of year for us, because throughout most of the year, we only hear from you through bug reports and things told to us by other people, but this time of year, we have labs, we have sessions like this where we can get into all of the things that we have done to try to make your lives better.
And whether you primarily target Safari as a web developer, or an embedded web view in a larger application, I think you will find a few things in this talk that will be useful to you almost immediately.
So I would like to start with a brief overview of what WebKit is and how it fits into the software design stack at Apple, and then move on to some enhancements we've made in Safari this year that you will be able to take advantage of.
And finally, I would like to talk about creating some amazing experiences for the iOS and Mac platforms.
Technologies that are available on these platforms that if you take advantage of them will really make your website more compelling and useful to your customers.
So let's get started talking about WebKit.
WebKit is our web browsing engine.
And it's an open source project that anyone, any of you could join.
And while you may know that WebKit is the engine that powers Safari, you may not be aware that it's used in a tremendous number of applications across the spectrum of things we do at Apple.
WebKit is the same engine on iOS and OS X with very few variations between them.
So during rest of my talk, unless I specifically call something out as being available only on one platform or the other, you can safely assume that the things we are talking about today will be available on both platforms.
So the takeaway here is that if you are a web developer targeting Safari or any web browser on iOS, you can use all the things I am going to talk about today.
And if you are an app developer with an embedded web view, you can use all the things I'm talking about.
So that was our introduction to WebKit, and let's move on to the enhancements we made this year.
So I'm going to break this down just for structure into new layout and rendering features.
So let's talk a little bit about the enhancements in Safari and specifically, layout and rendering features.
And even more specifically, I want to talk about backdrop effects.
In iOS 7, the design language for the user interface was changed to incorporate some beautiful backdrop blur effects.
For example, here you can see the home screen icons just kind of peeking through that frosted glass effect.
And this kind of layering gives a lot of depth and gives you a sense of what's happening behind this overlay, without obstructing the content that we are trying to view in the front of the interface.
And later, in OS X Yosemite, we provided similar backdrop effects.
Here we have a very subtle blur in the sidebar of the finder and we have this beautiful frosted glass effect on the doc.
And so these effects are important to feel like a native part of the system.
And they are the kind of things you might want to use in the most refined version of your webpage for people visiting on a Mac or iOS device, but it's doubly important when you have an embedded web view that you want to have be part of the system, and look like part of the native user interface.
But how do you do that?
Let's say I have an application that's displaying photos.
There's no obvious way to create a backdrop effect like the ones we saw earlier.
We can try an overlay with a translucent background but you can see that the content kind of fights with the text on top of it.
You know that there are things behind it and it's difficult, makes it more difficult to read.
Now, we have CSS filters and those include a blur.
Could we try something like that?
Well, that's a nice effect, but it doesn't really get us what we want.
About the only thing that is clear in this image is the background, which is kind of besides the point.
So we observed people, developers like yourselves going to heroic efforts.
What they would do is they would have a background picture like this and they would create an entirely blurred version of it, which would then be clipped and moved into position to cover up the elements that you want to dismay as a blur.
And that's awful.
I mean, it's amazing that you did that but it's bad for us that we did that to you.
So and there are other problems with that.
We can't animate those backgrounds.
And it's difficult to change the blur effects.
Once we have made a choice, we have to re-render everything.
So we needed a better way, and that is backdrop-filter.
Backdrop filter allows us to specify these backdrop effects entirely in CSS and it's been proposed as a standard to the W3C and is undergoing that process right now.
Let's see how this fits together.
So if we have an element that we want to provide a backdrop filter for, WebKit will take the region behind it and re-render it in an off screen context.
And while that's efficient, rendering passes are costly, and so we want to make sure we don't over use them.
Once we have this background context, we then apply the filter to them, so we blur it, we composite the front-end content back on top of it, and then we can recomposite the entire scene back together and you get this beautiful blur effect, exactly what we wanted.
And once we got the blurs to work, we realized that we wanted the flexibility to use any of the CSS filters.
So we did.
We made it so that you can use any of the CSS filters in this effect.
So we can invert colors.
We can combine filters together.
So we can get a blur and a grayscale to get an effect like this.
And most amazingly of all, we can overlay this on top of dynamic content.
So this backdrop blur filter that's one line of CSS can be on top of a video, which is amazing!
I was so excited when we had this working and I can't wait to see what you guys do with it on your own sites.
So let's shift gears a little bit.
Another area that we saw some issues was in layout and rendering of scrolling effects.
You have probably seen this great iTunes banner at the top.
And if you've ever tried playing with it, you'll notice that when you try to scroll it, it moves in whole steps.
You get an entire movie title, movie brick, each time you make a movement.
And our photos app in iOS has a similar kind of effect.
Each time we look at a photo we want to swipe to the next one, we move across an entire photo, we don't show part of one photo and part of another.
This kind of interaction is really great for image galleries or other types of tiled content like this.
And we know that that's a significant performance penalty.
So we needed another way to do this.
And that's scroll snap points.
Scroll Snap Points are a way to declare in CSS, regions of scrolling that take over the animation of that scrolling curve, and this is also a CSS standard.
So imagine we have a viewport of some kind, a box that we want to look at a series of album covers in.
And so in this image, I have the album covers kind of dim and off-screen.
But I want to cycle through them one at a time.
And let's say that I know that they have a thick size, they are all 300 pixels, for example.
Every time I swipe on this content, I would want the scroll to take me across, one entire album cover.
And we can specify this behavior in Scroll Snap Points using the Scroll Snap Points x declaration.
And we tell it that we want it to be marching along in a 300-pixel interval using the repeat function, with a 300-pixel argument.
And this animation shows kind of how this looks.
I make a gesture to swipe through these images, we travel across some number of them, depending on how strong my gesture is, but as we as the momentum slows us down, and we come to a stop, we always land on a clean album boundary.
Now, in source code, that effect requires two lines.
We turn the feature on using the Scroll Snap Type mandatory, and then we specify the repeat 300 pixel declaration.
So I did a capture on a live site.
You can see that as I'm swiping across these, you get movement.
And if I slightly pull off and let go, the system scrolls back to the nearest scroll snap point.
So, like, they're rubber banding back to that position.
And you've probably already figured this out from the name, but scroll snap points work in both dimensions, x and y.
So what I have shown you so far would already be a pretty neat feature but it doesn't handle the case of varying sizes of content in the scroll container.
And so here, where I have non-uniform elements, even though I might have a 300 pixel square, I also have a rectangular unit.
That rectangular image or content will not fit in that 300 pixel boundary.
And so if I attempt to do a scroll with that set content, it won't look right.
And so scroll snap has a way of dealing with this.
If we take the scroll container as this white box behind me, there's something called the scroll snap destination and that's a position that we will align our elements when scrolling.
It defaults to the upper left corner but we can position it using standard CSS positioning syntax.
The companion to the scroll snap destination is the scroll snap coordinate.
These are positions on each of the elements inside the scrolling container.
And they are also defaulted to the upper left corner.
So we can tell the scroll the WebKit that we want our scroll snap coordinates to be in the center of each element using this syntax, and we can say that we want the center of the scrolling container to be our target point, the destination.
And when you put them together, when you perform a scroll gesture, we land on a clean, centered point on that box.
And the code for that is no more complicated than it was for the simple repeating pixel case.
We turn the feature on, on the container, the scrolling container, with mandatory, and we position the destination in the center of the scrolling container.
And then we position the coordinate on each of the elements.
And I created a class, 'photograph,' here, but, you know, you can do whatever you want, and position that in the center.
And so this is a capture of what that looks like on a website.
And so with a series of images, as I scroll through them, we always land with something in the middle.
And with an example, with a demonstration of how this looks in practice, I will invite Chris up to give you an amazing example of this.
CHRIS YOUNG-ZAWADA: Thanks, Brent.
My name is Chris Young-Zawada and I'm a developer on Apple's Interactive team.
The interactive team at Apple does a lot of work around the company, and one of the things we do is we're responsible for a lot of the web content you see on Apple.com.
So I'm super excited to be here today because I feel like a lot of the features that Brent has been showing off are going to be really great for web developers and I'm really excited to use them myself.
So to get started what we put together is a little web app here that shows off some of these new features in WebKit.
And we have a photo gallery laid out here that we can scroll up and down.
And you can see that some of the photos are different sizes than others.
We can hover over one, and when we click to open it, it will open in this overlay view, where we are able to scroll between the photos, by going left and right, and we can even choose our favorites in the top right by clicking here.
Now this is pretty cool, but I feel like we could make it a lot better using some of the new features in Webkit.
So, to get started, I want to focus on backdrop filters.
If you notice at the top of the application here, we have this fixed navigation element and right now it's just a solid black color and it's fixed at the top.
As we scroll up and down, the content goes underneath it and then goes into the Safari tool bar where it gets blurred.
That's pretty cool but we actually can make it a lot more cohesive by adding a backdrop filter to this element and making it feel like it's much more part of the UI.
So I'm going to show you how to do that.
Just so you guys know, I like to use spaces a lot when I code, so I'm going to jump between the UI here and the code, back and forth, quite a bit.
Cool. So right now, I'm in Xcode and I'm in a CSS file that we are going to start appending some new code to.
So to do that, I'm going to start, and I'm going to paste a new navigation declaration here which is targeting that solid black navigation bar, and we are going to set the background color to be solid black with 50% opacity.
And then we are going to add a backdrop filter with 10 pixels of blur.
If we go back, we can now see in just one line of code we have added this amazing new way to blur the content behind as you are scrolling.
The text is still super clear and everything goes really nicely into the Safari toolbar.
I think this is awesome.
Like, this is fantastic work on the WebKit team, to do this.
Awesome. So the next thing I want to show you guys is scroll snap points.
And I think a really good candidate for Scroll Snap points is this overlay gallery.
Remember, when we're scrolling this left and right, we can get left in places where we might see through the content and not exactly focus on what we're looking at here.
This is okay, but we can definitely make it better and by focusing on the content with Scroll Snap Points we are always going to look at the photos we want to look at.
So I'm going to show you how to do that as well.
So if we go back to the CSS, we are going to add a new declaration on the overlay gallery where we are going to set the scroll snap type to mandatory and we are going to set Scroll Snap Points x to repeat at 100 viewport width.
Each photo container is this size, so everything should fit really nicely when we go back and we scroll that element.
If we refresh, we can now very cleanly go between the photos and WebKit has taken control of the scrolling.
So you'll see that I can hit the edges and everything will bounce back into place.
It's really nice.
So we can change how many cells we want on the x and y axis.
And we are going to extend our masonry gallery constructor to a Snap Points masonry gallery.
We are going to, and basically all we're going to do is we're going to add a new method called set snap point styles.
What this will do is we will actually set the scroll snap type to mandatory, and it will set the snap points on the y axis to repeat as tall as each cell is in the y axis and this is a variable that we set inside of the constructor when we are running this on instantiation.
The last thing we're going to do is we are going to tell our JS file to use this so, because we've extended it, we just have to put it here and use that instead of the masonry gallery.
And now when we refresh, you'll notice that the nav bar sits very nicely with these elements and we can throw it and it will always land in a really nice place where it fits with the content.
I think that's really great, and with that, I want to give it back to Brent, who is going to talk some more about layout and rendering.
BRENT FULGHAM: Thank you.
That was amazing.
So I just want to go over a couple of things about those features we just talked about.
Backdrop filters are very efficient.
They are hardware accelerated, but the rendering passes that it causes to trigger can be expensive.
So we want to be careful to measure and see how things work on your own sites.
Scroll Snap is great for page content, for tile content, but you want to be careful if you are doing any kind of programmatic scrolling because the two features will fight each other when trying to animate the scroll.
So keep that in mind.
And that wraps up the section on layout and rendering features.
I want to talk for a moment about a few of the exciting features that we put together this year.
Last year, in our session, we talked about a number of features that were added and we haven't been sitting around since then.
We have expanded the ES6 support tremendously this year with a lot of stuff, symbol objects, object out of sign, weak sets, but I am just going to touch on a couple of things that I think are really, really useful.
Let's start with my favorite.
Now how many times have you run into this problem where you have a set of you are trying to build a logging string or produce something for a user, and you have a bunch of string chunks that you want to concatenate together, and some objects.
And so you end up with something like this old syntax example.
And I have spent more time than I care to admit looking for the missing concatenating operator or the closing quote sign that I forgot about.
And so I was super excited when ES6 introduced this new template literal syntax, where we create strings, special strings, using the backtick character instead of a regular quote string.
And when we do that, anything inside of the string that is escaped with this dollar sign curly brace syntax gets converted into string representation automatically.
And you can even do operations inside the syntax, like, here I'm adding two numbers together.
And so both of these give us the same output, but I find that the second one is so much easier to read, and I have jumped wholeheartedly into this.
Everything I write is in this syntax now.
I love it!
Another neat shorthand that was introduced this year is related to object literal creation.
So you often have a situation like this, where we have a generator function of some kind with a set of argument names that we want to use.
And often those argument names are actually the names we want to use for the new object literals that we're creating and so you send up with a silly repetition of name, colon, name, and category, colon, category.
And that's such a common idiom that the ES6 designers introduced a shorthand for this, where you can create an object literal with variables and if you don't supply the property names it will just use the names of the values that you are supplying to it.
We were able to get rid of a couple of hundred cases of this kind of duplication in the web inspector, and found that to be quite useful.
And I'm sure that if you look into your own code, you will find plenty of cases where this is helpful.
So here I have a simple example of a polygon class written in the standard prototype syntax.
But in ES6, a new syntax has been introduced, an object, a class-based syntax that looks very familiar to anyone who comes from a language like C++ or swift, and allows us to encapsulate everything together.
It's so much easier to read and easier to see where things relate to each other.
The class syntax includes a special function, a constructor, that handles the object initialization for us, and we can define methods in the class that are part of the object.
And it supports inheritance.
So we can inherit using the extends keyword from existing objects.
When we inherit, we want to make sure that we initialize the parent class using the super operator.
We can override methods like you would expect from other object-oriented languages, and it even supports static methods now, so you can define methods on the class that you don't need a specific instance of the object to use.
And finally, this new class syntax is completely compatible with the existing prototype-based syntax.
So you can immediately start extending prototype-based code using this new syntax without having to rewrite anything.
I think that's a huge advantage and it's something that you can start using right away.
Now, as we've dealt with CSS for many years we have run across a number of patterns that lead to bloated style rules.
And so this year, we implemented a number of new CSS standards that are aimed at combatting that, making styles simpler and easier to maintain.
It's a recurring theme in this talk, but I don't have time to get into all the things we did this year, any-link, placeholder-shown, lang, just a bunch of improvements, but I do hope that you get our developer seed and try it out.
So I want to talk first about some recently unprefixed properties and values.
We became satisfied with the standards compliance and stability of a number of features this year, and so we've unprefixed them.
So now you can use them in their native format.
We will continue to support the WebKit prefixed version of these, so your existing sites will continue to work.
We recommend that you switch to the new WebKit, or the WebKit less version of these strings in your new code.
Now, I know it's going to be hard to top that exciting unprefixing slide.
But I am going to try.
A very common need is the ability to recognize when your site is being used in a browser that supports specific features.
And so you may choose to use certain features or not depending on what the browser can do.
Let's say, for example, I have a website where I want to use a neat drop cap style, and so to achieve this look, I want to use a different font for that "C."
I want to add spacing and extra padding around it.
I want it to be a different size so that it's visually distinctive.
And I can do that using WebKit initial letter, which is another new feature this year in WebKit.
But if the browser viewing my site doesn't support this, we get this awful I mean this is gross!
I would never have used this font if I knew it was going to end up looking like this.
I wouldn't have put the spacing around it, if I knew it was not going to fit in this with idea that I had.
I would rather have done nothing at all.
And so in the past, we would use code that looks something like this, to probe the browser and say, hey, do you support initial style?
And if you do, then I can do some extra work, navigate the dom, find the elements that I want to style, turn these things on.
And now we don't have to.
WebKit supports the @supports function this year, which allows us to create a conditional where everything inside the brackets is applied only if the conditional is true.
So in this case where I have WebKit initial letter, I can have all my special styling inside the supports clause.
And so if I go to that site with a browser that doesn't support WebKit initial letter, I get a, you know, blander view of things, but it's perfectly fine.
This is legible and it looks good.
But if someone goes to the site with Safari, they get this glorious drop cap.
Amazing! I want to talk a little bit about reducing repetition.
This is some actual code from the web inspector.
Well, I cleaned it up a little bit for the slide, but we have lots of cases where we have something like this, defaults and a bunch of classes that are part of are part of that same group, and we want to apply some styling to them.
But we're repeating defaults over and over again, and you multiply this times dozens of other classes and hundreds of other styles that we are trying to achieve and it ends up being a lot of stuff to maintain.
And so the CSS 4 designers agreed and created the matches pseudo-class.
And what this does is it allows us to programmatically define all the permutations between default, for example, a class, and a list of selectors.
And this takes the place of those repeated lines of common stuff.
Replaces it with one line.
And, so, about the only thing I like better than writing code is deleting it.
And so this is fantastic!
Because we can get rid of tons and tons of replicated code.
This was a great day in the web inspector when we were able to land these changes and get rid of all this duplication.
And so those were some new CSS features this year.
And that also completes our discussion about enhancements in Safari.
So now I want to shift gears a little bit and talk a bit about creating amazing experiences on OS X and iOS.
How many of you here have sites that are targeted just for desktop?
Or you have special things that are just for desktop?
One or two.
And others that might have stuff that's specific for mobile, right, iOS and Safari.
And so while the bulk of my talk is aimed at convincing you to use some of these web standard features that have been developed, in this part of the talk, I'm hoping to convince you to adopt a few of the things that are unique to Mac and iOS.
And by supporting these technologies, you can surprise and delight your users and extend their engagement with your content across our entire ecosystem.
AirPlay has been around on iOS since iOS 4 and we've supported that in Safari since iOS 4.
But this year, we opened up AirPlay on Safari, on OS X which allows your users to play your media to Apple TV directly from the device.
The API is identical to the one that was produced for iOS.
So if you did the work to support it back in 2013, you are done!
Or if you use our media controls, you have that support now.
But if you haven't, I recommend that you look at our WWDC 2013 talk where we go into some detail about how to support the AirPlay protocol.
Wasn't it cool to see multitasking on iPad yesterday?
Until yesterday you had a pretty good idea that when you viewed content on an iPad, you had a good idea of what you were getting.
You pretty much had the entire screen.
But now you can have two-thirds of the screen allocated to your content, or half, or a third.
And so responsive design is really important now.
Users control the size of the view, and iPad is a lot more like desktop now.
It's so important, responsive design is so important, that we have an entire session tomorrow, same time, same place.
I know you all are capable of getting up in the morning because you are here today, and I recommend you come and see "Using Safari to Deliver and Debug a Responsive Web Design" tomorrow, which goes into the tools and features that have been added to the web inspector in Safari to make your life easier when trying to support these styles.
There's also a session on multitasking for media-based apps on iPad and iOS 9 which is also of interest.
And we talked about picture-in-picture yesterday.
The iPad has always been a great way to view content, and until yesterday, you had a good idea that your content would be consumed in this sort of full screen form.
But now we have a new way.
We have picture-in-picture which allows you to compress your pictures of your children into a small box in the corner of your giant empty calendar.
But it's a great feature.
We have we defined this in WebKit as presentation mode.
We support full screen, which you are familiar with.
And inline in which your content is displayed in the page itself, and picture-in-picture, which is our new style.
So we have a range of sizes that you need to be worried about.
The WebKit, default WebKit Media Controls support picture-in-picture out of the box, but if you write your own media controls, you need to use the presentation mode API to control these things.
And our developer documentation has information on how to take advantage of that in your own content.
There are a few things for you to be thinking about here.
When a viewer starts viewing your content in full screen video display, the page may not be obscured anymore because the viewer can exit full screen mode and go into picture-in-picture without you really knowing about it.
So if you take the opportunity to turn certain features off or hide content on your page while a video is being displayed, that may not look right if they are going to picture-in-picture.
And since the media may be playing in a very small window, we strongly recommend that use HTTP Live Streaming, or HLS, for delivering media.
HLS allows our media engine to select a bit encoding, a bit rate for the video that matches the size of the content being displayed.
It also takes into effect, network conditions, battery status on the device.
And so by using it, you will ensure that your user has the best experience because it will take care of a lot of those details for them.
Multitasking essentials for media based apps on iPad in iOS 9 is a great session to see on Wednesday.
And if you haven't heard enough from me this year, you can see me and Jer talking about advanced media for the web last year, where we went into some detail about HLS.
So finally, I want to talk about something really amazing, our Force Touch trackpad.
back in March we were excited to show off our new products with this great new hardware.
It allows us to recognize a second level of click, we call Force Click, and we are really excited about this.
We had a lot of fun adding new user interface features like this mode of dictionary look up that allows us to find out what a fluoroelastomer really is.
And we added a way to view the content behind a link without having to leave the web page.
I know that all of you can come up with even better ways to make use of this hardware in a web context.
And so we wanted to open up access to that hardware so that you could use it yourselves in your own web pages.
Let me talk briefly about how this fits together.
When we have a normal Trackpad, if the user presses down we eventually reach a level of force that we consider to be mouse down.
And as the user continues to press, and then lets up, we come back through that pressure level and call it mouse up, and we issue it a click event.
We extended this model to support Force Click operations by adding a WebKit force property to all mouse events, which tells you how much force is being applied to the Trackpad.
And then we also added a number of new events that you can register for, to handle this.
So if we go back to this last slide where we had mouse up, mouse down.
We now emit a mouse force will begin event.
And that's a great opportunity to call prevent defaults on the event itself to prevent us from calling the dictionary look up logic or from doing the link preview, if you want to take over this yourself.
After passing through the mouse down phase, if the user continues to press, we hit a second level of force that we consider to be a force click and we emit a mouse force down event.
And as the user lets up on the force, we pass through a mouse force up.
So it's completely analogous to mouse up, mouse down, we have mouse force down, mouse force up.
And during the entire phase of time, between mouse down and mouse up, we emit mouse force changed events and we do this because the user may be changing pressure, changing the amount of force they apply without moving their finger around.
So there would be no mouse move event to capture that force for you.
And note, we also define two layers, two constants that define the level of force at a regular click and a Force Click.
And we strongly recommend you use these constants instead of capturing numeric values because those may change as the specification matures.
And so to show us how to take advantage of this in your own website, I would like to invite Chris back to show us another demo.
CHRIS YOUNG-ZAWADA: Great.
So as Brent just told us about Force Touch, there's a lot of really cool things you can do with it that can really enhance your websites.
And if you guys remember when we were looking at the demo earlier, when we were clicking into this overlay, we had the ability to choose our favorite photos.
That's really easy to do, but it's also another step and I think if we can really make it better for users that have a Force Touch trackpad in case we want to make a little bit more interactivity for them.
So while I was offstage, I actually made a couple of changes to the code and what I have done is I've actually extended the Snap Points masonry gallery to create a force enhanced masonry gallery and we are going to use this to add some force events, and actually do some animation on force change.
So there's a couple of things to point out here.
The most important thing is we are going to get the min force and max force values from the mouse event data, which are the force at mouse down and force at force mouse down contstants that Brent just told us about.
The other thing we are going to do is we're going to bind some event listeners for the force events that get thrown so we can actually bind to them and make updates on those.
I've just stepped out how we are going to handle those, so it doesn't do anything right now.
So we are going to go step by step.
Cool. So to get started, I am actually going to start with force mouse down.
We don't want those to interfere.
So this basically makes sure that the transitions is set in a lot of things.
The next thing we are going to do is look at what kit mouse force changed.
And we do a few things here.
We are actually getting the force data from the WebKit force property of the event.
And we are going to create a progress, and we are going to see how far along between the min force and the max force values we are.
And we're actually going to animate some elements between those, so you'll see that we are going to go back and do some interesting things there.
And basically when we are through our progress we are going to say that we favorited the image and we are going to say that we are done animating.
So if we go back and refresh.
If you hover over this photo you can see that now as I press up and down, we are actually scaling the image depending on the pressure that I'm applying to the force trackpad.
It's really cool and it's really interactive and it adds a whole new layer of depth.
When I press all the way down, you will see that this heart appears which means we've liked the photo, but I'm actually still holding my finger down.
So as I pull it up, you will see that we go into this overlay view.
And that might not be what we want.
What's happening is that the click event is still being fired because we haven't prevented any of the default behavior in the browser.
So to do that, we actually just go back and add a quick line of code.
And we're going to go to 'mouse force will begin' and we are basically just going to call prevent default.
This is going to make sure that none of the OS interactions interfere with what you as developers are doing and you get full control.
So if we go back, we can try it one more time, and after we hit this level, nothing is going to happen.
But we still have to reset everything.
So we can just fill that in with mouse force up.
And all we are doing here is removing a lot of the styles we set and making sure that all of the CSS properties we put in there get removed and go back to normal as if we never touched this at all.
Great. So with this new interaction we can hover over the photos, get that animation, like them, and just like that, we have got the ability to add favorites to our photos and we can still just do a regular click to go to the gallery any time.
I think this is really cool and I'm really excited to see what you guys are going to do with this new technology.
And with that, I am going to give it back to Brent.
BRENT FULGHAM: Thanks, Chris.
So I think you will agree that that was a great way to make use of this hardware.
A couple of best practices for the Force Touch trackpad that I would like to recommend.
Always use the mouse force constants and not hardcoded numerical values, because we expect that these may change as we navigate the process of fulfilling or completing this feature.
And remember that not all users have Force Touch hardware, sadly, and so we should use this as a shortcut or as a flourish, an extra for people who have this hardware.
Use it to drive animations or to provide a shortcut to content that you can get to other ways.
And that was creating amazing experiences on Mac and iOS.
And that rounds out the bulk of the talk today.
I just want to summarize a couple of things.
We talked about backdrop filters, an amazing way of hardware accelerated backdrop filter effects on your sites.
Scroll Snap Points allow you to get tiled scrolling with just a few lines of CSS.
We talked a bit about AirPlay coming to OS X through Safari, and picture-in-picture and iOS multitasking, and some sessions that you should see about that, and this new Force Touch API.
For more information, documentation is available.
We always love people to come to the WebKit project at www.WebKit.org.
Join us and see what we are doing or come try out the nightlies and see what new features are coming for next year.
Get a sneak peek.
And for general inquiries, I recommend that you get to know Jonathan Davis, our WebKit Evangelist.
He's a great person to get to know when you have issues that you want to talk about or if you have messages you want to get to us on the WebKit team.
And with that, thank you so much for your time this morning and have a great time at WWDC this week.