Practical lessons from a year of building web components - Google I/O 2016

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

This was a good video. Made me think about my component creation process in a different way

👍︎︎ 1 👤︎︎ u/Yowhasoy 📅︎︎ Jun 05 2016 🗫︎ replies
Captions
MONICA DINOSAURESCU: Good morning, everybody. Thank you for coming. Thank you for coming to this 9:00 AM session for the jetlag and insomniacs, and those of you haven't left from the party last night. So let's talk about web components. We had a whole bunch of titles for this talk. It doesn't actually match what's in the program. My favorite was The Meownica School for Kids who want to Web Component good, and do other Things Good too. It was rejected. And addyosmani suggested, Meow Meow Protips Meow Meow, which is pretty much what's going to happen here. So meow meow. Hi, everyone. I'm Monica. I'm notwaldorf on Twitter and GitHub and internet places. And officially at Google, I'm an emojineer. And that's because I get very excited about emoji. And I sort of like shout about it into the void that is Twitter. But what they actually pay me for it is to-- oh-- emoji. So the funny thing about this slide, I had to use android emoji and not the Apple ones. It was mandated by legal. And what I do is web components. And for the four people in the audience, I think-- as we did a raise of hands, who don't know what that is-- web components are a standard we've been working on. So that you can write reusable widgets for the web. So you can make your own fancy button, and give it to people, and everybody can use it. I work on Polymer, which is a library that helps you write these web components. And in particular, I write web components with Polymer. We have elements like these ones that are like material design [INAUDIBLE] elements. We also have elements that don't look like anything. We have a declarative AJAX element that you can put in your page, and get super easy XHR requests. And that's kind of fun. So, you might not think of yourself as an element developer. You might think you're a web developer. You make apps. But if you want to start playing with web components, I think thinking like an element developer is really important. So you might only make elements for your own application. But you're kind of making them for future you, because future you is going to have to use these elements. And if they're crappy, future you is going to have a hard time. So, I'm going to tell you basically all the mistakes I've made in the last year of making web components. So that maybe you won't have to do the same ones. So there's like four things that I thought are kind of interesting about making web components. You've got to make an API that doesn't enrage your users. And this is actually kind of interesting. You've got to maintain this element, once you start giving it out to people. You've got to make sure that it's fast, and isn't slow like molasses and destroys everybody's application. And you want to make sure that it's accessible. So these are the four things we're going to talk about. So let me tell you a story. In the '90s, we had HTML1. And it was lovely. And it was basically like reading the paper on the internet. Things that you might see on a page, or things like links and headers and images if you were lucky, and that's all that happened. You opened the web page, and you read it, and that was pretty much it. And in 1995, things got exciting. We got HTML2. And in HTML2 we got three awesome elements. We got input. We got form. And we got select. And I think we button, well input type equals button was there. So now this meant that websites could offer you interaction. You can type something in a text box. And the website would react to you in some way. And the reason why I think this is important is that these are basically like OG web components. They are little, reusable widgets that the platform gives you, and you can put in your application. That's exactly what a web component is. And since '95, in the 21 years that we've had this, we've come up with a couple of more web components, or like whatever you want to call them. We have video and audio, which are kind of awesome. Canvas is like an enormous framework in and of itself. Dialog and details and things like that, aren't really implemented in all the browsers. And a lot of the input types aren't implemented in all the browsers. So the reason why I'm telling you is that, even though we kind of had web components for something like 21 years, we're not very good at making web components. And I'm going to spend the next 10 minutes telling you how input is really terrible. Because that's one of my favorite things to do in life. On the other side of the world, we have UNIX. And here's where it begins to be a little bit of a flame war. So we've had UNIX since the 1970s. And one of the things that UNIX is really good at is making reusable little programs that everybody knows how to use. These are the ones that I've just used probably in the last week. These are the ones you've probably used ever in your life, maybe not telnet and links, unless you were playing a joke on somebody. But UNIX is really good at this. You use ls every day. If you use a terminal, you use ls every day. And the reason why UNIX is so good at it is because UNIX has a philosophy about how to write these super tiny components, commands, programs; whatever you want to call them. And that's what we're going to talk about for a little bit. Because if you're going to go ahead and write web components, I want you to think of what grep does, and not what input does. Grep is a great example of a reusable component. Input is absolutely terrible. First thing, so UNIX has 17 bullets in their philosophy. And some of theirs are super meta, like value developers time over computers, which is great. And I don't know what that means. But one of ones that's the most popular one is that your component should do one thing. And this is 100% true of web components. If you build a component, it should be really tiny. It should do the thing that it says it does. And it shouldn't do anything else. If you look at the cat command, cat takes a file from your computer and spits it out to the terminal. It doesn't try to print it. That's what lpr is there for. It isn't trying to find a string in it. That's what grep is there for. It doesn't try to sort it alphabetically. That's what sort is there for. Cat takes a file, and prints it to the terminal. Input, on the other hand, has something like 21 types, I think, today last time I checked. Even when it started in 1995, it had 8 types, off the bat. That's how we started the races. And that's really terrible. Because they don't really have anything in common, these input types, other than the allow you to select a value. You have input type equals text, where you just mash keyboards, and they appear on screen. You have the slider, which you drag a ball on a vertical slider. And that magically picks a number. You have a color picker that gives you an RGB color. You have the map type, which is basically like an image map. And where you click on that image is the thing that gets saved as a value. So again, all of these things they have in common the fact that they have a value. They shouldn't be the same element. They don't even look the same. And then you start painting yourself into a corner once this is your API that you start with. So here, I am creating input. It's by default of type equals text. So it's an HTML input. And because you can type in, and it has a caret, you can get where that caret is. And selectionStart is the property that you do this. And then I'm going to change the type to input type equals number. I can still type. I still have a caret. But now, if I actually try to access that property, I get an exception. It's not that it's a bad value. I literally get an exception. The browser panics. And this makes no sense from an API perspective. Both of these are an HTML input element. Both of these have the same prototype. They have the same property. And yet, if you access it on some types, like most of the types to be honest, selectionStart just barfs on your console. And the reason why this is happening is because input type equals text and input type equals number should never have been the same element. They were the same element, because in 1995 we didn't have JavaScript. We didn't have polyfills. We didn't know how to fall back to a default behavior. So we're just like, we're going to put everything in one element that is going to have a default value. And it's going to be great. But 21 years later, we're still paying for these mistakes that we had to do in 1995, because of what the platform was like. So this is why don't look at input for API advice. Because input makes mistakes all the time. Another one of the UNIX philosophies is composition. Programs play very nicely with other programs. In UNIX this happens with pipes. The output of any program can become the input of any program. And everything works magically and beautifully. And the way this works on the web is by sort of nesting elements together. So select is composable. Select and option are composable. That's how you can put elements in a checkbox. And you can put in text. And you can put in a button. And you can put in an input, and an image. And what do you think is going to happen here? Does anybody know what actually happens? Yeah. This happens. It's amazing. So the input gets rendered outside of the select box. We're not even trying. There's no image. And with a button, we're just taking its text value. This is not a composable element. This looks like it could be composable. And select had a chance to get it really right, and they made a mess of it. And the historical reasons here are again, because in 1995 when it came out, IE4 on Windows didn't know how to draw select combo boxes otherwise. But 21 years later, again, we can do better. And with Polymer, we did do better. We made our own select box. We called it paper, because it's material design. And in the dropdown, you can put on items. So you can put in text. And you can put it an input. And you can put in a button. And it looks like exactly what you would expect. There is the text. There is the button. There is the lemon. I don't know why you would put an input in a pop-up menu. But I mean you could. Nobody's stopping you if you want to do that. And that's a composable element. So when you're making your elements, think about this. Are you expecting to have children composed in there? And if you do, try not to make assumptions about them. Try to expect sort of any types in there. Because people are going to put inputs in your dropdown menus and you're going to have to deal with it. And this really leads me to the extensibility, which is the code that you're writing today should work in 10 years from now. ls was written 40 years ago on a platform that is nothing like the Mac that I'm running it now. And ls still works. It probably had to be recompiled. But I don't think anybody changed the source code dramatically. 20 years ago we wrote form. And form is the opposite of an extensible and planned for the future element, because form only works with the input element. When I say it only works with the input, I mean it is literally baked in the parser. When the parser gets to the form element, it only looks for elements that have the tag input and skips everything else. And this blows for us as web developers. Because what if I make a super awesome input now that is way prettier than the crazy native input? I can't put it in a form. Because the form is going to ignore it altogether. So I have to start hacking around it, and make hidden input, so that the form recognizes it. So in contrast, in Polymer we try to not make assumptions about what sort of things, again, our element expects. We have the swipeable container, where anything that you put in it, gets this magical android swipe left or swipe right action. And this means that I can put in divs, and I can put in inputs, and I can put in Polymer elements. And I can even put in web components that people wrote without Polymer. That element doesn't care. It accepts everything. And that's a really good element. Because if it works today, it's going to work in the same way like in 10 years, when the DOM might change a little bit. But the elements stay similar. So the point here is to not make any assumptions when you're making your elements. And so the way I interpret it is that when you create your element, assume that it starts sort of naked, without anything. It doesn't have any properties set on it. It doesn't have any children. It's just like born into the world. And then it starts reacting to things. When properties change, react to that. Don't assume that the properties are already set. If people add content to it, react to that. Assume that when your element starts up, it has nothing. And you have to deal with everything that follows. And that means that pretty much in any way that people are going to use your element, you're going to be fine. Because you've pretty much covered all your bases by just reacting to changes. And this also leads me to this conversation about state. Because unlike UNIX-- and this is where UNIX wins-- UNIX programs don't really have any state. They start up. You give them some input. They do something with the input. And then they die. And everybody is happy. But on the web, the input lives there on the page for as long as that page is open. And you're probably going to type in it. And it has to somehow remember what you typed in it. And that is in its internal state. Which isn't necessarily bad. But what you should do about it, is that make sure that if your element changes the state internally, you communicate this to anybody who cares. You fire an event every time this internal state changes. And similarly, you as a user should be able to always change the internal state of this element, in the same way that the element can do it. And guess what. Guess what input fails at. So input type equals number is a good element. Because in theory, it lets you validate what you type in it. So it lets you type in digits and a period for decimals, and the negative sign, and E for exponents. So it doesn't let me type in Monica or emoji, which is great I guess. So if I type in 1234, the internal value of the input is 1234. If I type in nothing, the value is nothing. And if I type in junk, the values nothing-- wait, what? Yeah, so it turns out because this value is actually invalid, the input is going to secretly reset the value to the empty string, but not actually tell anyone. It's just going to do it internally, and not fire an event about it. And if you start with nothing and you type in junk, you as a programmer cannot detect this change. Nobody has told you that anything has happened. But you with the eyeballs, are looking at that input, and be like, look there is junk in it. You've got to do something about it. But as a programmer, you can't. Because input is like hiding its state away from you. So don't do that. Don't be input. Which is pretty much the point of this talk, never be input. Because nobody really likes surprises. Surprises in an API are the worst. They're like finding that your cake is made out of kale and not cake. This is San Francisco, where everything is made up of kale. This is the new tragedy in my life. So remember how I said that the reason why we painted ourselves into a corner with input is because in 1995 we didn't have polyfills. We had to somehow have a default type on all these stupid inputs. And the only way we could do it is just jamming them into an object. But now we have polyfills. So we need to deal with polyfills. And the really important thing about polyfills is that if your element expects a polyfill, please for the love of God, do not include that polyfill with the element. And here's a story. So we have an element that uses the web animation polyfill, with the web animation spec, which works on some browsers, and on all of them. So there's polyfills for this. And we were like, we're going to be so nice to our users, and include the polyfill with this element. And everything is going to be grand. You're going to have a great time. And then Chrome settings came around, and they're like, we would really like to use this element on Chrome settings, a page that runs on Chrome and no other browsers. Chrome has the web animations standard implemented. But because we jammed the polyfill in that element, Chrome has to actually download the polyfill for something they already know how to do on every single page. And that's really great. So they don't really want to use that element. And they hate us for it. So the moment you include the polyfill in your element, you take that choice away from the application developer. Maybe they want to use a different polyfill. Maybe they don't even care about supporting Internet Explorer. Who cares? Don't jam the polyfill in there. You're not actually helping anyone. Document it that it's required. But let the user take care of that. So what I hope you got from these last 10 minutes is that input is terrible, and you should not look at it for any API advice, and that grep is kind of really good. Because UNIX is actually really good at making this. So if you want to read the 17 bullets of UNIX philosophy, I strongly recommend it. They're kind of really interesting. And they're probably going to help you make better APIs. Got it in the end. Awesome. So we have an element. We've given it to people. It has a beautiful API. Nobody hates us for it. And now we actually have to maintain it somehow. So, the thing about maintaining your elements and why it's important is that if you go on npm, and you download a package that hasn't been updated in two years, that's going to give you like the creepy jeebies. If nobody cares about this package, and nobody is fixing it, then I'm probably going to be running with a lot of bugs. This is the same with web components. If you want people to use your elements, you've got to keep your elements up to date. Because that makes them cool and usable. And one way we in Polymer do this is by making sure that we follow semver. Oh, whoa, whoa, whoa, whoa, whoa, whoa. That was exciting. We got there, semver. I get excited about semver all of the time. So semver stands for semantic versioning. And basically it means that every one of these numbers in these versions actually means something. They're not just random. So the last number-- on the right here, I have a tweet from Dave Methvin, who makes fun of semver. Because no matter what you think you're shipping, you're actually going to break your users. So keep that in mind. The last number means that this patch has a patch fix. It has bug fixes. It's still backwards compatible. Everything is a-OK. The middle one means that you're shipping some features, but it's still backwards compatible. So if you're using this version yesterday, and then you update, and you get the new version, your app should still be fine. You're going to get new features. You don't have to use them. But everything that used to work, should still continue to work. It probably won't. Because you'll write some bugs. But that's a different problem. And the first one is a major version. This means you're actually introducing breaking changes. So if somebody wants to pick up this new version, they actually have to do a little bit of work for everything to work in their application. And there's two things I want to tell you about major version bumps. One of them, numbers don't have meaning. So please do not think that increasing your major version is actually a marketing ploy, or anything like that. Don't get obsessed about this. All you're doing is communicating that this version has breaking changes. You're going to have a bit of a hard time. And the second one is just because you can communicate these breaking changes, doesn't mean you should have really aggressive breaking changes. Breaking changes are really terrible for your users. They have to do work. They have to read the new API, and figure out how you broke them, and figure out how to make their stuff work again. So in Polymer we try to be very deliberate. We haven't shipped a major change yet. Because we want to make sure that the moment we ship it, it's a right change and it's going to not be actually very hard for users to update to it. So be very deliberate about what you're shipping in a major change. Don't just abuse it, because you can communicate it. That's what Ruby does. So now that we have semver, we can tell the users that this version is going to break you or not. But the only way we're going to figure out if we're actually going to break users is by testing. And this should not be new to anyone. You write software. You test it. Duh. But testing web components is kind of interesting. Because web components are new. And I found that I had to test things that I did not expect that I had to test. The first one is obviously the public API. If you pinkie swear that a function exists, you should make sure the function exists and does what it says it should you. Duh. And I'm trying to click now. We're having great times with this remote. I really like it. So the other thing is that you might want to start introducing this idea of a private API. JavaScript doesn't care. So don't worry about that one. But if you introduce a convention, like underscore means private, you get to be responsible for less of that API. A lot of your configuration methods, or any of your internal functions, you don't have to make them public. Because if you're making them public, you're responsible for them. But if you make them private, then anybody who is using them, you can be like, listen you're on your own. I told you not to use it. If you really want to use it, I can't promise it's going to be there. So in Polymer we use underscores. Any functions or properties that start with an underscore, or two underscores if it's a behavior, are private. Use them at your own cost. I might just delete them for shits and giggles. You should test your accessibility. So elements should be accessible. And I'm going to rail on this one in about 20 minutes. But you should also test this. You should unit test it. Because you don't want to break it. We use the accessibility developer tools. It's on GitHub under Google Chrome. That's what this cryptic diagram means. And they're basically an API that you can run as a unit test. And every time you set something like roll on an element, it makes sure-- it runs 20 tests and makes sure all the aria labels are set up correctly and tab indexes are set up correctly, and your contrast isn't terrible. So it's really good. You can automate them. You should also test the look and feel. And this is where things get interesting. Because your vending elements that look like something, the thing that they look like kind of becomes part of it becomes part of your contract with the element user. So I discovered this the super hard way, where we had an element. It was a button. And I thought I was being extremely awesome, and I changed the box-sizing from content box to border box. And I was like, everybody is going to love this change. And I broke 15 people. Because it turns out if you change it to a border box, and somebody was sending a size on that element, that site is now completely messed up. And they're going to have to adjust everything and add 20 pixels to everything. And I shipped that as a bug fix, and it was actually a breaking change. Go me. And that's because I didn't any test for the UI. So make sure you actually test the UI. Because you're promising your user that a thing looks like the thing it should look like. Here's a bunch of UI frameworks and libraries that let you make UI tests. I don't care which one you use. Just use one. You don't even have to-- everybody's taking pictures of these, nice-- you don't even have to use this one. You can literally do get bound and client direct on your elements. And make sure they're the right size, and the font size is the same. Do whatever you want, as long as you test your shit. And finally remember, I told you elements are composable. And they should except children, and they should work in other things. So if your elements should be composable, and that's a thing that you care about, make sure that you test it. If you're writing something that's like a form, put all sorts of things in that form, and make sure that it doesn't crash. If you thing is like an input, put it inside a form and see that it works fine. Test your things. Cool. We're testing. We have semver. We're telling the users we're updating our elements. Users trust us. They're delighted with our elements. They're going to use them forever. We need to actually write documentation about it. Because if you don't WTFM, you can't tell people to RTFM later. So cover your bases now. If your element has any edge cases, document them. I don't care that your element is being weird, if it's in like RTL mode, as long as you tell me about it. Because otherwise I'm going to write this super lonely stack overflow post that nobody's going to respond to. And I'm just going to be sitting there. And be like, it's been 10 hours. Why doesn't this element work? Just document your shit. It's going to be great. Whew. We're maintaining our element. Everything is great. Let's talk about performance. So performance has been a big topic at I/O. Performing apps, we want fast apps, fast apps lead to user engagement, lead to more views, leads to me getting promoted and getting paid more. Everybody wants that. But when we talk about elements, performance is actually really important. Because it doesn't matter how fast I make my application. I can use Rail and PRPL and everything. If I'm building it out of really terrible and slow elements, there is nothing that I can do. Which means that you as an element developer have to be very careful about what you put in an element. Because it's going to screw somebody in a major way later. So if you think about your element, maybe it's like one millisecond fast. Let's say it's a checkbox and it takes one millisecond to paint. Because that's what we really-- oh, do one thing. Do it fast. Duh. So if you think about painting, if it takes one millisecond to paint your element, you might high five yourself, and be like, one millisecond is the fastest paint I've ever heard of in my life. I'm doing great. But if I have 1,000 pizza toppings on that page, and they're all checkboxes, you've now added a whole second to that page. And a whole second to a web page is actually enormous. We've been trying to save milliseconds out of pages. And you just made it so much slower. So focus on first paint. And make sure that the first time your element shows up on the page, is as fast as that can possibly be. Steve Orwell, on the Polymer team, has an amazing rule about this. The best to advice about how to make your element be fast, is do less and be lazy. This applies to anything that you want to be fast. Do less. Be lazy. By do less, we literally mean that. Don't do anything you don't need. Before first paint. Don't set magical handlers. Don't set magical styles that are needed maybe later. So we had this code a lot in a lot of our Polymer elements, where when the element was being attached, so when it was actually inserted in the DOM, we were updating the pointer events, to make sure you couldn't click on disabled things. And we were adding click handlers. And this looks like a very reasonable code, right? It's very short. It probably doesn't take very long to run. But again, if you do it 1,000 times, that's 1,000 event listeners you're setting up before you're painting the page. That's enormous. So what we do now is we wrap it in this afterNextRender. We do everything that's needed for paint. This isn't needed for first paint. And everything that's needed, literally the tick right it painted, we do it after the next render. And this is really great. Because now my page paints really fast. My elements paint really fast. And they're interactable, instantly right after. So everything is perfect and everything is fast. Be lazy takes that one step further. Don't do anything unless somebody actually asks you for it. Don't just volunteer to do work. That's bonkers. You would never do that in real life. I have nothing to do right now. Let me do some work. It's great. You watch Netflix. You know you do. So in Polymer we have a lot of Polymer elements. They implement the material design spec. And the material design spec has this thing where every time you click on something, it has a really satisfactory ripple that is a little jiggle. And everything is really nice and fun. So the way we were coding it up is that literally every element had a ripple element inside of it. Checkboxes, buttons, inputs; everything had a ripple. Which sounds really great, in theory, right? It should ripple. We should put a ripple element in there. It turns out that's crazy. Let's go back to my pizza topping analogy. I have 1,000 pizza toppings. I'm probably going to click on four of them. Because I've tried to put all the pizza toppings on a pizza before. And it is terrible. Don't do it. Pineapple and mushrooms don't go together. They go together with onions though. So if you're only going to click on three things, you only need three ripples. You're now creating 997 ripples you don't actually need. So we updated our code. And we do something else now where no element has a ripple when it starts up. But if you click on it, the first thing it's going to do on that clicking would be, do I have a ripple? No. Well, here's a ripple. Make it jiggle. So now in this enormous application we're only creating the ripples we actually need. We're being incredibly lazy. And this makes everything super fast. Because I'm not just creating dominoes that are sitting on the page doing absolutely nothing, not even giving them access to Netflix. Do less. Be lazy. Do less. Be lazy. This is your mantra. Tattoo it somewhere. And we didn't just come up with us one day. Well, Steve did. He woke up. He's listening to this weird podcast, I think, that tells him that. But we actually started writing test for performance to figure out how this was going. And there's many different ways in which you can test performance. And they're all terrifying. Because I'm actually terrified of everybody else's frameworks. So I have two simple ones that I use, and they work really well. The first one is console.time. So console.time takes a label, and basically between the first time you call time and time end on that label, it calculates how much time this cost. And you can also nest them. So you can be like, well creation took this long, but setting attributes took this long. And the reason why console.time is nice is because you get a timeline in the dev tools, and you can see what's actually happening here. This is incredibly fast. Because I was just doing random numbers in a loop. You're never going to get a code that runs in 10 milliseconds like that. But yeah, so that's console.time. It gives you a timeline. If you're even lazier than that, and you don't care about that, you can use performance.now, which literally just tells you milliseconds now, milliseconds now. So you can do it before and you can do it after a task, and see how long that took. And the thing that you do inside, if you want to test your first paint, is that you want to create your element. You want to attach it to the body. And you want to do a giant hack. So let's talk about this giant hack. In the same way that we're optimizing our elements, the browser has been optimizing itself. Because it assumes that we're terrible developers, which we are. So just because you're appending something to the body, it doesn't actually mean Chrome is going to paint it. Chrome going to wait to batch them. If that thing isn't visible, Chrome doesn't even care. If it doesn't affect the layout it doesn't care. And you can't actually tell Chrome to paint things. So the only way we can time this correctly is by sort of forcing Chrome to re-layout the entire page, which also forces it to paint. offsetWidth is one of these attributes that when you call it on an element as a style attribute. It has to recalculate the layout. Because it's in reference to its parents. So that's the one that I use. Pretty much anything with the word offset in it, is going to cause a re-layout. You can Google for all the other ones if you don't like it. But the idea here is that if you want to make sure your element has painted, somehow trigger a re-layout on the page. And the follow-up to that is don't do this once. Do it 1,000 times. Do it as many times as you have time for. Because if you only do it once, anything could have happened in there. Somebody could have sent you an animated gif to your slot GNL, which slows down your computer. The garbage collector could have run. The garbage collector could have not run. If you do it 1,000 times, you'll get more accurate numbers. You actually get a good answer about how slow or how fast your element is painting. And the reason why this is awesome is that now you can automate it. You can put this in a unit test. You can put it on a test that you run on every merge. And then every merge you can be like, well this element was 10 milliseconds fast yesterday, and now it's 15. And then you can ask yourself whether the feature you're adding or the bug fix you're adding is actually worth this performance cost you're taking. So let's talk about accessibility. There's this amazing quote about-- so anyhow, the conclusion here just to like bring it home, is test your elements for performance. Make sure they are fast. If your elements are really slow, I hate you. And you're going to slow down the web. Please don't slow down the web. It's really hard for all of us. Accessibility, so there's this is amazing quote by Cordelia Dillon, which is that accessibility is like a blueberry muffin. So the way you make a blueberry muffin isn't by taking a plain muffin and a fistful of blueberries and jamming them in there, and be like, I made you a blueberry muffin. You made me garbage. The way you make a blueberry muffin is by taking the eggs and the flour and the sugar and the butter and beating them together, and adding the blueberries to this raw dough and putting them in the oven, and waiting for 35 minutes. And then you get delicious blueberry muffins. Accessibility is hard. You have to do it the entire time from the birth of your element to the end of your element, in the same way that you make muffins. You can't just make an element and the last day before you ship it, be like, shit I didn't make it accessible. Let me jam some aria labels in there. You're going to make a terrible job about it. And the reason why this is important is that if you don't have accessible elements, you're not going to be able to make accessible apps. And if you don't want to make accessible apps, you're a terrible person. And you shouldn't be making apps for anybody. You should be doing something else. Thanks, you all. Rob Dodson gave a really good talk yesterday at 9:00 AM on this stage about how to make your elements accessible. And I strongly recommend going and watching it at home. It's an amazing talk. And he tells you proper, concrete things on how to make it better. I'm going to tell you two things that I got wrong, because they were kind of really easy things for me to get right, and I didn't. Focus states are a really big one. Focus states tell you where the focus is on the page. It's a really ugly outline that in the 2000s, it was really cool to set outline none on focus, because nobody really liked it. And that's really terrible. Because if you're not using the mouse, and you're just using a keyboard. You're not going to know where you are on the page. But even if you are a mouse user, if it's just you, remember the last time you had to buy something on the internet? And at the end you get to the 15-field visa credit form, where you have to fill in all your information, your shipping address, your mailing address, your name and your credit card number. And you're going to be tabbing through them. I promise you, you don't actually click on every single field. I know you. And if nobody is telling you where the focus is on that page, you're going to start typing your credit card number and your address field. You're going to get frustrated. It's already a frustrating experience buying things on the internet. Don't make it worse. Don't make bad UIs for people. I don't care whether you use this outline or a different outline, or you're communicating focus in a different way, as long as you are communicating focus in some way. You can make a nice ripple around it. Just make sure that if somebody is using the keyboard, they know where the focus is on that page. And the platform helps you with this. tabindex equals 0, whatever you put it on that thing becomes focusable. And by default, at least it gets the really ugly outline. It's ugly. But you're doing better than not doing anything at all. And the other thing is that you have document.activeElement, which tells you where the focus is on that page. Which means now you can unit test this and automate this. Make a test where you have 17 of your elements, and simulate tabbing through it, and check that the thing that is focused is a thing that you expect to be focused, and it's styled like you expect it to be focused. Unit tests are the best. They make sure that your element doesn't randomly break. The platform also gives you aria. Aria is what voiceover applications use to read HTML. There's a whole bunch of documentation on aria. I'm not going to talk about aria. I just want to mention that some elements have built-in aria like NAV and A have extra aria built in themselves. And that ARIA-LABELLEDBY is this really awesome attribute that is basically ARIA-LABEL on steroids. Because if an element already has a built-in aria label, like the native input does. It uses the aria label to read whatever you typed in it. You can't put an extra aria label on it. You can only have one. So if you want to make the native input more accessible, like say with a label that describes what it's for, ARIA-LABELLEDBY is there for that. It always adds more information to any element. So this is really important. Please make your elements accessible. Because if we're going to make accessible elements, we're going to get accessible apps. And the same thing happens for performance. If you have fast elements, you're going to get a fast app. And if you have maintainable elements, you're going to get a maintainable app. And that's really our goal as element developers. We want to make the web better. We want to make amazing apps for other people. So, that's it. I hope you got something out of this talk. Please go home and make elements. And if you do, tweet them at me, so I can see what you made. Thanks. [APPLAUSE] [MUSIC PLAYING]
Info
Channel: Google Chrome Developers
Views: 73,220
Rating: 4.9108782 out of 5
Keywords: Chrome, Developers, Google, Web, product: chrome, Location: MTV, Team: Scalable Advocacy, Type: Live Event, GDS: Full Production, Other: NoGreenScreen
Id: zfQoleQEa4w
Channel Id: undefined
Length: 33min 28sec (2008 seconds)
Published: Fri May 20 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.