Skip to main content

The Conference

CSSConf is a conference dedicated to the designers, developers and engineers who build the world’s most engaging user interfaces. The presenters push the boundaries of what is possible — talking about the latest technologies, cutting edge techniques, and tools.

CSSConf 2016 takes the show on the road anew, bringing two days of talks from experts around the community to Boston!

Part of the international CSSconf family

CSSconf Family Since the first CSSconf US in 2013, the CSSconf family has expanded around the globe. All CSSconf organizer teams share the vision of an international, diverse and creative CSS community, for which the CSSconf series offers a platform to meet, hack, share knowledge and build friendships.

Talk Videos

Sarah Drasner

Creativity in Programming for Fun and Profit

>> SARAH: Is that good? You have to do a lot of height adjustments when you're my size. All right. I'm Sarah Drasner. Hear to talk about creativity and programming for fun and profit. One of the really awesome things about being on this stage is that about a year ago I was on the stage before and I hadn't had a lot of experience speaking. Now I speak a ton. And it's because CSSconf really gave me a shot at it.
And now I'm here giving a keynote. So I just wanted to thank CSSconf and Bocoup for allowing me to be up here again. Thanks.
[ Applause ]
So creativity in programming is kind of like a huge topic, right? And there's no way to talk about all of it in 30 minutes. I'm going to talk about some of the key points that really make a difference for me and why it's even worth discussing. I think creativity tends to be something we push off to the side as being not that important. And maybe like secondary to a lot of other processes. But I'm going to talk today about how it's core to all processes. And like I said, my name is Sarah Drasner. I take being up here very seriously.
This is me as a child, as well as my relationship to authority. I am a Web technologies consultant. So I get hired by companies to come and help out with some of their tech staff, including SVG animations and component libraries.
So let's dive right in. What does it mean to be creative? Like why are we talking about this? Programming is not something that you think about and think, like, oh, creativity. But programming is, in essence, a creative act. This is a very normal kind of interview prep question, Fizz buzz. How do you write it out? Two possible scenarios. These are two functionally equivalent solutions to fizz buzz. And they look different. Every time you're giving instructions to a computer you're really communicating with other people. The compiler sees it a completely different way than the way you type it. And Kyle Simpson talks about how we spend 70% of our time maintaining code and only 30% of it writing. So this kind of the way that we write things and the way that we're communicating with each other is an act of creativity. It's the way we're expressing ourselves. The one on the bottom, only 58 characters, was a creative endeavor. That's not something you're probably going to put in a code base like the one on the top you can read and communicate with more humans more easily. So it's important to your business. When we're talking about, like, creative forces and questioning things and why we're even engaging in this, it might seem like that's secondary to business efforts, but Hewlett Packard puts a good amount of money into R&D. In 1999, $2 million and saw profits of 42.37 billion. That was a huge return on investment. Frito Lay had a cost savings of $600 million due to creativity programs. And CEOs, when interviewed say that creativity across the board is the number one thing they look for in potential candidates. Over being hard working, over being loyal. And that was a survey across 33 different industries and 60 different countries. It's also important for you.
Let's go into why. A lot of you have probably heard of the phenomenon of flow. It's complete immersion in your tasks. What I mean by that, you lose track of time. You're engaged, totally, fully in that activity. You forget to go to the bathroom, forget to eat. Somebody has to tell you put the computer down now. Shares traits with hyper focus. And people get these two things mixed up a little bit. When you're really trained on finding the solution to something, you can be in hyper focus. But usually it's not the same thing. You will notice if you're hungry, stressed in hyper focus. Pushing out code for a deadline at work, you're often times in hyper focus, not in flow.
And creative program tends to put you in a flow state. So you have a loss of self reflective consciousness and your experience of time is kind of altered. What ends up happening, people who experience flow talk about this being some of the happiest points in their entire life.
So when we're talking about burn out at a company, if you're continually programming in order to get something pushed out and continually programming to get something done and you're stressed when you're programming, you have this association with programming and this stress.
So it's actually like a way that you can fight burnout. Burnout is fought a lot of times by resting. But it's not the only way you can fight burn out. The way that your brain works, neural pathways get set, you have the joined synapse and they're firing, programming and stress and programming and stress, you lock those two things together. If you start to do creative activities, you start to refocus the neural pathways, join them. You actually increase plasticity in your brain and you can start to tie that creative and happiness and fun along to programming in a way that you didn't before.
If you have done a side project that works really well. Sometimes I did really drudgey things at work and work on something that was a side project in my spare time, and come to work rejuvenated, feeling happy and excited. And that's contagious. That actually kind of ekes into all of your program processes.
So flow plus this thinking can actually reduce stress and cause happiness while you're programming other tasks.
So I made this kind of like little silly demo. If this is your understanding of things and these are all the things out there that you can learn, every time you're pulling something into that sphere, it's actually growing your understanding. But if you try to learn too much at once, it's not really going to work, right? You're going to glaze over it. You have to focus on that activity and bring it into that sphere.
So we talked a lot about the whys. Now let's get into the hows. I'm just going to talk about my hows. I'm not going through every way you can go through creative programming. There's tons and tons of ways. But we're going to break down as many as possible in this short amount of time.
So one big thing is questioning the base premises. Another is to impose artificial bounds. Another is re purposing, another is combining, and the last one is using open source as a tool. So let's start with questioning the base premises. Because that's a really, really big one.
So when we're thinking linearly. Thinking A equals B, think of something like we reduce cost by spending less money, right? So if you're thinking laterally, okay, what if that's not true? What if we spend more money? What if we spend more money, but on fewer vendors, and place larger orders on some vendors and get bigger price breaks. The source here, if you want to read more, is igniting innovation. And more than a million dollars’ worth of savings at a company based on one hour creativity sessions.
This is happening in programming as well. So you have the Ethernet. A series of computer networks, there were token ring networks. And you can think of token ring networks, they're kind of like planned or coordinated systems where it's similar to a talking stick in kindergarten. The kid holds and talks and passes it on. It's kind of coordinated and organized. What ether net did was question the base premise of that. What if we don't wait? What if we do a completely different system? An emergent system. That's a little bit more like a discussion. Computer cans all say stuff at the same time, but if they see somebody else is talking, they kind of back off.
And this system is way more chaotic, but ended up being surprisingly more efficient. So React questioned base premises. Whether you like it or not, this was tons of weird best practicing thrown out the windows. What if we write in line JavaScript right in the component? What if we don't lose the DOM? Use a virtual DOM to be diving? What if we replace the syntax? These are base premises thrown out the window.
Sass did this as well. We don't have X in CSS. CSS needed a hero. What if we have variables and four loops and mix ins and we can dry out our code? This shaped our specs. We didn't wait for variables in CSS. They are here now, and Lea is going to talk about them later today with a great talk. But this questioning and taking action actually pushed our Web forward.
So the second thing that we can do is impose artificial balance. Sometimes when you look at a blank page or a blank state, if I was saying, you know why creativity is important. Go make a creative program. It's kind of okay. Where am I going to start?
By imposing artificial bounds you have some rules to follow and some ways to be creative. A lot of times when you have an assignment for something, you find your brain is actively thinking of new ways of working with something. So I just wrote an article called the nerds guide to color on the Web and talked about MSLA. There's hexadecimals, and all these ways of working with color on the Web were meant so the computer knows what color you're using. But HSLA was special, so humans could understand what color. It used a way of thinking about color. So H, the hue, is rotating. It's a complete circle. So as I'm scrolling this list it's just going to go around in a circle. Whereas saturation goes from zero to 100%. Lightness, zero to 100%, and the opacity, zero to 100. Similar to 1 to 100%. I can do stuff? Sass, write colors and mix ins. This was done with this color function here.
Also, because it's a full circle I can hope that my demo loads. On my local host server. What you're not seeing is a full circle of color. What's really nice about that is there's no errors. Even if I pass in 480 degrees, I'll still have a color. There's no like top or bottom. So another thing we can do with that, kind of impose balance. So I made this city construction site. Get it? It's like a Website. Bad, bad joke. I'm on a comedy stage. I got to.
[ Laughter ]
And so I can hit this button and I can change the hues and saturation values. And this one's slightly different than the other one and not exactly the same. But they're relative color mixing. So they're going to play off of each other. And I can get weird colors and set it back to normal and play with perspective and do a lot of other weird stuff because it's fun.
So and that's really simple. I'm using GreenSock in my animation. And they allow for the color mixing. Just caching the HSL, doing it relative to the color it's already at.
So another way we can impose bounds and write artificial physics. If you have made Canvas or anything like that, it's familiar to you. If you're programming in the computer and you have a thing that's got mass and weight and physics, it's not going to have actually mass and weight and physics unless you tell the computer to give it some. Luckily for us there are books that tell us those physics equations if you don't want to learn physics from scratch. So you can just use those physics equations to create thing like a particle fountain. This is done with request and SVG. Telling it to update the value on the parameters and the circles are falling. Rachel Smith has a great article, hack physics and JavaScript. She explains it in more finite detail than I will. And the nature of code by Danielle Shipman. And I have JS stroll, I do like masters copy was thing, I copy other people's work and rewrite it and request animation frame in SVG, just really bare bones.
Rachel Smith did this demo, also the answer to every software question that you can ask. And really what she's doing with the stars is updating the placement and position based on these parameters that she's changing. She's not using gravity. She's updating them on a different set of rules. Not programming every single particle that's running in the loop.
We can use recursion. It's an awesome way to make things like fractal trees. One way VI work with recursion is you check a boundary and call itself again.
The reason we check the boundary is to not run an infinite loop. We can change it a little bit and make things like this tree oh. Internet. Okay. The Internet has forsaken me. There is no fractal tree that will come up here. But fear not. There's a better demo by a guy, Gregor Adams, who I believe is writing a book on fractals.
So you can kind of zoom this screen out a little bit. Change the vertices and move them around. Change their shape. It's easy to make completely different generative code. Change it to rainbow. All sorts of stuff. And this is open source.
Or we don't have to make fractals just do like go from one place to another. We can actually make really organic things and change the color systemically like we talked about with the HSLA. And this is so re purposing. This is one of my favorite ways of working with creative technologies. By taking things that you know. You are all really smart and have tons of technical knowledge. You don't need to learn any new types.
So if I'm going to open this up I made a game out of React and SVG. And basically like it's about this hipster element that's trying to get tacos. And his friends keep texting him because they want to change plans. And that really sucks. And that makes your power go down. And this is based on real life events.
[ Laughter ]
[Music playing]
You can see this heart meet r meter is going up and down. So you can win and lose and things like that. I just made this with regular Web technologies. SVG, React, request animation frame and GreenSock in CSS. That's all I used. I could have done it with jQuery, PNGs. This is what I like to work with.
I'm going to talk about the implementation details. As Claudina mentioned, I like SVGs, you're drawing with math. Here is a component. The div surrounding the SVG, a heart meter. It's got the width passing down a number for the score. I'm not going to show you all of that logic right now. What's really important here is seeing please load. Please. There's a demo here. So imagine I have an SVG with Erect that has an X and a Y coordinate and a width and a height. Those are the four attributes in Erect. Here we go. I can just change the width of it.
Do your things. And it will update. That width will get bigger or smaller and update. So I can actually make and because SVGs are scalable, I can make the heart meter as big as I want to. I can make it a thousand pixels big and shrink it down to any size I need for the placement in the body and update the score dynamically.
So I'm using request animation frame to check those boundaries. So one thing that we have natively in JavaScript is get bounding client rect. So get bounding client rect. And I can check and see if they hit each other. And when they hit each other, I can call another function that does an animation and plays noise and does all sorts of things.
So it's actually like pretty simple to use request animation frame and some native JavaScript to check where things are and whether they're hitting each other. Request animation frame is similar to recursion. And this makes the tacos go across the screen, and the fly by, and it calls it and passes in the parameters. There is a history of generative art music before there were computers. This is cool. Mozart made a musical dice game based off of chords and things he knew already about color theory.
So you could play the dice and mix and max pieces of Mozart's music and it would generate new musical scores. John Cage in the 60s made a project called ambient noises, a similar kind of thing, but using ambient noises from outside and stuff. No two were the same. Max Ernst did this thing, automatism. The Spirograph. Point or chalk across the board, it's generative. You could make the beautiful abstract pieces before abstract art was around. And these wall drawings. Generating drawings. He's programming with the museum staff.
So thinking about this, I want to, again, play with SVG and sound. So if I'm hitting the keys. Each of the keys call different animations, call different sounds. And I'm using, again, that HSLA, so if I keep hitting some of these I can make it very dark and like a completely different way. And I really like this.
So, you know, that's like a really playful way of working with stuff that I already know. And really in it I'm just setting the coordinates of the reqs and the CY and telling it what to do when it pops. And calling a time out to bring it back to its original size. I wanted to show keyboard on mobile, but it wasn't great, so I put my palette and exposed it so people can play with it that way.
This is by Jake Albaugh, a musical chord generator. And you can change these keys. It's pretty awesome. So you can I played with this for way longer than I'd like to admit to people. So that's that's really, really cool. You should check out his work on CodePen. And Josh Ellis made this drum kit with just some SVGs and animation and sounds. Pretty neat as well.
So you already know a lot of technologies that can probably help you make a ton of cool stuff. Another thing that is really important is combining things. So sometimes two things out there exist that are really great, but they are not great like they're not perfect yet together. You can combine things that are already around.
So when we're talking about flow and how important it is for you, it's also really important for your users. Kathy Sierra, bad ass, making users awesome. Getting closer to the flow state. So the users feel like they're engaging in a task really well. She talks about mapping and cognitive leaks. This is the burner, and you have the control, which one goes where? Be change the order of this, you reduce the amount of cognitive leaks. It's not that much harder to configure. And I definitely know this one goes to this one. So I was just on a trip to Barcelona. Imagine you're on a trip and exploring a city and you want to find out what to do. Build out a day of activities in that city.
And I love lonely planet, it has such good content. They write really, really amazing reports and have great reviews and tons of great thing to tell you, they point you to great sites if you're not familiar with it.
But go here, and then go to Barcelona and then the sites. And Sagrada Familia. They show a pub and a church nearby. But maybe I don't want to go to one of those. Or I want to eat or something. That doesn't give me much option. I have to go to Google maps and look it up and do another thing. Or go back to sites and see if one is nearby, and compare the two maps in not great. And the food and drink section which looks totally different.
And down near the bottom, explorer map section. Okay. Great. Explorer map. It brings up sites which you can see. But you can only look at the site, not other things in that area. So not too great for planning my day. Google maps does something that's great and also also great but not exactly on the mark either. So if I already know the site I want, I can look it up, that's great. But then if I do restaurants nearby, like I have this map of all the restaurants nearby. Great. I can send that to my phone or something like that if I find one. But if I want to find a bar for later, I have to go out that of that and I lose all of the food and I'm not sure if they're near each other, and I'm not sure where it is anymore. I have to send each one to my phone. Their content is not great. These are the reviews on Google maps, a Google user five years ago, five stars. Cool.
So let's empower the user by combining a couple of these things. So in this demo I kind of like was just doing a prototype of what I wished that I had. Come on, demo.
Oh, the font it okay, there we go. So we can search through these, we can pick the different foods and we can kind of read through them. And then we can send it to our phone and create an entire itinerary for our trip. I'm going to do that one more time because we kind of like are really small here. So we search for Sagrada Familia. We look through sites, decide if we want to choose the destination. Look for food, and choose between choosing the destination or between choose and send itinerary. So it works a lot better for the user. Like that is actually what I would have wanted. And those steps are a lot easier to manage.
So the last thing is to make use of open source for tooling. I made this demo that's like A frame and React. That's repo. So this is just spinning up a bunch of, like, VR objects that I can look at with the camera. And what's really cool about this is it's a fairly small amount of code because I'm basically resting on the shoulders of giants around me.
A frame is an awesome tool by Mozilla where they have these kind small kind of like spheres and boxes and things that you can overlay. And they're just HTML elements that you can plug into. Really, really easy to work with and super awesome. There's another tool called A frame React where I can use ES6 to make a ton of different things. Here are some of the functions I'm calling where I can spin up a bunch of these objects. So that's really, really great.
Even this first demo about your understanding is not the first time I have seen something like this. I'm pulling this in. This is by Tiffany, who's active on CodePen and she made this GUI object. You're kind of pulling it back and forth together. So I saw her demo and I was inspired. And she saw this demo. Which strangely works. And this is on another site.
So you can change the viscosity and the color here. And they were inspired by this demo. By Lucas on CodePen as well. Even though they look similar, they're all built with completely different technologies. Some made with SVG filters, some with canvas, some in draggable. All are really, really different. None were forked with one another. And I took that GUI idea and created a candle out of it. So it doesn't have to look visually similar either. The idea that SVG doesn't have to be straight lines. That we can actually take filters and like animate those as well. So actually you can't animate a standard deviation in a facilitator in native CSS, but you can do it with animation frame. So I'm just tweening that attribute here.
Social coding sites are awesome, help you learn and stay inspired. I made a CodePen propaganda poster. Because in soviet Boston the CodePen was loaded with you. I don't work for them. I'm just a nerd and I like making things like this.
And, you know, just to recap, creativity, some base premises, question the base premises. Impose artificial bounds. Re purpose other things you know. Combine things that are already out there and use open source as tools. You don't have to start from scratch. The impact this kind of creative work has on your life makes you feel happier and more productive in all sorts of environments. And you become a more pleasant human being to be around when you are at work. When things get stressful. And your co workers will thank you. And Val Head and I are coming to New York and Austin. And I'm also write a book called SVG animation. This is not the cover. This is my friend trolling me. I don't have the man blog animal. That's not thousand spell my last name. I do, however, have a fancy chicken. And this book is available for pre order, and also coming out at the end of the year. Thank you for having me.
[ Applause ]
>> CLAUDINA: Over here while our next speaker gets set up. This is great. So you love to make weird stuff on the Internet. Which is obvious. And you have an amazing CodePen you were talking about planning your flow and combining all these things. Can you talk a bit about how you got yourself into this and how you just started creating?
>> SARAH: Sure. I can yell. I actually have a kind of dual background in both like tech and also art. So I was a college art professor for many years.
So and I've also been Dev’ing for the Web since 2000. I think for me it comes kind of naturally to think about both. And I enjoy thinking about both. But I do think that most of the time at work I'm kind of in the like I've managed giant component libraries where it's very just like thinking using like technical ideas constantly all day. And definitely creative. But parts of me were really, really rejuvenated by some of the projects I did on the side. That was the thing that got me excited about programming in times when I started to feel a little bit burnt out. Even when a vacation didn't kind of help with that.
>> CLAUDINA: Yeah. I was noticing on your site, you were talking about those things that got you excited, that was the path to pursue. And one of the things that led you. And now you're truly doing what you love. You're passionate.
>> SARAH: Yeah, I'm doing a lot of Web consultant work nowadays. Yeah. I basically get to go around and talk to people like you at conferences like this. That's awesome.
>> CLAUDINA: Awesome. You talked about GreenSock, for those that don't know it, can you give a little bit of background?
>> SARAH: Sure. It's an animation API. I think it's a good one. Allows for a lot of cross browser stability. So if you're working in a production level site, it's really, really great. And they have a ton of plugins and things like that. I also did benchmarks for a bunch of different SVG animation technologies a couple years back. That's a couple years ago. So you should be running your own. The Web moves a lot. I found it was performant as well. That's why I use GreenSock for a lot of projects.
>> CLAUDINA: Thank you very much. Another huge round of applause.
[ Applause ]
View Slides

Brian Jordan

No Bugs in Sight

>> BRIAN: Thank you very much. Quick show of hands, how many of you have heard of or use code.org? A smattering. And a show of hands, how many of you had ever used or like investigating a test framework? Selenium or phantom JS? Okay. Good company today. I'll be talking about our journey starting to visually test stuff at code.org.
Before that, for a couple of reasons I wanted to quickly tell a little story how I got started with stuff. This is me and my three brothers, four boys. Poor mom. She was always hoping for a girl. If you can guess which one I am. Hard to tell. Left? Right. I'm the one on the way right. I'm the youngest. I was the last straw for my mom. She gave up. She's very happy now that she has daughters in law. That made up for it. This is me.
We were fortunate enough for two reasons when we were younger to be exposed to computer programming. On the one hand we had access to computers when we were younger. My dad started out his career doing programming, software work. We had computers around, super old computer there. I used to play DOS games on it. Anyone recognize this browser? Fortunately or unfortunately. Fortunately for me when I was 10 or 11 or 12 I noticed there was this button in the browser that said edit. Like I don't know if any other browsers I've seen since then had an edit button. I had never done any programming, I didn't know you could make a Web page. I saw the edit button. I clicked it. Actually, I was afraid to click it. I was on a big Website like New York Times.com or something. And I edit it, am I going to get in trouble?
I was pretty sure if I edited the page and clicked save it would change the Website. Which was both exciting and terrifying. I clicked it and made the change and refreshed and it was gone. So I was upset. So I got more and more into making Web pages. My brothers having older brothers who had gone into tech stuff before was very helpful and they were showing me how to style stuff up better than the Netscape editor. And started learning HTML and a little bit of CSS. This was a Web page I made for a sport fishing charter company I met on an AOL chat room who paid $25 for me to make a Web page. Which was probably a good deal for me. I was getting into the Photoshop, the layer filter effects.
And also, of course, the nice table based layout. I miss that. But it sounds like we're getting back to the ease of that now with the box model and everything. So yeah. This was my first CSS. And it was probably a snippet I copied and then changed some stuff out. You'll notice the mismatched capitalizations of the style tags. I have never sure if it was supposed to be all caps or not. Some nice weird semicolon usage. So anyway, the point of telling you all this then when I was sitting down to make an AIM as, you know, this is very popular back in the day. You had to have an AIM user name, I was trying different names. Brian Jordan, it's taken. This thing, it's taken.
I love turtles. I was like obsessed with turtles. I think I wrote some report about turtles. Turtle, taken. Turtleman. Taken. And then I thought what if I add that cool magic language I don't know how to use yet. CSS. That's my name, turtle CSS. I'm just telling that story, I'm really excited to be at CSSconf.
[ Applause ]
It's super cool knowing if there would be a room of people that knew about CSS and I would know a little more CSS I would be like, what? Back to the talk thing.
This is me and my brothers. Ultimately we all ended up taking different paths and ended up all now doing programming. It was it just makes me think I think now and then, jeez, what a weird, like, series of coincidences or just like luck or privilege to have to be able to have access to the computers and to be able to learn to program. Like none of our schools had any computer science classes the entire time.
You know, people who also had computers just never ended up having the opportunity to learn to program. That brings me to oh, yes. And I wanted to plug a talk. Alisha's talk tomorrow at the end of the day I think will be a deeper dive into the those sorts of efforts and what you can do to help that.
So what I do and actually those two other brothers of mine also now work me at code.org. Which is funny. I wouldn't recommend working with your siblings. It's okay sometimes.
Code.org. We're a non profit in Seattle. And we are expanding the participation in computer science. We feel the best way to expand the participation of computer science is to bring computer science into schools and be taught next to algebra in K 12. Computer science wasn't seen as something anyone could do.
Computer science there weren't create curriculums available for K 12 yet. Teachers didn't have the expertise to teach computer science or feel confident that. There were a lot of problems. States didn't count computer science as a credit.
We have been tackling it from every angle. One of the things we did, the Hour of code. A yearly event. Teachers, run one hour of code with your students. It's a little bite size chunk. And it's puzzle based games that students can play. Learning sequencing and loops. Just event handling and some basic concepts using drag and drop blocks to start for the younger ages.
Here's a little video that kind of shows it a quick one shows the other pieces of what we do. So many different pieces going on with it. So this gives a nice overview of the teachers’ trainings. All that sort of stuff.
[Music playing]
So, yeah, the funny thing is a lot of people haven't heard of code.org. But it's getting into a lot of schools. Like if you have nieces, nephews, sons, daughters, you can ask them, they might already be doing computer science in their school. Or their district might be planning on doing it. Most people just heard of code.org.
So this will give you an idea of what we're going to be testing. So students used our tools to make these apps. So they can make little games. Fun little stuff. Even fruit keyboards. It's pretty sweet. 40,000 teachers have been trained. Those are some of the teachers. Having completed the training. And we have a bunch of school districts. A lot of the largest school districts. Inner city school districts signed on to implement computer science across their whole district. K 12. It's pretty sweet.
75% of schools still don't cover computer science.
All right. So let's talk about how to test this. And I'll talk about if you're interested in volunteering. We're all open source. So yeah. We're working on a full curriculum, district partnerships, professional development, policy change. Fortunately I don't have to do all that have. I work on our K 12CS curriculum. That's what we'll be focusing on testing today. 300,000 teachers I think it was 40K. A lot of people using this stuff. The cool thing is we're in schools and during the school day we have a student population that reflects real population. Not just people who have computers at home or can make it to an after school program. It's actually in the school day. So that's very cool.
So how did code.org start automated testing? 2013 2014 was the first code, I was not there at that point. I joined early 2014. As you imagine when you create a new thing very quickly and push it out to production to a lot of people there's bugs that come up. And as we see, we use a lot of not leading edge, but leading edge for school computers technologies in our tutorials.
So, yeah, there wasn't really so much testing. So why would we test? Why would we invest the time to and yeah. The time and infrastructure to actually set up automated tests? I think the automated tests aren't necessarily for every team or, you know, the full cross browser test. I think you want to think about what are the use cases for it? What are the things that break? How bad when things break? In our case, pretty bad when things break. We're not doing financial stuff. But think about it, we're in schools. Used day to day in schools. You have teachers who yeah. I don't know if you've ever, like, been in a classroom. It's kind of pandemonium. We'll go in. The teacher will come in, get the kids all set up on the computers. Take like five, ten minutes. I got to log in. Press the button. Teacher, raise their hand, go over to them. It's pretty stressful.
When, on top that have, they say, teacher, the level's not going forward. Or this page isn't loading. It's it makes everything way worse. And it's super stressful. I have seen that in classrooms before. Very rare, of course, now. And, of course, schools. If you remember schools. Schools have quite a wide array of situations.
I remember yeah. I9, we got Chromebooks, iPads, a mix of everything. This one issue, doing the hour of code last year. A little tutorial. It's kind of like a 2D path. And you programs Steve or Alex to move around. I got this bug report. It was like two days before the hour of code. Like millions and millions of students and teachers are about to use it in their classroom. And we get a support request saying whenever whenever we go to the Minecraft Hour of Code page, the browser closes. The browser closes. Oh, my god. That's the nightmare. I was on the hook for that. In a day millions and millions of people are going to, maybe, I don't know, have their browser close. I needed to figure this out.
I was testing it on every browser. They weren't specific in the first request. I think they may have said Chrome. And they just said is it just is it the other tutorials? Using a new game engine, Phaser, very cool game engine. I don't know what might have been wrong. E mailed diagnostic stuff, try a different browser, try a tutorial.
I was just so confused. The Minecraft hour of code would close in every browser, and not the tutorial pages. So finally it dawned on me I think the night before the hour of code. I'm having nightmares about this. I e mail them and I say, can you try going to Minecraft.net. Oh, that closes too. It sits and closes the Web page if it says Minecraft anywhere on the page. So, I said, yeah, there want wasn't much I could do to excise Minecraft in our source. Maybe ask the ID department about that. So, yeah, weird stuff happens.
Also, we support a lot of languages. Like 40 plus languages. Including right to left mode. Which we take to kind of an extreme where we actually flip the entire layout of the page over so the run button's on the right, still toward the area, and the blocks the drag and drop blocks can expand out that way. And, oh, yes, as I alluded to, bleeding ish edge technologies, Canvas. Not so much leading edge. But there's a lot of different browsers and you can find when kids are clicking around and dragging stuff. Using it.
So see right here yeah, you can see like the drag and drop blocks out to program that. Think now, how would you test that? How would you make a sweet testing robot drag those things around? We'll be getting to that. This is called App Lab. I love it for creative programming, actually. Where you can drag out interface elements, write that stuff, and then create JavaScript events. So this is for our late middle school to early high school. So they start out with the drag and drop box in the earlier grades and later on move on to this.
And that actually you can transition from blocks to text there. So you can you got to get the goodness of self documenting blocks and transfer to text. How would we test that? So many things to test. Let's get started.
So yet it's kind of daunting sometimes thinking about how do we actually get started testing on my project or at our company? Because it's like what do I invest like a month and, you know, say, like, okay, we're going to do this thing. We started very small. The founder of code.org. We works with a bunch of companies and advises companies. And they said they would they said you guys are having cross browser issues. Check out the cross browser testing. I knew nothing about it, the engineers didn't know about it. And Brendan set up a test. Hitting a few browsers and going to a page and running that. So how are tests organized and run? When Brenden first implemented it, we had it use Selenium Web driver. Which selenium is kind of the lingua franca of telling browsers what have to do. And we use cucumber as kind of a higher level language. Like DSL language where you define your own steps to just kind of make little reusable snippets of steps.
And I learned there were other patterns for doing this, like a page object pattern. Like I have gotten called out for not using that before. But this works. And it's kind of cool.
So, yeah, we have features. It's our big list of all the testing that we have. Step definitions where it's like, like okay if they say click on this, what does that mean in the code? Use the browser object. Do that thing.
So this is what one of our tests looks like. So you're you basically say given I'm on this Web page. Go to the Web page. And if you're running on a different host, it will point to a different sub domain. And we're testing on iPad simulators. Some of the browsers have real device testing which we have not explored. But that is interesting for native stuff. Wait to see the dialogue, close it. And that element is there. And drag blocks to blocks, press the run button. Et cetera. A bad habit of ours, we often make cucumber steps that say selectors. You're not supposed to put selectors in the cucumber text either. But it works.
So the takeaways from doing that stuff, yeah, so building up a library of steps is actually pretty useful. Because you're building up very reusable pieces, especially if you have JavaScript you have to trigger on the page, or some assertion you want to make about something, you can build up reusable steps with cucumber. So in this case, you can drag block A to block B. Now in the step you have to write that, don't have to reference JavaScript or know too much about the stuff underlying it.
The other thing we learned was don't test on production data. That's going to change. Our education team is going through editing levels, adding levels, changing the order. So set up separate test data. Even better to have it programmatically set up. We use our own editing pipeline to set up test only levels. It's a smattering of levels on the site. Also a handy page to use if you want to do some annual testing. Oh, here's everything on our page.
So something that would be useful if you have like a style guide, a set of partners that your team uses for visual stuff. Well, we'll get to visual testing in a second. But I think that's a good target, maybe, for nothing is point your tests at. Other cool thing, annotations, cucumber lets you flag tests on and off. Don't run this on IE because we know it's going to not work. Or sometimes the Web drivers have their own issues. You want to flag that.
So on our team, who writes tests? So on our team we because we just kind of got it started when the immediate need came up, we all kind of did our part to set up the system and write our own tests. So everyone on our team writes these tests alongside their features. Or often times after the feature's done. There's a bit of thrashing when you're writing a feature like that. This worked out pretty well. I worked somewhere previously there are dedicated test engineers. And that would be nice and neighbor save of the problems we went through. So great for the people in test automation.
We run the test when you're developing a test. But you actually run it, so in 2015 we had one pipeline of tests. There was a server sitting there, oh, to get update, cool. Let's run a build. Spit out a bunch of stuff on hip chat. We would be sitting in the hip chat room and watching it come through. Now we're on Slack. No longer only run it through one machine sitting there with get updates, if your tests take a while, you have a lot of people pushing code in, then it's going to get backed up in your tests. You won't find out about what broke until later. Now what we have going on is UI tests, across cross browser tests for every single commit. This is using circle CI. You set up a little file that says here's how to build my project. And then the last step there, run our tests against this version of the project. And then that gets running. It's I think yeah. I'll talk a little bit more how awesome that is. But I can't say how awesome it is to have it run for every feature, versus buckets of failures. Eight failures. Look at the big list of commands. Who did what?
What challenges did we end up facing? Yes. Addressing the challenges I alluded to earlier. Multiple browsers. We support a lot of browsers. What we use is that Selenium Web driver. Because it's kind of got that lingua franca sort of factor of pointing to different browsers. We can point it at any given browser, we use sauce labs, a cloud provider of VMs with those browsers in them. So you literally say just point your Selenium test in the configuration of the URL. You can say point to sauce labs, give me this browser and the tests start running and they deal with all the stuff behind the hood.
There are ways of setting up your own cloud, but it's nice to not have to maintain that. And they're always adding new browser are support. This is our browsers.JSON file. The list of the different browsers we want to run against. So some of these are the Sauce Labs identifiers. You can say what operating system you want. You can say what browser you want.
And then when your tests are running you can even see they record a video of the test running. If there's a failure, okay, what actually happened during that run? Adds a little nice ability to debug that. You're writing a new test, or locally change something. A new feature that you know is going to break a test. How do you test that?
So if you're doing it locally what you can do is use Chrome driver in our case. Where you point the test at a local browser and it'll actually pop the browser up in front of you and you'll see the robot doing stuff. It's kind of fun. I'll show you a video of ours in a second. And we use sauce connect. If you want a remote browser to be hitting your machine. It's like an SHH tunneling tool that lets it hit your machine. It has fancy things, it caches stuff on their end so it's a little bit faster. None that have back and forth stuff going. And pull requests. I love pull requests.
This was my holy grail. I'm glad we have it. We just got it in the last month or so. Now our UI tests also run on circle CI and will tell you when your stuff broke stuff. And so you don't have to worry about those buckets of failures anymore.
So how about drag and drop? The standard selenium drag and drop didn't work for us, we ended up using jQuery simulate. Happened to work it our SVG based drag and dropping editor. Visual responsive changes. That's the cool thing.
So in last year or the year before I was doing a hack a thon with our older brother. We got into a hack a thon and I was trying to think of a project idea based on what's a project that would be really useful? What's a pain point at work and how can I fix that? And I was thinking we just had some bugs, button, and a second button showed up. How to test? There's going to be one button. It's too many steps when you're writing the individual, manual steps. And looking into who wrote what when, finding that out later from users or the CEO is not very fun.
So I figured, hey. What if we just I thought this was a super unique idea. What if we just took a screenshot of the thing and then compared it with another screenshot of the new version. Turns out a lot of people had done that before. I thought it was cool at the time. We found a tool during the hack a thon. I think it was called PDIFF that lets you over it'll kind of show you it'll detect what percentage of the pixels change. And kind of provide a cool view of what changed in between the two things. So we set that up. It was still a pretty cool tool. You literally put the URLs in and press run. It was cool.
But it turns out it was really hard to do that right. Apparently when you take screenshots things change that you wouldn't expect changed. Like sub pixel shifting of stuff. And it depends on like the browser's operating system renderer. Yeah. You see a lot of weird stuff. And also if you have something randomly changing on your page, you have to deal with that.
Turns out it's an actual thing, though. So there's something called Apple tools that we found after. It was like, ugh, why didn't owe tell me about that? So Apple tools, they're doing just that. They provide an API that lets you compare the images and adding more regions and everything like that. So actually in our case it was because we had the selenium test set up, and on top of the Selenium Web driver. We have the new steps, eyes.open. And we had a new cucumber thing here. Step here that says I see no difference for this. And that's basically a tagged baseline. A tagged image. I see no difference for the home page. If says, cool, check the last version of the home page. If it did break, then it'll throw it'll be upset.
So here's an example of one of our features that was converted to an eyes feature. We mark it to say make this stuff available to run that. And I say when I open my eyes to test this thing, go to the thing. Flip around. Still using Selenium commands. And at some point I say and I see no difference for blank game screen. Takes a screenshot at that point and gets ready for review. And cucumber has this thing, scenario outlines where you can write URLs and write the same steps for all of them.
So, yes, ignore regions. As I alluded to. Things change on Web pages pretty often. Rotating screens. In this case a random assortment of angry birds tiles on the screen. You basically draw you click this but then and draw an ignore region in which you want to ignore changes. When there's a failure, something changes. Here's an example of a failure. This button is showing up when it shouldn't be showing up. There's a version of this that has parameters and a version of it that doesn't have parameters. And there was some inheritance mix-up there that caused that issue. But we caught it before it broke the tool.
This is kind of the interface. And here was another example of the failure where the step button showed up when if shouldn't show up. And that was present on a lot of different steps in that same test. So you can kind of tab between the different steps there.
And yeah. Other thing is they also when you use the phone version of it, it'll show the top bar of the kind of the whole simulator and screenshot based on that.
So what did the test look like when they are running? We'll do a little bit of this speed run. See how I am on time. All right. So yeah. I just found this so cool. So there's a computer. This Selenium robot is sitting there learning how to code. So it's code that's learning how to write code. I just think that's kind of cool. That's silly.
Yeah. It's kind of fun watching your site get used very quickly. Cool. So wasting time. We're not wasting time. We don't want to waste time. Time is valuable. We can do things with time. So one thing that sometimes will happen is testing if you write a couple tests and it's like, oh, two minutes. That's fine I can do a minute long test. I can wait for that. And the team is writing tests, and you're writing tests. Suddenly the test suite is 60 to 90 minutes. And you're not going to run it very often, and the buckets are going to be larger. We started parallelizing the test runs in the test runner.
So you can basically say run this at parallelization 50 and spin up 50 browsers all at once. Telling them all what to do at the same time. All hitting your same server. Actually, oftentimes the bottle neck is your local server. It's getting hammered by a hundred different VMs. So in 2015 we got back down from 60 to 90 minutes back down to 20 to 30 minutes. Still around there. Oftentimes when we're having team retrospectives and it's like, what sucks about being our on call person or looking through the failures? Oftentimes people question the premise, why do we have tests? What if we just didn't have the tests? And sometimes it's hard to answer that. Or what if we just cut out Firefox or Safari. Aren't all these issues going to be the same? We're using jQuery. It will sort itself out.
I'm racking my brain, I could have sworn there's a FireFox bug or something. We started keeping a bug tests caught Wiki page. It's like a trophy for the bugs you caught. Nice thing about being an open source project, we can show you everything. Here's an instance where a button went away. Here's an instance where the button got taller, randomly. Here's an instance where this weird margin white margin got added to the right of the tool. It's like, that stuff used to happen all the time. And it's nice to get notified about that early.
This was a funny one. So there was some kind of like rejiggering of the whole of some of our top level styles. And overflow hidden ended up applying to this text up here. So if you can see the words are kind of getting cut off.
If I was just clicking through I might not even notice that. But we caught that one. Here there's a duplicate. It is tough to catch without the visual stuff. And here's one where there's one tiny gray pixel that
[ Laughter ]
I don't know how that happens. We figured it out at some point. It catches all the kind of little stuff. Here was a big one I caught. This was bugs still do happen, especially when you're using SVG. Yeah, the box when it’s hidden, blows up. And Chrome 50 did 50GL. Caught that one. And here is my favorite bug ever. Let's look at these two slides and imagine you're doing some manual QA on your site. What's the difference between these two Web pages? There is a scroll bar. But why? But why?
See that text down there? Yeah. And see actually even above there, stuff's getting shifted down too. The line height changed everywhere.
[ Laughter ]
The entire Website's line height was changed during a routine refactoring of top level styles. So we caught that.
And yeah. I'm pretty certain if we didn't have these tests in place we would still have that our Website would be just slightly longer forever.
[ Laughter ]
Who investigates failures? We have a Dev of the day. When failures come up, triage and stuff. It's not pleasant to be Dev of the day. Didn't used to be pleasant to be Dev of the day. It's slightly more pleasant now. A big bucket of failures, you have to figure out what caused them. So you're looking at any random failure from anyone's code from that entire day. And then you have to figure out who broke what and then make sure that they get their fix in before you do a production or revert it.
Now that we have those pull request tests, you don't have to do that. Because it just doesn't break. Because the yeah. Now that we're running every pull request, before you get the pull request, you check to merge it.
What's next for us? Get the test results out of the GitHub comment. In the branch. If you want to learn about cross browser responsive requests, Dave has a sweet introduction to that. You can see you define with resolutions and browsers to do that.
Some takeaways. Start small. Everybody test. Don't have to do that if you have someone to test. Maybe not everyone has to test. But worked out very well for us. And periodically speed up.
I think to thank my team who shared on that, and, of course, the folks at the various providers that we work with. Thank you. Yes.
[ Applause ]
>> CLAUDINA: All right. Let's have some Q and A with turtleCSS here. I'm not going to reveal my first
>> BRIAN: I thought mine was pretty good. Now that I'm here.
>> CLAUDINA: You got to bring it back. All the way. So we did have one question. Some folks are saying they have used Selenium for testing before, and find as applications change the tests become really fragile and difficult to maintain and they frequently have to be fixed. How did you avoid this at code.org?
>> BRIAN: The one tip that was having a separate portion of your site that don't crash as much is helpful. And then I think also making it okay to break tests, making the workflow for breaking tests a little less painful. I think that made a big difference for us. Yeah. It's when you find out about the test a day or a week later it's extremely painful to find out who broke what and what they did to break it. That mitigates the pain of having tests that are more fragile.
>> CLAUDINA: And I imagine when you decided to write tests, everyone has to be writing it and has to submit tests. How did that become part of the culture and day to day?
>> BRIAN: That's a good question. The way we started out is a couple people everyone is kind of dipping their toe in the water. There's a new project, new file, new steps to try to run tests locally. Maybe run this feature, oftentimes if something breaks a team member will say, hey, don't we have a test that covered that? Or what if we had a test that covered that? You'll say, okay. And write a test that covers that. Yeah.
So it kind of grew from there. And you don't want to accept a break. And if you could have prevented it by writing a test. Probably should have written a test for that. Kind of ends up being the owner of that. Works for our team. We have separate areas of ownership. Like features.
>> CLAUDINA: That's great. Wonderful. Adopt this through, and you're bugless, keeps everyone on point.
>> BRIAN: Fun list of all the bugs we caught. I like that.
>> CLAUDINA: All right. Well, thank you so much, Brian.
>> BRIAN: Yeah, thanks so much.
[ Applause ]
View Slides

Jessica Lord

Nativize Is the New Normalize

>> JESSICA: Hello! Okay. Cool. All right. I did finish architecture and urban design. But clearly left. So whatever. Hi. Whatever. We've already gone through who I am. Hello. I did work for the city of Boston and I did live here and I do really love Boston. All right.
So the longer is this I don't know I don't know if I'm talking. Oh, that's better. So the longer version wow. These are totally stretched out on here. But that's fine. Probably. The longer version of my talk title I felt really bad about this talk title. What a bold statement. I feel so bad. It's nativize is the New Normalize: when Websites become desktop apps with Electrons. So that's the caveat.
Because really what you're trying to do is make an app that's made up of Web sites feel native and not feel like a Website.
And before I dive into that I will I'm glad that I saw the hands go up who knew about Electron. I have really no idea because like everyone's going to know about Electron. This is old news. But I think this will be helpful to give a little background.
So Electron, this is the blush about Electron. It is a library for creating desktop apps with Web technology. And we can break it down a little bit more. It's a library for creating desktop apps for Linux, Mac, and Windows with JavaScript and CSS. It was totally open source and created by GitHub. It's what GitHub's ed for Atom is built on. It was built for Atom, and open source along with Atom. Now its own project with its own team and really growing community around it. So it's maintained by a small team at GitHub. And then a lot of contributors.
There are a lot of individual contributing to Electron core, and there are a lot of companies now building their apps on Electron that are pushing a lot of changes upstream.
So what is going on on the inside of Electron to make it be able to do what it's doing is it's combining these three elements. And so what I want to make clear is Electron is not a Web view. It's not just a wrapper a native wrapper around a Web view. It's actually a way to fully make a native app that's really integrated with the desktop.
And it does this by combining Chromium for drawing Web pages, Node for accessing file systems and networks, and then Electron has its own set of native APIs for doing operating system functions for three different operating systems.
So the Chromium part. Electron is using the Chromium, the open source version of Chrome. It's using just the part of that knows how to draw a Web page to paint elements, turn HTML into the visual things that you see.
So when you're working with Electron you get the complete DOM as you would expect. And you get everything that ships in the latest Chrome. Which right now Electron is on 53. But it's soon to be on 54. Usually when a stable Chrome releases it's about a week before Electron updates to that Chrome.
And then you get all of Node. And so this is the really, like, magic sweet part. Is that Node is available everywhere in Electron. Even in your HTML. So when you're writing a script tag in your HTML, you just write Node. There's no flag, no setting or anything. You just write Node as you would write client side JavaScript. It's cool. You can access the operating system, you can access the file system and immediately update the DOM. There's the native APIs. Electron makes available the APIs for all the things you want to do to integrate for the operating system. An open file dialogue, there's one API for that. Electron does the work of figuring out if they're running on Mac or Linux. You just have to use the one API.
So in whole Electron is a lot like making a Website, but only have to care about one browser, the latest browser. And getting to use Node and operating system features. So Electron apps are made up of HTML, CSS, and JS files. And there's a lot of overlap for designing for Electron and designing for the Web.
This is the Electron API's demo app. It's not as stretched out. But this is an Electron app demoing the Electron API. It's something our team made. It's open source. It's in the Mac app store because Electron apps can be in the Mac appear store. You can also download it. But it's a great way to get a sense of what are these native things that you can do with Electron and explore the source code for the app itself. It's a nice basis for an Electron app.
You might be using Electron apps. Atom is an Electron app. Slack is an Electron app. Visual studio code, Microsoft's code editor, brave, a browser built on Electron which is built on Chrome. And Pixate, which is a prototyping tool. These are just a few we have on the Electron Website, which is open source. We have a page for anyone who wants to add their Electron app to that page. They make a pull request and add their app. There's something like 200 apps on that page now. But all right. So.
We rewinding back to the whole point of the talk, how do we design for this new environment where we're creating an app with Websites but we want it to not feel like a Website at all. This is something that I feel like a lot of teams are figuring out piece by piece, on their own.
Normally I give talks about a lot of JavaScript side of building Electron apps. And there's a lot less out there about actually all these all these gotchas what you need to do to remove the Webiness from your app. This talk it about removing the Webiness. Because even though you don't have to support multiple browsers anymore, that feels huge. You have to support multiple systems. And so there's also gotchas around that.
All right. So the first broad category of things that I'll talk about are design things. The first, nativize your CSS. Nativizing is doing these things in CSS that you would never do to a Website. Or, I don't know, maybe you would. I don't know your style. But you don't want your app to feel like a Website. So no selecting, no dragging, no gloves. If you think about it, when you're using a desktop app you can't select the text. You can't drag your button off the screen in your desktop app.
And buttons don't get the glove cursor. They don't have the glove. They have the normal pointer. Straight off the bat you have to do these weird things like turn you are a selection. Also, no dragging images. You can't do that in the desktop world. Then unless you need these things. So in the Electron API demos app we have a link here that goes to an it actually opens a link in a browser. So we wanted that to have we wanted to differentiate it. So it has the pointer. But then this button doesn't. The button has the default cursor. And we have code samples and we want you to be able to copy so they have to be selectable. So the rest are selectable. So we have the selectable class and make the code selectable. So links are pointers.
Another thing that is a nice snippet is to target all of your external links because your app will have a lot of internal links, probably. But in Electron, HTTPS or HTTP, you can target those and think about accessibility and differentiate your links that are opening in another application, another window.
Also, no rubber banding. So it if you think about when you're in a Website in Chrome and you try to push it down, you get that bounce at the top. That's the telltale sign this is a Website and not a desktop app. So you got to take it out. If you do need a scroll bar you can create a container div. But in general to stop the whole page from rubber banding at the top. This is another snippet of nativizing. All right. So after you've done your basic nativizing you I'm feeling really bad saying that word now you start to think about your app's actual UI. So Electron provides you for opening dialogues, using the native notifications and things like that. But your actual apps UI, that's totally up to you. So you can emulate operating systems or follow your heart and create a whole new UI. And the first thing your users are going to see is the window of your app when it launches. And that's when you can start making decisions how your app looks and feels. You'll see I have four windows over here. The first one is the default one where you get the Chrome at the top with the traffic bar lights. That's default.
But you can choose to totally remove that and set the frame to false and have a frameless window. On Mac you have a couple more options for the title bar style. You can do title bar hidden and hid inset. And the only difference is the traffic lights are positioned in a slightly different way.
But that gives you the ability to kind of push your app full bleed. But not have to implement the traffic lights yourself.
So you make the decision when you define your browser window to set the frame to false before it shows. And you can do things like also make it transparent, so you can set transparent to true for your window. And then if you set the HTML and body to a transparent value, then you get transparent window, which could be nice depending on what your app does.
But there are some major caveats to using a frameless window. They look really nice, but you have to roll your own tool bar UI. It's not hard, you know, on click.window.close. But you are making your own traffic lights. You need to create a draggable region. Frameless windows are not draggable. And they need to be non selectable. You don't want people to be selecting the title bar. And then you need to make sure you don't have click events trying to happen in areas that aren't draggable. Just note. But it's possible and people do it. I have a link down here to a longer page about how to set up a frameless window and catch all of these things.
This is the example of an API demos app, uses the frame and gets the title and the traffic lights.
Slack. This is Slack using the hidden inset and pushing the UI to the top but keeping the traffic lights. A couple more examples, hyper term is Electron based terminal app. And you can see both of these apps are using hidden inset and you have the bash title there. That's the kind of thing you want people to not select when they're trying to move your app around the screen. And then Web torrent is creating a it kept the native traffic lights and implemented its own tool bar UI.
So once you go beyond the frame then you have the actual UI itself. This is vector which is an Electron app that is creating a totally custom UI. Like they even have custom traffic lights and all of the buttons obviously aren't specific to any operating system. Another one this is simple note, which is by automatic. And it's a really minimal UI. But then you can emulate the operating system UI. So this is Nyla's N1, a mail app. With their tool bar, emulating the native tool bars and native Mac styles with their buttons. And then do the same thing on windows. You can see the icon, the new mail icon changes. The icons look different. It's flat and white. And you can swap this out with classes and that's what they do. So because you have Node there you can just check what platform the user's using and then add a class to the body and then toggle between Mac and Windows UIs.
You can even go further if you want, there are APIs in Electron to let you know if the user is using dark mode on Mac or what the accent color they're using on Windows is. This is an app called timestamp that is doing that. It runs in the menu bar, but looking to see if they're in dark mode, and if they are, it updates the UI to match that.
There are some tool kits if you want to do the native UI route. There's one called photon. If you want to contribute to photon, that would be great. Because right now it's only Mac. There's another thing called React desktop. If you use React, it is native UI components for Mac, Sierra, and Windows 10.
All right. Another one. Single page apps. I'm using one of my apps as a whatnot to do example.
This is a Website I turned into an Electron app. And you can see the flashing because, again, this is this is a Chrome window. So whenever you switch pages it takes that second to load the new page in. And so doing a single page app will save you from all of these weird flashes here.
And you can pick your favorite flavor of frontend framework, or not. You can use HTML imports. That's what we used in the API demos app. And it worked really nicely. And Electron has Dev tools support for Ember, React, jQuery, Angular, all of these things. So if you have a framework you already know and love and want to use it, it works with Electron.
I cons. All right. This is one of the ones where it's the gotcha for you only have one browser but you have to support multiple operating systems. And icons are different on every operating system. So Mac and Windows and Linux all have these different file types. But the pro tip is to start with a high res PNG and you can generate the ones from Mac and windows for that. And I have links that are online tools that will generate the right operating system for you. Because you don't want to ship your app and then have the icons look all weird.
Another one is that Linux icons are actually set when you're defining your window. Mac and Windows operating systems, their icons are set when you're packaging the app. But if you don't do this here, your Linux app is just going to be a gray square with a question mark and very sad. Windows will also use this icon to put it in the top left corner of a window. So it's a useful thing that sometimes it takes a lot of pain to realize that you need to do.
And then, again, you're only designing for one browser. So whatever works in Chrome will work in your app on all three platforms. CSS variables, constraints, the shadow DOM, custom elements version 1 is going to be in Chrome 54 which will be in Electron soon. And over 90% of ES6 works in Chrome. So there's a lot of stuff you can just do in Electron out of the box without needing any other libraries for or compiling for.
Next is interactions. This is more about using Electron AP Is to make your app integrated better into the operating system. The first thing is to think about the startup. As soon as the app loads, you can change the background color of the window to match your app. By default it's going to start up white. If you're app is bright blue, there's a flash of white before your page loads. Especially if your page has a lot of resources and takes a lot of time to load. One thing you can do is change the background color before it loads anything. And you can also think about how to use CSS animations and transitions to, like, gracefully bring all of your app's components on to the screen. Another one is don't share your window at all until everything is loaded and ready to show.
You can initially set your window to be false, and once everything is loaded, then show the window.
But, if you're making a menu bar app, and you think about how menu bar apps work, the ones just in the top title bar, those don't have a doc icon. And you don't want a window to open when the user launches your app, you only want them to have where they're clicking your app. So these are things not default in Electron. You want to show it set to false initially and only show it when they click on that tray icon.
Menus. Menus I feel like can be so often neglected. But it's a way that your users are really going to be able to tell if you've put thought into making this feel like a Windows app or a Mac app. So things like preferences dot, dot, dot, is how it's written on Mac. But it's called settings on Windows. So it's nice if you take the time to actually set your menus for each of the operating systems to what users would be accustomed to seeing. Of this, this is an example from Atom for Adam on windows and Atom on Mack. What the menus look like. Can have another thing that doesn't cost a lot but adds a lot of niceties it to your app is if there are major parts of your app's UI, you should add them to the menu. Then you get an easy way to create a keyboard shortcut for them. And then they're accessible in the help like this.
Protocol is one that I think is really nice. Like if you are creating an app to view images or open PDFs, you can set it as the default for that kind of file. Or you can create its own protocol. So, for instance, in the API demo's app, we have a demo to create an API demos protocol. You can have the link on a Website and have it open on the user's system. And other things, like saving the screen size and state. Because you have Node it's really easy to save an object to the file system, write a little JSON file and have that file read every time your app starts to that you can start the app in the last position and state that the user used it in. You can use desktop notifications. They work on all three platforms. Drag and drop on icons and launching the app on startup. And so many more things. Like I said, when Electron first came out a lot of the API was tailored towards Atom. Whatever it needed to do, we built into Electron. But now teams from all over are contributing APIs. And so there's so much that you can do to integrate your app into the desktop with Electron. And finally, some nice things to do while you're designing and building your Electron app.
Use the Dev tools. Because this is Chrome. Dev tools are there. And you'll probably find yourself opening them manually each time. But you can set them to just open by default. Which is much nicer.
And there is a library I've linked to here called Electron is Dev, a nice way to see if they're running the app locally. And you can set the Dev tools to open every time. Every time someone is running your app locally.
Accessibility. A lot of because it's still the Web a lot of accessibility issues from the Web are shared on Electron. It has Devtron, using Google's auditing library. When you use Devtron, you can make your Electron apps accessible. Please. And it's total I hope that's you say it that we, pairs well with Electron apps. If you don't have the online tool, you don't have access to everything.
Following the test talk, there is a library called Spectron we have for Electron this is a Selenium library that knows about the API you can use to test your app. This is running it on the demos app and so it's not doing it's not taking images and comparing images. It's up to you how detailed these tests will be. But, for instance, like this test makes, you know, it's opening the app, it's clicking buttons, and asserting that a certain page is visible. That there are a certain amount of element on that page. That the elements have these names. But you could get really specific to make sure the colors were right or the position was right of these elements.
And so Spectron is really nice and you can run it on all the platforms.
And finally the menu bar apps I think are such a great gateway into Electron. They are super small and focused. This is a Web page that's this big. You can execute it. You get the satisfaction of having made this thing and it's working. And they're fun. And you can fill up your menu bar with things. This one being shown here is called Moji bar, lets you find the right emoji based on your emotion. And the menu bar by Max Ogden that does all the things default for you. Like with the menu bar, don't want the doc I con to launch. This sets the defaults in Electron for you to make it even easier to get started.
And lastly, I'll put these slides up online. And I have links here for resources for getting started. There are some so this Electron quick start is a good one. It is a bare bones app that you install and link to the Electron app to get started. It's a good one for starting any Electron app. And Electron as this really long list of every tool and talk and book about Electron, the API demo's app. And then repo's using Electron is a new one. It will give you the top hundred libraries that Electron apps are using so you can kind of see it.
Spoiler, it's React. But you can see the other 99 libraries that people are using in open source. In open source Electron apps on GitHub. So that's it. Thank you.
[ Applause ]
>> CLAUDINA: That was great. Your talk was full of just like so many tips and tricks and gotchas. And everything you need to make a good Electron app. Before you started at GitHub did you know about Electron?
>> JESSICA: Not at all. Electron itself is only a few years old. So Atom had started when I started at GitHub. I worked on different frontend things at GitHub for a year and a half before I switched over to the Atom team and went to the Electron team. No, I had no idea really. It just wasn't a thing that GitHub was giving attention to either.
Like because Atom was the focus, right? One person maintaining Electron and everyone else was working on Atom. And once I joined the Atom team and I learned more about the library actually powers Atom, I kept being the annoying person pushing to working on Electron. I was the first other person to work on Electron. And then I did that for a while. And then at the beginning of this year we actually became a real team our own repos and our own Slack. Yeah.
>> CLAUDINA: So we have your pushing to thank for Electron getting out there. Incredible. We have a couple questions, are service workers available in Electron?
>> JESSICA: Yes.
>> CLAUDINA: Everything that
>> JESSICA: The only thing not available from Chrome in Electron are Chrome specific things like trying to create I don't know what it's called. But the place you type your URL into. Things that are very specific to Chrome are in Electron. But everything specific to rendering a Web page and the DOM is available. Yep.
>> CLAUDINA: How do you for the other operating systems? How do you work for the other operating systems?
>> JESSICA: You only have one code base. A great perk of Electron. So instead of a different code base for every operating system you have one code base. And the way that you only need to differentiate for operating systems in certain ways like with the CSS, like detecting the platform and changing any CSS if that's something you want to do. But all of the Electron APIs, there's just one of them and Electron figures out which operating system the user is on. So you don't have to worry about what the user is using so much. You actually don't have to worry at all if you don't want. You can make an app that works well on Mac and you don't care.
>> CLAUDINA: Windows and the Mac world.
>> JESSICA: It's up to you how careful you want to be in the Windows version and thing like that. You don't have to. But if you want to make a multiple experience on multiple platforms, you take the extra steps.
>> CLAUDINA: One code base controls statements, if Windows, do this, and Mac, this.
>> JESSICA: Only in a few spots. Like only if you're changing the CSS. The menus or something where you would check the platform to change the menu labels. But like you wouldn't for a dialogue box. And you wouldn't for like 85 if not more percent of what you're doing you're just doing once. There are only a few instances where you might want to check the platform and make an adjustment. Yeah.
>> CLAUDINA: I'm just to blown away from HTML, CSS and JS now get to the point of writing desktop apps. Who would have thought? Oh, my gosh. I got to learn this native language, Mac or Windows. Now it's all in hand.
>> JESSICA: It's super fun. I do like I feel wary of saying anything is fun. When the read me is like using this is easy.
[ Laughter ]
But there is honestly like a magical fun feeling when you're using Electron when you're able to write Node in your HTML and you can write ES6 and use CSS variables are. Just everything out of the box there is this actual fun feeling of writing an Electron app.
>> CLAUDINA: How big is the team now? Two?
>> JESSICA: Four. We get a lot of support from the community.
>> CLAUDINA: Working on it. That's the best thing. Now more and more people are using it, I'm sure that's propelled.
>> JESSICA: Definitely, Slack and Microsoft and Brave have teams working on Electron core a lot.
>> CLAUDINA: How does GitHub feel about Electron now?
>> JESSICA: I think they're pumped about it. It's a really unique project for GitHub to have also because it's one of GitHub's biggest open source projects now. And in some ways has eclipsed Atom. But it differentiates, Atom is driven internally by GitHub. The team is deciding what features go into it. There's bug fixing, but the roadmap is set by GitHub itself. Atom is not using Electron 1.0, or maybe it's almost there. I need to check. But I mean, Electron 1.0 in May of this year and Atom at least as of like a month ago wasn't on 1.0. So a lot of what's driving Electron development is the community and not internal at GitHub.
>> CLAUDINA: The power of the community.
>> JESSICA: Yeah, it's a cool open source project to be on. Where and I mean, GitHub is fine with that. So, yeah. Like the community is really driving the development of Electron.
>> CLAUDINA: All right. Well, thank you so much, Jessica.

Pete Hunt

Component-Based Style Reuse

>> CLAUDINA: I wish we could cue Prince controversy here, and the segue into the inside the actors studio chat. We have a bunch of questions for you. How do you feel after your controversial talk?
>> PETE: Everyone seems really nice.
>> CLAUDINA: You're still on stage. All right. We have a few texts from folks. Here. So one thing was oh. Sorry. How can you have feature detection and still adhere to component based styling?
>> PETE: We generally would I know this is bad but Facebook does a lot of user and I don't know, developing in desktop with Flexbox I haven't had to do that much feature detection. I'm targeting evergreen browsers at this point. This is a little bit more experimental.
But, yeah, if you really need to use like modernize or one of these things, you can use your regular CSS techniques. You just don't need to use style sheets for all of your layout. Like a lot of times just trying to line up like two or three boxes and I don't want to bounce between style sheet and my JS code.
>> CLAUDINA: To follow that up, what happens if your JavaScript breaks and your markup isn't semantic and you're on a slow network connection or someone's trying to use your app from a place where 3G or 2G is the norm?
>> PETE: There's a couple things there. First of all, just because you're using this technique doesn't mean your markup aren't going to be semantic. If you think about CSS and the browser as a render target and you have whatever abstraction you can dream of that eventual renders down to the same result, I think it you don't have to accept that you're going to have semantic markup. You can use the same tags and hierarchy. In terms of if the JavaScript breaks, this is a little more of a JS framework question. React supports server side rendering where you can render out a page from the server, push it down, and then when the JavaScript and the client kicks in it will take over that markup and attach event listeners and stuff like that.
So I don't know. There like it does work, and that's the only answer.
>> CLAUDINA: So take care to make sure you can run it on the server. How does Facebook deal with it, Internet for all and accessible all over the world?
>> PETE: I don't work for Facebook anymore. I don't speak for Facebook. Facebook renders the interactive parts, the parts that need with JavaScript and still does a lot of server side rendering and they're exploring a bunch of ways to explore how the server side rendering was done. But it was that way where I was there.
>> CLAUDINA: How about React components and Web components where CSS is part of it?
>> PETE: I don't really like Web components.
>> CLAUDINA: Why don't you like weapon components?
>> PETE: This is I think the style encapsulation is cool. I think what we've been promised from the kind of shadow DOM spec of like being able to customize a select box. Awesome. Really excited about that. Five years later we still don't have that. I don't think the way that components communicate when it is particularly good. I don't know. Yeah. That's about it.
>> CLAUDINA: So my last question, how do you see like the sort of philosophies of React making their way into other frameworks or other basically like not being totally married to the React system. Do you see that happen something like flowing into other JS frameworks and other ways that we think about the Web? But it possible to do that in a way where we don't give the philosophy of Web for all. The CSS, boom, I've done it. The distinction, I'm making an app with this use case. A totally different use case than your document. But do you see any of that design philosophy?
>> PETE: Well, there's a lot to dive into there. The first thing is like I kind of trash on the, you know, trying to shoe horn this model as developer documents into developing apps. I have seen what the consumer startup world is doing, and the consumer tech wobbled. Web can't deliver the experiences we want, we're going to shift platforms and now people have to download a binary before they can use the app. It's got to be signed by Apple. And you have to talk to them before pushing an update. And that sucks. And it's less democratic and it's a lot harder for some kid to just open up Web inspector and start writing code. I think that movement's pretty bad and I think that we need to look critically at our abstractions and say, hey, it's 2016. The fundamental building block of every social app is this component called UI table view on iOS. It's like photoing that central and sticky headers. You can't build that on the Web. That's been the most important component for a long time on native apps. So, you know, I think that if we can figure out a way to kind of give framework developers the abstractions that they need to build kind of performant applications. The Web manifesto seemed to be going the right direction. I think if we can give everybody WebGL and share parallelism and maybe a text rendering engine, we would open the door for a lot of cool stuff.
I think I went off on a tangent. I don't know if I answered the question.
>> CLAUDINA: It's all right. I think our other speaker is going to want to speak anyway. So that'll be a nice way to end.
>> PETE: Cool.
>> CLAUDINA: Thank you so much.
>> PETE: Thank you, guys.

Jen Kramer

CSS4 Grid: True Layout Finally Arrives

>> Jen: Hey, everybody. I'm a little shorter than Pete. I'm pretty tall. But I'm a little short. Can ya'll hear me?
>> Yes.
>> Jen: This is the third time even given this, Drupal, and then in Barcelona. I did this talk. Of course things already changed. So I had to update it again for this conference. Anyway, I presented this in Barcelona, Full Stack. Fest.
Two days of frontend and backend. And it was great and people were complimenting me. Feeling good, it was a great talk. And then Twitter intervened and Twitter is, I think, just a little bit of the comments these days in terms of people being nice to each other. But Twitter informed me I was in fact wrong. I have no problem being told I'm wrong, it's the way I was told I was wrong. Anyway.
The way I was told I was wrong. Here. If you look at the WC3 specification, there is no CSS 4. How many of you actually knew that? A few of you. Okay. Cool. I did not know that.
So there is no CSS 4. We're not going to version the language going forward, we're going to version modules. A version 4 animation, a version for grid, a version for whatever else. But no CSS level 4. And then the other thing that happened this week, or in the last couple weeks, maybe ya'll heard about HTML 5.1 is finally going to be a thing. Everybody cool with that? It's going to be great. We have the picture tag coming. So the picture tag is the thing that's going to allow us to make responsive images directly in HTML. No more messing around with server side solution or JavaScript solutions or whatever. It will be in the HTML. Are we all psyched about that? Yea.
So it made me think of this graphic. So I fixed it.
[ Laughter ]
Okay. So that's what we got going forward. No language or no version number for CSS, but yes for HTML. All right. Everybody good? All right, good. So now I can really start to talk.
[ Laughter ]
All right. So CSS is totally awesome. How many of you just like love to make layouts with CSS? Like they make you happy? I get a few people more here. Two in Barcelona. Maybe a third of the room here. Yeah.
I mean, here we are landing European space agency landing probes on comets, and we have problems with cans layout. And it's really important to understand CSS layout. Because if you don't understand CSS layout, it can kill you.
[ Applause ]
So, so important. As we all know, we spend an enormous amount of time in these issues in modern Web design. So the second most thing that we do is trying to make the layout work. Actually this says this is a little out of date. It says make it work with CSS and go back to using tables. I updated it, it says we tried to get the layout working in Flexbox and then went back. So that's a thing. And then, of course, the largest part of this pie, many of us trying to work in Internet Explorer. A few of you live in a wonderful world, you work with the most recent version of Chrome. And I would like to be you some day. But the rest of us are still dealing with Internet Explorer.
Now that we have that out of the way, let's talk about responsive design. And for this crowd, I should ask the question, how many of you have no idea what responsive design is? No? Okay. So responsive design is this.
And part of my pet peeves about responsive design is that we use this word the way our clients use this word. Which is it works on my phone, so therefore it is responsive design. And that's actually not true, right? JQuery in mobile is not responsive design. It's actually a different approach, right? Server side, serving up server side templates in different ways. That's also a different approach. It's not technically responsive design. That's not technically no.
Semantics, important. I'm from Harvard, man. Got to use the language properly.
So first of all, let's review the industry standard about floats. You all know floats are a hack, yes? Yeah. Our city standard is a hack. Good times.
[ Laughter ]
Right after our table based layout, which was also a hack. So this is going to feature rows and cells, put floats into a grid based system. Right? And put the two things together, put the float on the cells, put the clear on the rows. And the source ordering is pretty much going to determine our display. So whatever order we list things in the HTML, that's pretty much the way it's going to show up from left to right on the page. We can have a little bit of minor rearrangement, and you're probably familiar with that. And then the Achilles heel of float base layout has always been equal column heights.
Way back in the day I'm going to say this for Molly. Look up Dan and faux columns, we used to tile down background images and all kinds of things to make equal height columns. These days, do it with JavaScript. That's how to fix the problem. Take a look at the code, it's going to look like this. We got a row, some cell welcomes HTML. Good times. We're going to write a little bit of CSS to go with it to style it. A little bit of a formula for clearing, or in our rows. We have some kind of floating and so forth on our cells as we scrunch the page and change the media query and the widths. We all know this, right?
Good. One of my other rants is people don't actually know CSS.
[ Laughter ]
So then we scrunch the screen down a little bit further and we got this. Okay. Here's where we come into our problem. The weird thing that happens, like you turn on the floats and like everything goes in the wrong direction is actually explainable if you know what you're doing.
So if you've got a couple of things lined up, they start to wrap around. They can't go all the way over to the left hand side and so they get smooshed over on the right hand side. That's what happens. But it usually freaks most of my students out anyway. And so this is what I'm talking about that you can fix with JavaScript. All right?
And then we can also rearrange columns. And so relative positioning means that we're going to pull it out of the normal flow of the document and leave the space where this element had previously occupied that open, right? You all knew that. You say that in your sleep, yes? Okay. And then we push some stuff around. We can use the left, right top properties and so forth to rearrange things on the page.
So that's floats. So far, so good? Good. Then we got Flexbox. How many of you are working with Flexbox? Good. Good. All right. That's awesome.
How many of you have not really like gotten the grasp of Flexbox yet? Still working on it. Be proud. Be proud. It's the cutting edge. It's time to learn it. Okay. So Flexbox.
So this was actually not designed to lay out whole Web pages either. We're still hacking, okay? We're still hacking. So welcome to the next phase of hacking layouts. It is designed to really lay out like if you think about a whole series of pictures coming in, you have a bunch of pictures coming in from the server. You don't know how many pictures you're going to get, need to lay out on the page. Flexbox is awesome for this. Still going to have similar kinds of markup. We're going to have rows and cells. They're going to be called flex containers and flex items, okay? And you have to have both of those in order to work.
They're really good at vertical centering and equal heights. That's like one of the awesome things about Flexbox. That's why everybody's really excited about it. It's very, very easy to reorder boxes. Another reason that people are excited about Flexbox. But the major disadvantage is once again as really designed, I'm calling it one dimensional layout. It's designed to take a long line of things and sort of wrap it around and display it. To actually harness it and have the browser do what you want it to do at every point along the way correctly is going to take some extra code. It's going to take some extra code. I'm going to show that in a second. And the browser syntax can be challenging depending on which browsers you want to support. You may be stuck with prefixing depending how far back you have to support Internet explorer. And I feel bad for the people at the federal government, still supporting IE7. These people still exist.
So like, you know, it's still a thing. All right. So three versions of Flexbox. We have gone through a couple of iterations for how the syntax works for this. Anybody for the bonus question today anybody know the one browser that supports the tweener syntax from 2011? IE10. IE10. Yeah. Seriously. So you have to do something special for IE10.
And, again, prefixing may still be required. Here's a little bit about the support if you're interested in that. And so the way that HTML looks is as follows. So once again, basically the same way we had for floats in terms of how we're going to lay this out. Make it work. Our rows are going to have a different kind of code on them. So the notable things here is that our widths are not really widths when we work with Flexbox. So we use something called flex basis, which is kind of like a width. We'll say here I said auto. But you may say it's like 45%. It's kind of 45% wear going to try to smoosh it in. Unlike a float where it's actually going to wrap on to the next column if things don't add to 100%. Flexbox is going to smoosh things around and try to make them work for you. This is me being lazy. Should have media queries wrapped around each one of those. Anyways. This is how to make the widths, flex spaces, a little bit different for each one of your various devices. Change that. And to reorder, it's easy. Order one, two, don't have to mess around with relative positioning or any of that nonsense. So far, so good? All right. For ya'll are falling asleep again? No? Okay. Good. All right.
So then finally we're on to CSS grid. Yay. So why CSS grid? All right. First of all, it is in development. The specification is changing all the time. We have yet another editor's working document published today. Hooray. So, you know, what I say right now may be going out of the date as I speak. Which makes it challenging to do a talk on this. But anyway. So the specification is under development. There's really no row markup required here. We're not clearing things anymore, okay? We're going to put a big wrapper around our whole page, that's added, but not necessarily thinking of things in a row by row fashion. The grid is used to work in two dimensions. I will explain better what I mean.
And finally the big recommendation here, the big takeaway, is that we ought to be using Flexbox for these UI elements so that image gallery, or the series of media boxes or whatever you got. But we're going to use grid for the major layout on the Web page. Okay? Grid for the major layout on the Web personal injury. This is the graphic that comes from the CSS working group. It's explaining Flexbox here on top. You notice here we have eight things. And for whatever reason the browser laid it out with three in one row and five in the next. It's just the browser doing math, and based on the settings that you chose for it, that's what it calculated. May not be what you want, but that's what you're going to get.
And look at the bottom here, that's the grid layout. Call spans and row spans, essentially. If you remember the table based layout. So we're back to that kind of thing again. But what is the big issue with CSS grid? Anybody know? How is the browser support?
Zero. Awesome. Yeah. Support without flags. Need to set flags in the browsers to work. Even with flags, 5 bazillion bugs. Especially in Firefox. Work in Chrome, set the flag. And spec is not implemented fully until some browsers, and/or there are bugs, you think you have the code correct, you have the spec, doesn't render correctly, it may not be you. Okay? It may be the browser.
All right. So. What does the code look like this time? So same kind of thing. I have the div with the class of wrapper. Notice I have individual classes for each one of these dives. Anybody annoyed by that? I'm annoyed by that. I'm so old I remember class. What's wrong with you people? So coming along here, there are going to be some various types of additional selectors that will allow us to select individual elements here without dropping all these classes in. So there's pseudo classes coming in a couple others way. Near as I can tell, they're not nearly supported in browses just yet. This is the way we're working with it now. Each cell in the grid layout is going to have its own class associated with it. The wrapper itself is going to get this type of definition. So display of grid and then a grid gap of ten pixels. The grid gap being the distance between the cells and the rows. And so forth.
And who is offended that I said ten pixels? Anybody? Some of you are offended. That's great. You should be offended. It should be percents. But percents don't work in the browser. This is a known bug. If you read the spec it will tell you that the the fact that this should be percents is if they get to it they'll actually try to make that work. But right now they're just makes it work with pixels. And isn't the talk after mine or tomorrow, the one about why we should not use pixels anymore.
>> Tomorrow.
>> In the afternoon. Excellent. Here's the way this code looks. So there's a couple of different ways to write your grid based layout code. And this is the one that sort of resonates with me. And we're going think about it this way. If you start counting the I don't know separator lines between each one of these cells that we have here, we can start numbering them. Count like humans, not engineers. We start with one, not zero. Which is really nice. And we're going basically write this out. So for each one of the cells, what is it going across? One to two. Grid column, one, two. Make sense. The next one, two, three, three, four. And I ran out of rime. What's the last one? Four/5. That's the way it's going to work. A slightly more complicated example. What happens when you have a layout like this? You're going to have things going down the page and things next to it. You can do that with a grid row property. So this thing here on the left, column one, is going to go from one, skip two down to three. So 1/3 for that. And that's going to be that's location on the page. Now, there is some alternate syntax for this. I like the numbering version of this.
There's also individual property elements where you can have your grid column start and end, and start and end. Nobody's going to do that, nobody's going to be typing all that stuff. So I picked this. The alternate syntax is actually to have some named grid template areas. So puck actually define these areas inside of your code and say here's a header and here's a footer. And where that's going to appear in your grid based layout. And refer to those areas in this of the rest of your styling. And I just sort of ran out time to talk about that. But if you go to Rachel Andrew's site, gridbyexample.com, she does have an example of this and you can take a look at how that works.
All right. So then if we think about reordering. So if we take sort of that kind of ideal that I had my wrapper and inside of that, a header, an article and an aside. How might this kind of reordering work? Show that to you right now. Just to point out there's code posted if any of you would like to access that. And then I will go ahead and show you this in the browser. And this is a reordering example. So here we go. So here we are. We have an aside, we have a header, we have a title. I'm not a graphic designer. I type in background color yellow, green, and blue really well. They kind of go together.
And so as we start to shrink the page down here at some point in time we can completely rearrange things. How cool is that? All right. Awesome, huh? So I moved my header all the way down to the bottom of the page and move my aside to the right. That's what you can't do with the grid. And if you shrink down further. Let's say this is the mobile layout. This is actually the source order for this HTML. So the source order, it is really important for accessibility purposes. You want people to be able to read this very easily from top to bottom. And search engines like that also. So this is going to allow you to put the source order in exactly the way it should be to best serve those populations. And you can make it appear anywhere on the page that you want.
Now, why you would do this in real life, I have no idea. Just because you can doesn't mean you should. Okay? Don't get all excited backend people. If we have any backend people. Oh, that's awesome. I'm totally doing that. Don't do that. It's just an example.
All right. I guess I'll show you some of my other examples that I've gotten at the moment. I have a page that I coded the same way three times. Because only you guys can get excited about that.
[ Laughter ]
So I just got back from Barcelona, like I said. This is the Palau de la Musica in Barcelona. This is the Web page and pictures. This is a float based layout here. And as I shrink my page down, things are going to rearrange. Things are going to stack on top of each other. They're going to change size until I get down to the mobile version. Let's call that the gold standard. Yay.
Then I coded the same thing with Flexbox. This is a Flexbox based grid system. I purposely didn't do a whole lot with the images. This is the images displaying their regular size. They're going to do whatever they're going to do. We can apply a little bit more CSS to make them behave the way we want them to. So as I shrink the page down, they stack on top of each other like this with Flexbox. It looks a little odd. But it still works. You can still understand what's going on. And then they're going to go like this underneath. And then we're going to shrink it down again to a single column. All right? So that's Flexbox.
And then grid. So how did I code this? What cells here are under control of grid? Yeah, the layout part. So my fine Website, my aside, and the article here. How did I handle the pictures? Flexbox. Flexbox, right? So once again, as we shrink the page down here, that's going to go ahead and rearrange itself. So these all look fairly similar is the takeaway for that. Like I said, the HTML and the CSS are up on GitHub. How am I doing on time? I don't think I have a lot of time to go through all that code. You are welcome to look at it. And I'm on Twitter if anyone wants to Tweet questions.
All right. So let's just wrap up here. That's my code example. So if you are interested in learning more, there are some really great resources out there on the Web. Oops. Except the WC3 editor's draft was updated today, not then. I should have updated that. These are really good resources on that. And in terms of my current recommendations how to lay out your Web pages, first of all, if you need browser support, can't go wrong with floats. Can't go wrong with floats. All right? Don't have to worry about browser support, it just works. And if you're okay with a few prefixes and learning something new, Flexbox is a reasonable interim step until we get support in all the browsers. Flexbox and Bootstrap 4. So the grid system in Bootstrap 4 and the foundation is float by default. But for both frameworks, go into the Sass files, there's a property there you can toggle on and say use the Flexbox based layout instead. Retile, and you can use the Flexbox based instead of the grid system. That's there. It's in Bootstrap 4. Coming soon. It's kind of mainstreaming Flexbox. Time to learn it.
And keep waiting for CSS grid. Good stuff it always five years ago. This is probably five years away. Maybe get lucky and it'll only be three. I have had mention that maybe somebody will write a polyfill for it, and how cool would that be. And people say polyfill, and yada, yada, yada. The browser is what it is, and we're going to get the support we're going to get. Keep your fingers crossed. It's going to be great when it gets here. And I'm around if you have any other questions. So thank you very much.
[ Applause ]
>> CLAUDINA: Want to come sit in the chair? The future.
>> Jen: Thank you.
>> CLAUDINA: So do you teach your students this new stuff that hasn't come out yet?
>> Jen: I do. I have a two semester course of extension, modern frontend Web design one and two. So in the fall they're actually learning selectors, specificity. Actually they learn float based layout and they learn regular positioning. Because my feeling is that they don't actually know that.
>> CLAUDINA: Right. How many of us know that?
>> Jen: They don't know it. When they get done with my class, they know it. And in the spring we get into Flexbox, grids, animation, some hot cutting edge stuff. Get into the basics first. If you don't know the basics, hard to learn the fun stuff.
>> CLAUDINA: Do you teach pre processers?
>> Jen: I do. In the spring term, customization with Sass, and maybe Bootstrap. I haven't decided yet. And I think it's an important skill these days if you truly know HTML and JavaScript, you can learn the next framework that comes along. Not an issue. And unfortunately the way that the industry is trending as I see it, I know Angular, so I'm hot stuff today until React is the hot thing. And then you're no longer hot stuff, right?
So if you learn the basics of these things, you can switch to whatever you want to do. But there's still definitely a place for knowing how these frameworks work. You have to read the documentation, you have to figure it out and make it work. So I do incorporate either foundation or Bootstrap. Because I want students to start getting that sense of how do I read a framework and start to implement it? I will not always be there for me.
>> CLAUDINA: I love what you're talking about, the basics of understanding like the core languages. And also that you teach new stuff. Because I feel like that is so absent in so much Web education. It's kind of like, oh, well, here's this thing that you need to know. And, yeah, welcome. And you see these hires and you're like, what? What are you learning? There's so much interesting stuff out there.
>> Jen: We in academia have not done a good job of servicing our students. That's serious. Academia never figured out where Web was supposed to fit. It sort of ended up in the art department with the graphic designers who learned Photoshop, illustrator, and in design. And so how do you do Web? Dream weaver. Right? It wound up over in the business school, they learn social media and digital marketing, but don't understand how to incorporate that curriculum into a Web page. That's content that drives a Website. We never get there. And subsequently the marketers never learned HTML and CSS. And now in journalism schools. Now we're getting big data into journalism schools. But they might be learning Python, but they don't know how to do anything with a Web page. That's a little odd. We in academia failed in that department. We have a digital media degree at Harvard extension. It's frontend Web development, video and instructional design. Like please explain that to me. I don't know. I try to tell the story that it is storytelling. It's storytelling across media, right? If question focus on the story, it starts to make sense we would put together frontend, Web design, video, and instructional design. Just in different media. But still we in academia are struggling with the Web. It is so interdisciplinary.
>> CLAUDINA: It's great you're there and can teach and champion and work with other professors. You have inspired me throughout my career.
>> Jen: Thank you.
>> CLAUDINA: One question to ask you, what happens if two elements are configured to cover the same cell?
>> Jen: That's a great question. Could that happen? I'm thinking it couldn't necessarily happen. Because the grid the way the grid is set up going across and down in terms of rows, you would not be able, necessarily going to have to think on that. Because I have not tried that.
>> CLAUDINA: We can do some hacking afterwards.
>> Jen: We can do some hacking afterwards and see. Then the question, is it the browser that is configured wrongly allowing us to do it or not do it, or in the spec?
>> CLAUDINA: Essentially finding bugs.
>> Jen: Essentially finding bugs. But what you really want is the answer to that question to be no.
>> CLAUDINA: Yes that couldn't happen at all. If you asked that question, find Jen. Do a little hack.
>> Jen: Let's try it. See what happens.
>> CLAUDINA: Amazing. Thank you so much, Jen. Loved your talk.
View Slides

Will Boyd

Silky Smooth Animation with CSS

>> WILL: Yeah, so I do have a I counted 2044 fish in my demos. If you like fish, you are really going to like my talk. Again, my name is Will and I'm going to talk about Silky Smooth Animation with CSS. But actually before I talk about silky smooth animation, I want to take a moment to talk about the exact office. I want to talk about janky animation. Often called jank. If you have animation that hiccups or stutterers along, it's jank. It's not a good thing. Simply put, jank doesn't look good, and it can be distracting. In a worst case scenario, it can be disorienting. Motion, when applied carefully and thoughtfully can be a huge asset. But if you have janky motion, that sort of ruins things. We don't like jank. We want to do everything we can to eliminate jank so we are left with silky smooth animation.
So ensure smooth animation you have a goal of 60 frames per second. That means while the browser is animating something it is doing all the calculations that it needs to do, it's figuring out what pixels to update, and pushing the updated pixels to the screen. And it's doing all of this 60 times in a second.
This works out to an average budget of about 16.7 milliseconds per frame that your browser has to work with. Sixteen.7 milliseconds is a very tight deadline. It can potentially be a very ambitious one too. Your browser may be asked to do a lot of work in that short period of time. If your browser cannot complete the work, the frame rate can suffer, meaning the animations will be just that much rougher.
So I want to give a quick tour of the work that your browser is doing behind the scenes. And I think this will be great because this was really helpful for me. Because when you understand the work that your browser is doing, then you can start to see ways to optimize things, to make things more efficient. Because anything you can do to decrease the workload for your browser means that your browser can finish that work just that much faster and your frame rates will stay up and your animations will stay smooth.
Now, this sequence of events I'm going to show you is mostly the same across all major modern browsers. But there are some differences. So this particular sequence I'm showing you is going to be Chrome centric. So I will try to talk about the Chrome specific parts as I come across them. So when you think about all the work your browser has to do from when it receives the HTML all the way to the end where it actually pushes pixels on to the screen, conceptually you can divide this sequence of work into four main stages. Loading, rendering, painting with and displaying.
So starting with loading were your browser receives the HTML and Parse this is HTML to figure out what elements it's working with. Once it knows the elements it has, it can arrange the elements as nodes into the DOM tree, or the document object model tree. This is a representation of all of the elements found within a document. From here your browser can transition into the rendering stage.
Here your browser will use the DOM tree as a basis to create another tree called the render tree. Or if you're Firefox you'll call this the frame tree. But they're the same thing. So the render tree cares specifically about the visual aspects of elements that will ultimately be displayed on the Web page. So in order to figure out how to craft the render tree, your browser needs to calculate styles.
So it's going to take a look at the CSS. It's going to determine which style rules affect which elements. Also, if you have any animations that are in progress, then it is going to calculate the values for that moment in time for any animated properties.
So with all of this visual information your browser can start to shake the render tree. So, for example, all browsers, by default, say the head and title element should not be displayed on a Web page. Assuming you don't muck around with that default then those elements will not be included in the render tree. Also, let's say that you have CSS that says that all H1 elements should have display none on them. In that case H1 would also not be in this render tree. But the render tree, it's not just about removing nodes that were in the DOM tree, it can also have nodes added to it.
So, for example, if we have an HTML with a couple of lines of text in it, those lines of text are actually treated as separate text nodes. And each of those text nodes are added to the render tree. And just one more example if you have CSS that defines before or after pseudo elements, those would also be nodes that were added to the render tree.
So we have this render tree that the browser has crafted. And now your browser's going to start thinking about layouts. So it's going to calculate geometry. It's going look at all of the elements that are in the render tree and figure out their widths, their heights. It's going to take into account margin and padding and figure out the positions of things on the page. And it's very common for the geometry of one element to affect the geometry of another element.
For example, the height of an element can affect the vertical position of an element after it. So there is a bit of interplay here between the elements in terms of geometry. And layout can be very costly for your browser to do.
So just keep that in mind because we'll be talking about layout again or linger. But layout can be very expensive. After rendering we move on to the painting stage. And here Chrome will assemble a series of draw calls. You can think of draw calls as instruction sets for how to turn an element into pixels. So when these draw calls are executed your browser will actually draw pixels on to a bitmap. And this process is called rasterization. It's important to know these are not on the map yet. They are drawn on bitmaps hanging out in memory right now. There's another step to get the pixels on to the screen. But before I talk about that last step I want to take a step back here for a moment and talk about where we are from a broader perspective.
So everything I have shown so far has a curve in the render process. The render process has multiple threads running within it. Threads are your browser's way of splitting up the work that it has to do and potentially doing that work simultaneously across threads.
So everything I've shown you so far has happened on the main threads. Except for rasterization. There are other tasks that are also on the main thread though. JavaScript is a big one. The main thread is typically your source of a performance bottleneck simply because there is so much that's going on on the main thread. And next here I have raster threads. So Chrome will actually offload rasterization to these raster threads. So it's very common to have multiple raster threads running at the same time all of them working to join pixels. And the last thread I have here is the compositor thread. It will assign work on other threads and do coordination between these various threads.
So at this point I want to introduce you to the GPU process. The GPU process has one thread in it. The GPU thread. And that is where your GPU or your graphic processing unit is going to do the work of putting pixels on the screen. So here we are now in the final displaying stage. So earlier that rasterization that your browser did, those bitmaps are going to be uploaded into the GPU thread where they are treated as textures. And your GPU is very adept at putting textures on to the screen. It's going to do that. And finally, success. We have pixels pushed to the screen.
This is great. But there's good news and there's bad news. So the bad news is that I actually skipped a lot of stuff.
[ Laughter ]
There's actually more work that your browser has to do to push pixels around. And there's even more work on top of that. Not directly related to pushing pixels around. But it's still work that your browser has to do. A big one that I barely mentioned is JavaScript. JavaScript can have a huge impact on the workload your browser is taking on. That's the bad news. Now let's talk about the good news.
Again, here, I have the four stages we worked through, loading, rendering, painting, displaying. And your browser does not need to do all of this work again every time for every single frame. In fact when it comes to CSS animations, once your browser has gone through the loading stage it does not need to reload anything in order to support CSS animations.
So we can just kind of forget about loading for now.
It is very common, however, to have CSS animations that force your browser to work from rendering, painting and displaying. But if you are very careful with how you craft your animations and you only use certain CSS properties, then you can eliminate the work from rendering and painting such that you're only asking your browser to do a little bit of work in the display stage. And that's good. Because as I mentioned before, the less work your browser has to do, the smoother your animations will be.
So at this point I want to talk about three categories of CSS properties and the costs associated with animating them. The first category of CSS properties are those that cause reflows. So this happens whenever you animate something that changes geometry. So when you animate the geometry of an element you are forcing your browser to redo layout. If you recall from before, layout can be very expensive. Because not only does your browser have to recalculate layout and the geometry for the element, but it could have a chain effect for all the elements below it in the render tree. So that can be very expensive.
The second category is CSS properties is when animated will cause repaints. So this is whenever you are forcing your browser to redraw pixels for an element. So the most likely culprits here are color and background color. Now, repaints will not cause reflows. But reflows can often cause repaints.
The reason being is if you force a reflow and an element is moved, then your browser may have to repaint it in a new location. So he flows and repaints are not that great. But this third category, this is great. So these properties, when animated will cause no reflows and no repaints. In fact these animations can be handled completely within the GPU thread. Which makes them extremely efficient. What's happening when you animate these properties is your browser will actually find the element being animated and promote it into a compositor layer. It's independent of anything on the page. It's very limited here. We only have three CSS properties, but you can actually do a lot with these properties. Transform will let you move things around the page or scale things, rotate things, skew things if you want to. Filter lets you pull off a lot of really interesting effects. So you can change the color of your element by adjusting the hue. Or you can turn it into grayscale. Or you can bump up the contrast or the saturation. There are two effects, however, blur and drop shadow that are not GPU accelerated. If you use these, you will cause repaints. Just be aware of that. And finally I have opacity which lets you fade things in and out.
So at this point I want to start to get into some demos. So I'm going to show you some demos of fish swimming around. Each of these fish is a single div. So I have a div with a before and after pseudo element. I'm using them to draw a fish. Essentially all you need to know is I'm animating dives on the Web page.
In this first demo I'm animating using a key frames animation. These will be absolutely positioned fish and I'm going to be animating the left CSS property to move them back and forth. And then I'm going to have a demo right after that has the exact same setup, but instead of animating left, I'm going to animate transform. So is I'll be using translate X to move them back and forth.
So let's dive in here. And I am offline. It's okay. Wait, wait, wait. It's okay. All right.
[ Laughter ]
So 20 fish swimming around. So these are the fish that are being animated via the left CSS property. These are very talented fish. Swim both forwards and backwards.
[ Laughter ]
It look like they're having a fine time. But let's take a closer look. Oh, I'm use jQuery which is online. Okay. Hold on. What is it, boxmodel? I should have I should have kept jQuery local.
This one? All right. We're saved. Man, I'm glad. Because my talk is like two thirds demos. I would just have to get offstage right now. Okay.
So we've got our fish swimming around. I've opened my Dev tools here. I'm going to hit escape. And down here on the rendering I'm going to turn and this is going to show green rectangles around everything that's been repainted. There is a green rectangle around all of these fish. And more importantly it is a persistent green rectangle. So these fish are actually being repainted over and over and over every frame.
So that's not the greatest. That's a lot of extra repaints that the browser is doing. Let's move on for now. So I'm going to close this. And up here on the timeline tab I'm going to record a two second timeline. And this is going to show me all of the activity that happened on the page during that two seconds. So you can see we have our threads here. Here's the main threads. And here we have four raster threads going at the same time. And then finally the GPU thread here at the bottom.
And each of those colored bars is showing when the browser had to do work. So we can actually zoom in all the way down to the frame level here. And we can see exactly when and which thread the browser is doing the work. And we can even zoom in further and see exactly what work is being done. So that's pretty cool. But I'm going to stick to this bird's eye view for now. Come down here to the call tree tab.
And this is going to show me an aggregate of the work that the browser is doing for particular types of tasks. So here you can see that rendering is 73.3% of the work being done I know, it's kind of hard to read from there. But 73.3% of the work being done in terms of time. So I can actually drill into this and see that recalculate styles is 38.9% of the work being done. And that seems high.
So what's happening is because we are animated via left, which is not a GPU accelerated animation, this is running on the main thread. Which means on the main thread we have to calculate a new value for the left property. Every single frame in order to create this animation for our fish. And we're doing that for every fish. That's times 20. So that's a good bit of work there. And let's see. Down here, we have layout. Fourteen.6%. And painting seems to be the remaining percent. So let's compare these fish to these fish. I have 20 fish swimming around. I'm using transform, which is GPU accelerated. And I'm going to turn on repaint. Nothing has happened. There are no repaints. So the browser doesn't need to do any repaints to support animations via transform. Below paint flashing there is an option here to show layer borders. So it's kind of hard to see out there. But there is now an orange rectangle around every fish.
So these orange rectangles show anything promoted into a compositor layer. If you remember, they are very efficient for the GPU. And now do a timeline reporting once again. And you can see it's a lot sparser. In fact, we're not even being shown the main thread or any of the raster threads. And that is because there is simply no work being done in those threads. The only work the browser has to do is in the GPU thread. So that's a big improvement. Let me hop back into my presentation here.
And now having shown you these two demos, you might be think, oh, Will, I don't know. Looks like those fish were swimming just fine in both of those demos. And to that I would say that you are absolutely correct. To be honest, this Macbook Pro is going to have no problems animated 20 small fish around a screen even if I am using terrible CSS. So let's push thing it is a little further.
[ Laughter ]
How about instead of 20 fish swimming politely back and forth I have a thousand fish freaking out. So before I do that I'm going to open up my Dev tools real quick to make this smaller. And down here I'm going to turn on the FPS meter. This meter in the top right is going to show the frame rate that Chrome is delivering while animations are occurring. So let's see what this looks like. So here we have a thousand fish spilling on to the screen. These fish are being animated via the left and top CSS properties. Which as you may recall cause reflows and repaints. These are not GPU accelerated. And kind of choppy waters here. Right now Chrome is telling me that my frame rate is right around 15 frames per second. Which is actually pretty bad. So let's see if we can get something better than that.
So here I have a thousand fish being animated via transform which is GPU accelerated. You can see it's noticeably smoother. And right now Chrome is telling me my frame rate is a rock solid 60 frames per second. We just had a frame rate increase of 45 frames per second. Which is absolutely massive. So
[ Applause ]
So by using the right CSS properties to animate on, we can achieve a huge performance boost. Now, a thousand fish swimming around on a screen is obviously a completely contrived scenario. You will probably never have to animate fish like this. More likely you'll be animating a side panel or a modal dialogue or navigation menu or any of these sorts of things. I'm just using fish as an example. And also in this last demo I was animating a thousand fish simply because I'm trying to push the hardware I'm on. I'm on a relatively powerful Macbook pro, but you can't assume users are on high end devices. And you can't assume there won't be other things fighting for the CPU. Your browser may very well be carrying out an intensive task at the same time that you're asking it to support your animations.
So with that in mind I have an example from personal experience. Earlier this year I was working on a side project to create a JavaScript powered Web app that would run on a Raspberry Pi. They are not super powerful. And the JavaScript I was writing had intensive client side JavaScript that was eating up the already limited CPU. So for this I think I had a UI with a progress bar going along the top. And I was animating this progress bar via width. Which causes reflows, causes repoints or repaints. It's not the most efficient thing to animate on. And the results were absolutely terrible. So the progress bar was super, super janky. So I had to try a different approach. I'm going to show you what I came up. Left, animating width, and the right is what worked. So instead of animating width, I'm animating a transform. I'm scaling the div along the X axis to make it grow and shrink. Much better results. By using transform I have a GPU accelerated animation which is a lot better. By using CSS properties animated in maybe slightly different ways you can achieve the same end results but get a lot better performance.
One more example I have of this, here I have two buttons and just color shifting from gray to pink. And on the left is maybe the most straight forward thing you would think of, just animating the background color between gray and pink. But animating background color causes repaints. So another option is what I have on the right here is to use CSS filters. And you can use a combination of grayscale and brightness to make the color change, except now you have a GPU accelerated animation.
So I've talked a lot about having better animations from the standpoint of having a better frame rate. But there are also other benefits to using these GPU accelerated animations. So I'm going to show two of these bonus effects right now.
So here I have the last no, the next to two last fish of my demo. So I have two fish swimming ever so slightly back and forth. The fish on the left is animated via the CSS property. I'm going to zoom way in. Hold on. Let me make this bigger. So I'm going to zoom way in here down to the pixel level. And you can see that as this tail is moving back and forth, it is snapping to pixel boundaries, right? That's kind of choppy at the pixel level.
Now, compare that to animating on transform. So you can see it's not snapping to the pixel level, it's actually smoothly anti aliasing across pixel boundaries. So it looks a lot smoother, a lot nicer at the pixel level.
And then here I have my last demo. And this one's my favorite. I've kind of hinted at this before. You guys see what's coming.
[ Laughter ]
So GPU accelerated animations can run completely within the GPU thread. And that's what the fish on the right has. It's been animated via transform. Other animations like top and left cause repaints and reflows. They are animated on the main thread.
And JavaScript also runs on the main thread. So what happens when I have absolutely terrible JavaScript that completely wrecks the main thread? And we're going to find out.
So I'm going to click this but then and it's going to cause awful JavaScript to run. This JavaScript does nothing but churn non stop in a loop for ten straight seconds. And I'm going to click this button, and the figure on the left is dead. R.IP left fish. But it's completely inside the GPU thread, it's not effected by the main thread. That's so cool. You could have really, really intensive JavaScript that's just ruining everything, but your animation could still be perfectly fine.
So that was my last demo. Winding things down here, I have one last major point. All of this is under constant development. Issues are constantly being ironed out browser performance is constantly being increased with and be new debugging tools are constantly being made available. Hi a whole segment for this talk planned where I was going to talk through a gnarly text issue with animations in Safari. But while I was working on this talk Safari fixed it.
[ Laughter ]
So I had to take it out of the talk. That's great, right? Things are always getting better. And as an example of new debugging tools coming down the pipeline, this is available in Chrome canary. But it is the ability to throttle the CPU that your browser is using. So this is excellent and handy for emulating and testing what your animations would look like on lower power devices. This is going to be super useful and hopefully landing in Chrome proper very soon. All of the demos I have shown you are online at animation workshop.herokuapp.com. And you can go to the link and have the demo code available. That's all I've got. Thank you.
[ Applause ]
>> CLAUDINA: Whoa. There we go. Whoa. That was like, so much stuff. A lot of fish too. How did you get into like understanding animation at such a deep level? Was this something that came about through your work? Or were you just like I'm going to figure this out?
>> It's something I had an interest in. I like to do a lot of CSS animations. There's kind of a sub culture on CodePen where you try to do as much as you can without JavaScript. So you would use all kinds of crazy CSS animations to pull things off. I kind of got sucked into that, I thought it was fun. That's where I learned about CSS animations. And then I pitched the idea for this talk, and I realized there's so much more below the surface. As I mentioned in the talk, I skipped a lot of steps. There's a lot of work that goes into this. Yeah. Browser animation is really, really impressive.
>> CLAUDINA: Yep. Very, very difficult too. So folks in the audience are curious if you can speak to framework performance for non GPU accelerated animations. Is there a way to keep it when you're animating other properties? Or is it difficult?
>> WILL: You can do things to improve non GPU accelerated. And there are things you can recognize are expensive. Background fix makes scrolling expensive. It causes a repaint on the entire region being scrolled.
If you have a lot of performance issues sometimes you can cut out some of the niceties. Like box shadow might be expensive for lower powered devices to animate. Maybe cut those back for the sake of performance. Yes. There are certainly things you can do beyond the GPU.
>> CLAUDINA: Has striving to keep your animations performing and focused on accelerating made you think different about your work? I liked the examples, here's another way of thinking about this. Just move the div.
>> WILL: Right. I have had some experiences at work. One particular example was for a past job I was working on kind of an online photo gallery viewer. Which seems not that bad, but we had basically an app that was infinite scroll for tens of thousands of images. That's where we started seeing all kinds of issues, including animation performance issues. Yeah, it's been really helpful to kind of to understand, like, how the browser handles these things and what things are expensive to the browser. So that I can make things in my work more performant.
>> CLAUDINA: Do you see a world where well, I guess my question is, I'm curious how these properties get defined? Which one is non accelerated and which one isn’t? And in your studies, when you found this out, is there a world where some of those may change? I'm going to improve the animation of this property so it is more performant.
>> WILL: I think it mostly comes from the capabilities of the GPU. Like there are certain things, like, for example, if you have an animation that causes text to reflow. I don't know what you can do about that. You're going to have to draw the words in the new reflow positions. But there are some things that, you know, the GPU can very easily animate. Like moving around textures on the screen is very easy. If I remember correctly CSS filters did not used to be GPU accelerated. I don't know if anyone can back me up. But as browsers progressed then they were added as something that could be GPU accelerated.
>> CLAUDINA: So it's possible that the browser vendors may start moving more over
>> WILL: I don't think everything can be GPU accelerated. But I do think that more things very likely could be.
>> CLAUDINA: Great. Thank you so much. That was a wonderful talk. And I know that you recently said you started speaking. But this was incredible. Thanks.
View Slides

Keith J. Grant

Stop Thinking in Pixels

>> KEITH: Researchers did a study on running shoes several years ago. And they gave one group of runner痴 shoes that had firm midsoles, not a lot of padding. They gave other runners the shoes with thicker, softer padding. The thinking being that they could the cushioning would protect the runners and result in fewer running injuries.
So they tracked the runners over six months and got to the end and found absolutely no difference. And they were puzzled by this. This should surely make sense. So they brought the runners if, put them on a treadmill, video recorded them. And they found the runners with little padding under their feet naturally landed softly. The other group with soft, squishy shoes stomped with every step subconsciously and totally neglected any benefit that the padding was supposed to offer.
I think when we approach CSS, we do signed of the same thing. CSS is an abstract language. And it offers a nice abstraction layer between us and the browser that can make a lot of good decisions for us. But we, without really fully understanding that abstraction layer, without really understanding what CSS is doing for us try to push through the abstraction level to get to the bare medal. Find something concrete. And we want stability. We don't want we want to know exactly what's going to happen in the browser rather than trusting the system to do its thing. CSS allows us to write a rule set. A set of styles to take unknown content and an unknown medium and put it together in the browser. And don't have to know whether that's going to be a smartphone or a desktop computer. We don't have to know whether that heading is going to be two short words or a long complete sentence that's going to go around.
I'm Keith Grant. I come from Atlanta. I work at Intercontinental exchange. You don't know us, but we own the New York Stock Exchange. And I work on a Website team where I'm kind of the residency assess guy and do stuff in React and Node. And I'm the author of the book CSS in depth. It is available for early access now, early chapters and get early updates. If you want to follow along with the slides, there's a link on my Website.
I'm mostly talking today about Ms. Who here has tried working with Ms? Who here did not have a good experience? Some of you. Who here had a kind of okay experience? Who here just still uses pixels? It's okay to admit that. It's okay to admit that. Ms are frustrating.
And the reason they're frustrating, they're part of the abstraction layer and an important tool and if you don't understand what they're trying to do, they can trip us. So an M in CSS is equal to the font size of the current element. So the box on the left here is one M high by one M wide. And the box on the right as well. I put the capital letter M, there's a myth it's related to the width of the capital letter M. Not really the case. Maybe in old fonts centuries ago. But when Ms get tricky is when we use for font size. An M as a font size as a current element, we can't define font size by itself. It has to base the M on the inherited font size.
This means if a parent element has 16 pixels, and child size, the browser has to multiply them, resulting in 19.2 pixels for that child. This means font size is different. It's a special snow flake. And if you give a bunch of properties, 1.2M on the same element, assuming a 16 pixel, it would compute the 16 pixels for the font size, 16.2, now the new local definition of an M. And that value is used to compute 1.2M for everything else, coming out at 23 pixels. This is quirky. We can live with it. It's a little weird if you're not looking for it.
But what starts to trip us up, Ms inside of Ms. And nest them deeply. A child size, 1.2M, browser multiplies it, use M again, and the browser multiplies that, and scratch heads and do a little math. And it just gets completely out of control fast. No idea what an M is anymore. We totally lose track of it. We can see a similar problem I don't know if you can read the red there. That's a UL selector. It's targeting the list. We give the font size of 0.8M. And nest the list within a list, that selector targets every list and each one starts shrinking because it's 80% of the font size.
Of course the solution to both these problems is the REM unit. Similar to an M. It's short for root M. Sunset much being relative to the inherited font size, it's relative to the font size of the root of the document. The HTML of the document. Now if we use a REM for a font size, it's always the same. Because it's based on the same value.
So if you're just getting your feet wet with Ms and rems, you've begun using pixels and you're thinking about, you know, making the switch, this is kind of my starting recommendation. Use REM for font size because it's predictable. And pixels for border width. You want a nice, fine line. And it can get weird. Use Ms for that but for everything else. With one exception, line height.
And I put here, don't use any units for line height. They inherent funny. If you want to see an example of that, see me afterwards. But basically you're safe with Ms. Rem for font size, pixels for border width and M for everything else. And I'll show you some examples how to capitalize on this.
You have probably heard this rule, use relative units on your font sizings. M, rem, a couple of the others, and this is an accessibility rule. It's an important rule. Because if the user goes into the browser settings and they need a larger font size so they can read the font better, came up with a default font size, if you use pixels you cancel out their option, override it. But use M and rem, the browser will make it relative.
Now you can get into a debate whether this matters, they're moving away from the default and use the zoom, it will zoom font size to pixels. And I will argue that browsers will doing that because we're not very good at following this rule. And I would also say that browsers such as Chrome still offer the default font size. I think we should follow this rule. But I'm not here to talk about accessibility. This rule might be what gets you dipping your toe into the Ms and rems. That got me to start toying with them. But if that's all you ever get out of them, okay, I want this many pixels and convert to Ms, then you are missing out on a lot of things you can get out of Ms.
I will argue and show you that if you favor the use of Ms and rems over pixels consistently, you can have code that's more accurate, more simple and more flexible. Which is a very good thing. Because it can mean your site responds appropriately. You are trusting the abstraction layer that CSS brings and allow it to make decisions for you that you would not be able to do on your own.
So this is an important formula when you're working with Ms. You have probably seen it. If you know the pixel value you want and convert to Ms or rems, take and divide by the base. Ms, the inherited font size, rems is the base side. You want a 14 pixel, and want 16 pixel, it gives you 0.875. Go and hit command space and type it right there, it's nice and handy and quick. If you want an 18 pixel font size and want 14 pixel, you can divide, get 1.2857. This gets real tedious.
[ Laughter ]
And if you are doing this all of the time, you are going to start to dislike Ms and you're going to really start thinking that pixels are a more inviting thing. You need to know this formula. You need to have it on hand. But if you find yourself doing it all the time I we, because I have been in this boat, are not leveraging Ms properly. We have all of the tools for calculating an exact M amount to represent an exact pixel amount. You punch in a base font size and get all the M values to get all the results. We have mix ins in Sass that convert our pixels to rem. And I have to ask, why?
Why is it so important that we have an 18 pixel font size for a sub header? Why is it so important we have precisely 24 pixels for that page title? Why must the footer text be 12 pixels? And I think if you dig deep enough the answer to that we comes from this book. The elements of Typo graphic style by Robert Bringhurst. It is the model for typography. And he said you should start request small font sizes and grow up increasingly larger as you go up. And he gave this illustration as an example.
And I think we inadvertently as an industry took this example and said, perfect. There's our font sizes. Sixteen, 18, 21, 24. Those are magic numbers. And we implement I'd say 90% of our designs use these numbers. As if these magic numbers are what Bringhurst was talking about. He wasn't talking about these numbers. He was talking about the relationship.
He was saying there should be some sort of mathematical scale from one font size to the next. The larger font size is spaced out more and more. The smaller font sizes are closer together. And this is how we should approach it. It this Website, typescale.com. In the selector here you can choose a different what I'll call scaler. In this example it's 1.414. And multiply by 1.414 again. Keep multiplying it up, divide to go down. You can choose a different font size. And this Website draws parallels with the musical scale. I don't know how much credence there is to it, but it sounds cool to me. I think the point is there's a number.
What I'm getting at is, this is how we approach design. This is the status quo of design in our world is we, whether it was Bringhurst back in the day or us, our designer now, take a scaler and we compute a bunch of pixel font sizes. And then we go over to our CSS and reverse back the exact same app you can get back to the name value. We don't need this middle step. It's irrelevant what the pixel font size is if we just use a scaler and stick with it. And let's watch happens here. So we'll choose a scaler of 1.25. And we'll multiply it up and down a few times.
Now, whatever our current font size is, if we multiply by 1.25 it gives us to the next size. If we divide by 1.25 it gives us the next size down. Or you can invert that. One divided by 1.25 gets you 0.8. Instead of 14 pixels, 18 pixels being the magic numbers. These are your new magic numbers. Pick a scaler for your design. Multiply up and down a few times. I guarantee you'll commit these to memory within the first day on the project.
Just two numbers. The next few steps may take a little longer to commit to memory. Stick it on a post it note.
But if we do this, the browser doesn't work for us. We don't have to divide and multiply things to figure out the pixel value. It doesn't matter. Don't nest a lot of M font sizes deeply. But on this scale you can take any one of these numbers and multiply it by any other one of these numbers and you'll still be on the scale.
If you stick with these numbers you will always have a font size that looks good in your design. So don't micromanage it. Let the browser do the work. If we just use a scaler, call that the magic number, it will take care of a lot of these problems for us. Now, I have to acknowledge the real world here for a minute.
[ Laughter ]
If you're in charge of everything from conception, design, and implementation, this system's pretty nice. But in the real world you got to work with someone else who may not be familiar with this approach. Might be a contractor. Might be someone else on your team. And it does get tricky. Dealing with that. Because you will wind up having to do some conversion and figuring out exactly what's going on. I wish I had a magic bullet answer to this. I don't. But I do think one of two approaches makes sense.
Either you can just suck it up and do the conversion yourself. This might make sense if you're working with someone short term on a contract. If you do the conversion, what I have found is that early in the project there's a lot of this. You'll do the math for several days, maybe in a week. And you'll get your font sizes in place in CSS. And then you'll find that the workload of that math really drops off. You won't need to do as much conversion. Or if you're working with someone long term, someone on your team, bring them on board. Sit down, hash it out early on. And just use it as your terminology on the team. Then you can forget about the pixels.
So that's font size. Which is kind of what got us into Ms in the first place. We wanted to be accessible. And I get it's our accessibility. But I think we can go beyond that. I think Ms are incredibly powerful if we start using other properties as well. And I'll show you some tricks. There was an article in CSS Tricks a couple weeks ago that was similar to this. I'll modify it a little bit and you'll see why at the end. But consider a design in pixels. This will have a tile module. This is terminology, but familiar with VPN, a block. And this module has padding, border radius, margin everything defines in pixels.
It's got a sub element, a smaller font size, define in pixels. And if you want to scale this down or up you have to get in there and recalculate probably using some kind of scaler. Maybe a smaller border radius, smaller margins, font size. And readjust the element font sizes.
So let's do it this way instead. Let's save some trouble. Let's save the top level element of that module. And we'll establish its font size using rem. It will be our one rem declaration for that module. And having used rem we now know what an M is locally. So if we use Ms for the sub elements of this module, we know what they are. And the computation is only one level deep, two levels deep in a really complicated module. But you should strive to avoid that. One rem value and a bunch of M values for everything in between.
Reworking that tile, everything looks like this, a padding of Ms, 0.6 and 0.2, a border radius in M, font size in rem. For the top level element. Anda font size in M for the sub level element. Now, to scale this, we have defined everything in this module in terms of the one rem value. Change the one rem value and it changes all the other values. It's kind of like reactive functional programming with CSS. Everything just responds to one value. We want to make it large, we can make it large. Everything responds.
So, again, we use rem to establish ourselves in the global font size. And then use M local based on that rem. And I've got buttons here. Rescale the thing. And you can see if you look here at the browser tools that I'm not cheating. That's the wrong property. It's the wrong element. There we go.
If I change the rem value everything scales cleanly. This is kind of fun to play with, actually. So we'll do it again. This is a really powerful pattern. Let's do it with some other modules. Let's do it with a dropdown menu. This drop down menu I've used the border trick to do this. The positioning is an M. Top, 1M, right, 1M. And the border size, in this case, is 1M. That's what determines the size of the triangle.
And we see a demo here. Or you can make it small, make it medium, make it large. Because we use Ms in our positioning, the position of the triangle is always right, and the size of the triangle is always right. And play with it here. Even better, if we open that menu and play with the value it still works. It scales perfectly.
Because this element, the drawer that we've revealed, has the top position of 2.1M. Two.1M is the size of the button. It's the top padding. Here's a different example.
This time we use images. The image is size in M. We can make it small. We can make it large. And because SVG is awesome the image always looks nice and crisp no matter what crazy size we scale it to. Find the right element again. The other thing here I've done is the vertical alignment is an M. Now, vertical alignment used to drive me crazy because I would use top and bottom and center and baseline. It was never right until one day I realized you can put an arbitrary link in the vertical line.
If you use M in an inline image like this and however you scale it, it just works. One last example. This is less of a module, more of just kind of global style. But I'm going to do an effect here with links on the page. So instead of just a normal underline I'm going to use a transition on a box to make that underline when I hover the mouse over it grow and emulate a background image. And, of course, I use M in the inset box shadow. If we see the demo, this is what the effect it. We make it large. And it just works. We could put a link, now, in the heading. We could put a link in the footer. We could put a link wherever we want in the page. And because we defined the size of the box shadow in terms of the font, it's always the right size.
Use this pattern throughout your page. Use rem to establish yourself back into the global font size. So that your font size locally is stable and predictable. Use M within that. And you can nest modules within other modules. They reach back up to the rem value. Doesn't matter with where you place them. They are sized predictably.
That's cool, I need big buttons, but I don't need a large and a small version. Actually you do. Because if we've defined everything on our page in terms of one value, the root font size, all we have to do is change that one value and the entire page will respond.
Something like this. Root, which is also a selector if you're not familiar with that. This targets the HTML element. And we give it mobile styles. Zero.8M on the root element. Medium break point, font size of 1.25M. Now, everything on the page, there's a sample page I stole from my book. Everything here is defined in Ms and rems, which is in turn there's your break point. So you can see at the break point the root font size changes and everything else changes with it. The heading gets smaller, the buttons get smaller, paddings adjust.
Go down to our small break point. Did I pass it? I missed it. There it is. Same thing. Everything scales. Which is pretty slick. But that breakpoint's in the way. So let's get rid of that. We can use viewport relative units now. If you're not familiar with these, these four units are in terms not of a font size, but in terms of the browser's viewport window. We want vw, percentage of the viewport width. Now we can do something like this. Throw away the media queries. Don't need them. The font size is now 2% of the viewport width. See what that looks like.
Same page. Now, there are no media queries in the CSS. As I resize the page everything resizes with it. It's pretty slick. It's fun to play with. Unfortunately it's a little too responsive. Because you get down to mobile size and it's hard to read even on the big screen. And you go to very large screens and it approaches something along the lines of 24 pixel font size on a 1200 pixel screen. Obviously too much. More than we want. So what we need is to soften the effect. We can do that with calc. We'll establish the font size as a blend of an end value and the unit. So that 0.5M serves as a theoretical font size. Even if question shrink the browser to zero it will be at least half of the browser default. Add a few pixels to the actual two, 300 pixels of a mobile device.
Now it's responsive, but not quite so extreme. Now it shrinks to a nice, readable font size and grows to a larger font size, but still, you know, appropriate and responsive.
This is a really cool pattern. I we've scaled the whole page with no media queries at all. Is it perfect? All the way to the responsive design? No. You come in and touch things up. We need to line break these things. And you can do that with Flexbox. We want the columns to stack. Or stick a few selected media queries where you want. But if you use this pattern you'll find you don't need nearly so many media queries throughout your style. Don't need to create a media query for a large break. Don't need one to make sure it's smaller on smaller screens. All of the fiddly stuff will naturally happen. And you can come in and use media queries and touch up the rough edges where you want.
If you are still trying to figure out how many pixels this text is, you're going to have a rough day. But the whole point is, it doesn't matter. Use a scaler math on your font sizes, they will all be the appropriate font size. Your scale works at any scale.
So what we've done is we have created consistent hierarchy of our font sizes on the page. And we have the rem value at the top. Selectively so the root font size at the top. Selectively a module on the page, we use a rem font size to go back and establish ourself. And then leaf nodes inside of each module are defined in terms of the module's root element. And what this allows you to do is get in there at any one point in the tree, fiddle with the value and have the effects just automatically ripple down the tree.
Nesting Ms is chaos when there's no system. But if you use a system like this, keep it structured. Know how it's supposed to work in the design. And you don't have to use my system exactly. But something that you know you understand. Something that you can keep control of. And it gives you very flexible design.
So jump in. I found that kind of trying to do it halfway with some pixel values and some M values just makes a mess. They really don't blend well because pixels don't want to change and the Ms want to change. So go for it. If you're nervous, pick a side project and use Ms everywhere. And rem. I use Ms collectively. I think it provides us with some really cool things that we can get out of our pages. It shortens our code. You don't have to override so many values. You can just tell the browser, hey, respond to this when asked to respond.
So that's all I have. Oh, the astronaut got cut off. There's an astronaut here. But there's the book. The book didn't get cut off. That's good. Here's code right now, good for a week or so, 50% off. First three chapters are up at manning.com. More will roll out as they go through the editing process. It should be finished in print in the spring. And I cover all sorts of stuff.
So this was basically an extended version of my chapter two where I dive into Ms and that sort of thing. But I also tackle fundamentals that developers typically miss. Really understanding the box model and not just at the height of things. And stuff like that. I spend a large section of the book talking about layout, and then I look at code organization methods. Working at scale for very large projects and more advanced stuff like introduction to animations and transitions and that sort of thing. Thank you for listening. And thanks to these people for helping out.
[ Applause ]
>> CLAUDINA: Good stuff. So here's a question that came in for me. How do you propagate like scaler thinking throughout your teams to avoid the, like, three pixels here, 12 pixels here. How do you do that?
>> KEITH: I well, I cheat.
>> CLAUDINA: Cheat.
>> KEITH: I am the CSS guy and I wrote the CSS. But I did have to work with the designer. We had the designer put together the design. And so there was just and I had those thoughts hadn't fully matured. I was still doing the division, compute this to get in and compute this to get this. But I did find that if I just took their pixel numbers and did the math that the workload of that arithmetic did drop off pretty quickly once things were established.
>> CLAUDINA: Are you using Sass functions or modular scale? Or I'm going to think that way
>> KEITH: The code is simple. You can obviously stick the scalers into a Sass or something like that. Then you don't have to commit to memory. You know, just call it up one, down two, something like that would be helpful.
>> CLAUDINA: You're lucky you're the only person. I find it's really challenging when you have bigger teams. One thing I've had to learn is just patience with your designers at first. No, we don't want to use a kale. Now the designers are like I can't believe we did it any other way.
>> KEITH: I think there's just an awareness that needs to get out there. Needs to be seen as a valid approach. I saw that type scale Website ages ago. And the ramifications of it didn't really click until much later.
>> CLAUDINA: Do you think that for a designer, because most of us as frontend, usually getting the designs from a designer, they have done this thinking, and we have come from the measure everything. But their tools don't think scaler. Like they don't think that way, right? Do you think that is probably one of the disconnects?
>> KEITH: What I did on our Websites is if you open your Chrome Dev tools and resize the window, it'll show you the pixel size up in the corner. And so I would make sure that my window was at precisely the size of their mock up. So they gave me a mockup for 1200 pixel viewport. I set it to exactly 1200 pixels and did the math to make it match at that size and kind of the rest fell in.
>> CLAUDINA: Very cool. So we have some questions. So someone asked, what should we set the line length to then?
>> KEITH: You can use a unit list number. I don't think I said that. I don't know if you're looking for the exact number, whoever said that. I usually do 1.2 or 1.5. If you set it M or any unit, really, if you say your line height of this element is 1.5M, what the browser will do, it will compute it for that element. So say 16 times 1.5 which is whatever. But that computed value will then be inherited. So if you change the font size of the children they will still have the same line height as the parent.
I don't know if that made sense. You have to play with it. But if you assign a unit list number, the unit list number will inherit. So the line height will be recomputed every child element. With the same ratio. I hope that makes sense. Yeah.
>> CLAUDINA: It makes sense. The person, if you want more details, find Keith. You'll be at the party, right?
>> KEITH: I'll be at the party.
>> CLAUDINA: How do Ms and rems work in Web components?
>> KEITH: Meaning? React components? Is that kind of or.
>> CLAUDINA: My guess would be the same.
>> KEITH: Yeah, I so I'm not quite sure what to do with that. Like in a React component I use so I would use my module my CSS module of, you know, is the base element. I would just use that as kind of the
>> CLAUDINA: So the component itself.
>> KEITH: Right. So the component should ground itself back to a rem value. So that whatever the top level element of the component is, you know what the established font size is. And you're safe to
>> CLAUDINA: So you're not setting it on a full document, but on a component level that way. That makes sense to me. Speaking about React and things, I was taking a peek at your blog beforehand. And you've got an article called into the future of CSS where you talk about this idea of like scoped CSS. And I was just wondering how, you know, just bring up some more controversy. I was curious what your thoughts like if you could talk about that a little bit. What your thoughts on scoped CSS are
>> KEITH: Scope CSS is a spec that's updating. It's a done deal. I tried to raise a big stink. And they were like, no, it's over. So the thinking was and if you actually look at the recommendation of the spec for the cascade, scope is in there. There's just no way to define a scope. The only way we can actually define a scope is an inline style. If you think about the way an inline style works is it's a small scope applied to one element. And regardless of selector specificity it will override styles out of it.
So the idea with scope CSS was that you could scope CSS to a selector. And it would take the inner scope would take precedence over the outer scope regardless of specificity. So this is what happened for specificity. The net result being that if you design for module A and you style style from module A, style from module B, whichever one you put inside the other will get the correct styles. They won't receive styles from the outer element. Yeah. So the way forward with that is shadow DOM. That's really the replacement. The reason the spec has died is because shadow DOM is taking its place.
>> CLAUDINA: So someone that just wrote a whole book of CSS, and sounds like you also do work with React?
>> KEITH: Yes.
>> CLAUDINA: Where and this is also because of your blog and the articles you were doing, where do you stand curiously on the fate of CSS?
>> KEITH: The fate of it?
>> CLAUDINA: Like CSS and your views of it in this component?
>> KEITH: I think we are having important discussions in CSS right now. The whole inline styles encapsulation discussion. I think it's an important discussion. I'm also incredibly optimistic that these things will find an answer in the spec someday. That may take a few years. But I think that, you know, libraries like CSS modules and, you know, inline styles work as a stop gap and they're a great way to experiment with possible solutions. But if you look at thing like coffee script, which was this crazy thing people were like, oh, what are you doing? And half of coffee script makes its way into the specification. It's JavaScript now. These experiments are important because they will affect the spec.
>> CLAUDINA: Absolutely. That's the content behind the Web manifesto, be that beacon and inform to the browser. Thanks so much, Keith. Really enjoyed your talk.
[ Applause ]
View Slides

Lea Verou

CSS Variables: var(--subtitle)

>> LEA: Hello, everybody. It's great to be here for the fourth time, I think. So before I start talking about variables, I feel like I should introduce myself. Hi, I'm Lea. Here's a fun fact you might not know about me. I'm actually originally from Greece, and specifically from the island of Lesbos. That makes me geographically lesbian. One of the very few you will meet.
Apart from that, I like making stuff. You might have used some of my work. It's on GitHub. I'm an invited expert in the CSS working group. My day job, research at MIT, and usability. And as Claudina said, I have written a book. Totally buy it. Shameless plug there. Oh. Okay.
Now I can't see my screen, though. Okay. Hopefully you can hear me better now. So on to CSS variables.
So the first ever CSS variable actually came way before the CSS variable spec and it was called current caller. It came from SVG. It's been supported in browsers for a very long time. Even I9. And the way it works is it automatically gets the value of the color property. So if I change my color property here, not only the text color updates, but my gradient as well because I use current color here. CSS variables are like on steroids, we can extend the concept to pretty much anything we want.
So let痴 specify a caller variable. So CSS variables are declared with this weird dash, dash syntax. They're essentially custom properties. They work the same as any other CSS property. The dash, dash comes from so many people ask me why didn't we use a dollars or something like that? The reason we didn't use a dollar is that we wanted people to be able to use both Sass variables and CSS variables. They do different things. They accomplish different goals. There are things you can do with CSS that you can absolutely not do with Sass. And there are things you can do with Sass that you cannot do with CSS variables. So we want people to use both of them on the same style sheet. You can imagine it's like a prefix property with an empty prefix. We have like dash properties. So CSS variables are like properties with an empty prefix.
So you call their value, but with the var function. And I can use that everywhere. Almost everywhere you cannot use that in selectors, or in property names, only in property valuesand you cannot use it in the query part of a media query. But you can use them in every property value with very few exceptions that I will discuss soon.
So you can see now if I change the value of the dash, dash color property it changes everywhere. You might not be very impressed. You are thinkingwe can do the same thing with current color and support in more browsers. With CSS variables we can do way more things than just colors. Is a I want to prioritize the size of these corners with another variable called corners. And then I go here, and instead of 90% I say 100% minus the value of this variable.
Which I have to go with the corners property. So the var function. I always make this mistake. I just type the name of the property because it's what I'm used to from Sass. But you have to remember to use the var function to call it. So now I've created my custom property and I can change the size of the corners by just adjusting the corners property.
And you might not still be very impressed. Okay, that was one place in your style sheet. Why not just go there and specify 20 pixels in the color? Just because CSS variables work just like any other CSS property, you can use them everywhere. For even inline styles. And it still works just the same. So the first takeaway from this CSS variables work like the properties. The actual name for the spec is called custom properties, not CSS variables.
And another thing to keep in mind is that they inherit. Here I have a simple structure of three dives, and each contains another div. And I have applied I have said on every div on the page I want the outlying property to take the outlying variable. And this first white div, I've specified the dash, dash outline is equal to this outline. Point to sol I would. But the inner div get the same outline. Because the first declaration applies to it. And it gets the dash, dash outline. And I can target explicitly if I want, of course. But by default all CSS variables inherit. I can specify I can use the universal selector. And giving it a value of initial.
And as you can see this cancels inheritance. I can still target it specifically. And, of course, I can use the inherit keyword if I do want it to inherit. So like this. Sorry. Inherit. So then I can explicitly make it inherit what I actually wanted to inherit. But by default I've made it so it doesn't inherit anymore. And the way this works, this takes advantage of the fact that CSS properties applied directly on an element have higher precedence from values being inherited. And the universal selector applies to every element directly, and, yes, a specificity of severe, but it has higher values than those that have been inherited.
So the second takeaway is that CSS variables are inherited properties, not just they don't just work like any property. They're also inherited. But you can change that. What we saw.
So a third thing is so here we're using this sad.jpg background in an image folder which has other images presumably. So it's a reasonable thing to think about that why not make a variable with the name of the file and then build the URL here? So that I can change the name of the file without having to type the whole path. However, as you can see, this doesn't really work.
So my second my second thought might be, okay, I can try to put the entire path in there. It's not great. But maybe that will work. Let's try that. So as you can see, this doesn't work either. And last attempt. We might think let's put the URL function in there as well. At this point the variable doesn't even help us very much. But we're just experimenting. So let's see. Does that work? Nope.
This doesn't work either. However, this is a Chromebook. It works in Firefox.
[ Laughter ]
This version this version should work. The previous versions do not work. And that's because and that's due to a bug in CSS. That's not due to a bug in the browser. It's due to a bug in CSS. The reason is the URL function has very weird Parsing rules because it can be used with an unquoted and quoted URL. The URL function is the only place where variables don't work. In any other function work everything we saw in the radial function, virals worked just fine. In the URL function, no. If in the future we're talking about adding an alias function that works exactly the same as URL, but has a different name and uses variables. And a way to concatenate so you can concatenate different parts and slowly build up a URL or an SVG path or a ton of other things. But right now, no.
By the way this is kind of funny. So in Chrome that has this weird bug. The bug is not why URLs in general. It's with relative URL. If I specify an absolute URL, suddenly it starts working. I don't know. So the takeaway
[ Laughter ]
Is CSS variables plus URL equals chocolate ice cream.
So WTFs, because CSS after all. So dash, dash foo with an empty value is invalid. That is not quite surprising. If I ask you how many of you think this is invalid, you would probably all raise your hands. The WTF is this is valid.
[ Laughter ]
And the value of the variable here is an empty space. A space, I mean. All spaces are empty.
[ Laughter ]
Also, unlike any other CSS property, variables are case sensitive. Eh. So you could provide to the variables by using the second argument of the var function. So it actually supports a second argument. And you might be wondering, but I can provide in CSS by just using a normal declaration before it like I have done here with the red color. The thing is these two work a bit differently. So as you can imagine, and you have to use both of them. As you can imagine, if variables are not supported, this code snippet would produce a background of red. That's invalid, the browser is like I don't understand this. Would throw away the whole declaration. The place where the orange becomes useful is where the browser supports variables, but there is no accent color set. If accent color has not been set, then it will use orange. If accent color is set to yellow green, it will use yellow green. Of course, that's not surprising. Now what will happen if accent color is set to something that doesn't make sense in background like five or something?
How many think orange? How many think red? It's actually transparent.
[ Laughter ]
It goes with the initial value. So these fall backs can be daisy chained. So you can have color one whose fallback if there's no color one set, is the value of two. Who is fall back is the color three, and whose fall back is red. You can daisy chain them as much as you want.
Also you can combine variables with the @supports rule, and depending on whether they're supported or not. Can be useful in some areas. So if virals are not supported, then this entire rule will not be applied. So you can apply specific CSS to browsers that don't support CSS variables by using the not operator. Obviously they need to support @supports as well. So I'm sure many of you at this point will be thinking, okay, these variables are nice and all that, but would someone please think of browser support? Like surely these things are not supported anywhere. Yet. Right?
Maybe just Chrome? How many of you had thoughts about browser support while I was explaining variables? Yeah? Most of you. So you might be surprised to find that actually CSS variables are supported everywhere.
[ Laughter ]
With one small exception. And to be fair to Edge, because they've actually changed their ways and they're now putting a lot of effort into supporting standards. They're putting a lot of resources into it. So they have announced that they're working on it. It's no development. And 99% it will be on the next version of Edge. So that's good news.
Something that will trip up people coming from the Sass world is that they're used to using variables everywhere and it doesn't matter. Use them in selectors, use them in property values. You can use them in I don't know. Everywhere. You can concatenate them with other things and slowly build your CSS. Because the Sass compiler just spits out CSS. Sends to the browser. The browser never knew what variables you had. That's not quite true for CSS variables. Mostly for the better, they're very dynamic. But there are a few glitch here is.
So in this case we have this div whose width and height are Ms. And we sized based on the font size and scales as long as our font size does. But what if we want to change the proportion of the size and the font size? We want to reduce the size relative to the font size? So as you can see I'm making every change twice. Which is not good.
It's against dry coding. You should try to write your CSS in such a way that you can change things in one place. Otherwise they're bound to get out of the sync, especially as more and more people work on the codebase. So we had the idea that, okay, we're going to make a variable and we might be trying to take it to its absolute extreme, not going to repeat M either. I'm just going to use six. And this is very good in Sass. But if we try to do this in CSS, as you can see it is not working. It's exactly the same as if we haven't specified the width and height at all. And the reason this is invalid is because these variable values are not seen as just random strings. They cannot be anything. This is seen as a number. It's the number six. The browser knows it's the number six.
And if when you try to put it next to the M, it doesn't see a length. It doesn't see 6M. It sees a number nextan identifier. And it doesn't even know what the M identifier is. So and how to deal with all this. How to deal with a number and an identifier? The browser sees this as equivalent to this. So it doesn't know how to deal with it and just throws it away. Of course, you can put Ms here and then it will just work.
And if you want to have six as well because you might to want use it in another place too, you can specify second variable. Let's say side. And then if you have six here you can convert it to Ms with calc. So you call your variable ed in calc. And then you multiply it by 1M. And let's change the variable we're referring to here.
And as you can see, this works. And I can change it here and it just works. And if I want to use the six in another place, I don't need Ms, but I need something else, it will work. You might be wondering now, okay, why do this? Why not specify 6Ms, and if I need somewhere else, I can divide by 1M instead of multiplying by 1M. However, you cannot divide by lengths, you can only divide by numbers. Calc is invalid if you try to do something like this.
So even though you can convert from a number to a unit by using calc, you cannot convert ten pixels to ten right now. Maybe in the future, but right now there's no way you can do this. So it's always better to use variables for pure data, not CSS values unless you're like absolutely 100% sure that you will only need it that you will only these this variable as a length. Then set it to a number. Because you can do anything with a number, but you cannot do anything with a length.
And even in cases when I thought I would only need the length, eventually it turned out that actually I didn't. So it's always better to plan ahead and set variables only to pure data and only to numbers.
So how many of you have worked with CSS animations? Not necessarily at work. If it's a personal experimenting that counts too. Okay. Most of you. Great. So now I think many of you might be wondering right now, okay, CSS variables are cool. But you know what's even cooler? Animating them. And I degree. But there's some problems with that. Because CSS.
[ Laughter ]
So let's say instead of animating background color I wanted to set background color to a variable. Say BG. And let's test that this works by setting BGto orange. And we neat need to cancel the animation first. Yes. That works. And go inside the animation and change to BG instead of background color. Fail. As you can see, this doesn't work. And the reason it doesn't work is both elements of CSS variables and the browser bug working together to make us pull our hair out.
The spec reason is that this is a quote from the spec. CSS variables can even be transitioned or animated. Yay. But since the UA has no way to interpret their contents, they always use the flips of 50% behavior for values that cannot be intelligently interpolated. So what this means is because the browser down know exactly what type these variables are, or pretends to not know because they are tokens. It should know. The browser pretends it doesn't know how to interpolate them. It should be flipping from yellow to turquoise without any transition. The part that's dropping this completely, that's a browser bug.
So yeah. CSS variables and animations equals chocolate ice cream. There is some hope in the future we'll be able so set what our variables are. For example, this is the syntax. It's JavaScript. We'll be able to use this to say, for example, this custom property is a color and its initial value is black. Why do you have to use JavaScript to set the type of a custom property that you defined in your CSS to use it in a CSS animation in your CSS? That is beyond me.
There is some hope. So you cannot animate these custom properties, but you can use var references in animations. So let's say you have color one, which is yellow, and color two, which is turquoise. And inside here we don't need this anymore. I want to say animate background color from color one to color two. And that would actually work. As you can see.
So it's only that you cannot animate the actual variables. But you can use their values in animations. Also, transitions kind of work. Not exactly. I will explain. So in this case I have this slide and when I'm clicking on it switches to turquoise. You can see the code here. Just changing the background from yellow to turquoise. And I have the transition so it transitions smoothly.
So if I did the same thing and I was trying to animate a variable to transition a variable and let's say background is bg. So you can see that now this happens smoothly. Even though what I'm changing when I'm clicking on what I'm changing when I click on the slide is the variable. Not background.
So why why is this happening? Does it mean I can transition variables but I can't animate them? That doesn't make a lot of sense, right?
So this tripped me up at first and I actually tweeted, huh, you can animate you cannot animate variables, but you can transition them. And the editor of the spec replied to me and he said actually what is happening there is not that bg is animated, is being transitioned, it's the background is being transitioned as a result of bg changing. So if I stick my transition here to bg it doesn't work. There is no transition. Because the transition doesn't actually happen on bg. It happens on background.
But still, there's hope. So let's go to some more frequently encountered use cases. I will not mention any use cases of things you can do with Sass variables as well. Because I don't think they're particularly interesting. Yeah, you can set your main fonts enroute and then you can use them throughout your style sheets just like with Sass. You can set your main colors enroute and use them throughout your style sheet just like with Sass. But I think the most interesting use cases are the things you cannot really do with Sass.
I don't discriminate. Or any other preprocessor. Let's just assume when I say Sass I mean any pre processer. So a very common case is having components with their own styling and then creating variations of them. This is a very, very simple component. Just a button. You can imagine how the same thing extrapolating to way more complex components. So I have my base styling which uses a black text color and a black border. And when I hover over it changes to a black background and a white color.
So the I have the same color for the text and the border. And then for the background. And everything else stays in the same in the two variations. So I have a big variation here, but I had to create it explicitly. I had to support the pink class in my CSS. And basically had the CSS override the colors in the base class. How do variables simplify this? Variables simplify this in two ways. Let's say I set a color variable and I set it to black.
And then I use it here. And I use it here. And I use it here. And then I can create a variation just by setting the value of the variable. I can get rid of this entire rule. I only need one line of CSS to create the thing for my component. And it works exactly the same way. I can even get rid of this class and specify it inline. Like, say, color blue. And now it created the blue component. I don't need to have pre defined variations anymore. I have infinite variations suddenly.
Well, nearly. If there are any mathematicians in the room, they would be annoyed if I said infinite. And another good thing is not just that it reduces code, it's also that it lets you style components without having to care about their internal styling. I don't have to care whether the hover effect is done with the background or some other way. Say I wanted instead of a background I wanted to do it with a box shadow. An inset box shadow. Ah. And I need to add a transition.
And you can see the effect. And I changed this effect without affecting anyone's code that is using my component and theming my component. People can use exactly the same code to set the color without having to care whether they're using a box shadow or a background. I'm using a color here, setting dash, dash color to black and overriding it. This is kind of flimsy. Because it means people theming my component need to use higher specificity than what I have in my component. The proper way to do this is to not have a color declaration as all and then provide a full here as we have shown in the second argument.
So this works exactly the same way except people don't have to care about the specificity of their rule to be able to theme my component. And you might be thinking, variables are about reducing code, but this is a lot of repetition. I have to repeat this in a ton of places. So you can set a variable with it.
Or, my favorite solution, is what I call default default values. CC copyright Lea Verou. Default default values. Let's make this a thing. So let's define another variable with that actually calls color and gives it its default value. And then in the rest of my code I just used that variable. And not the actual user variable.
Did I do it everywhere? Yep. You can see. It still works the same. And now we can change the full bug in one place. It's rebeccapurple. Takeaway, CSS variables are theming independent of structure. People don't need to know how you wrote your CSS. Which I think is important for sharing components. And default default values are possible by using another value. People don't have to know I have a co variable here. I just tell them, if you want to theme this component, use dash, dash color. Unless they read my CSS they don't know that code exists. And if they read my CSS, well, they're free to do whatever they want anyway.
Another big use case for variables is responsive design. Instead of having to put code inside media queries you can just set a variable. So and here I don't have to specify a different margin depending on the width of my window. I just set the gutter variable and I can use the gutter variable everywhere in my CSS. So let's try to get off full screen and see how this works.
You can see that now that I've reduced the size of my window I'm getting the smaller gutter size. And this is not a particularly fancy example because it's just one place. As you know in ops, you use this gutter side in many places.
So CSS variables make responsive design much easier. And these are some of the basic, like, cool case interesting use cases that variables were made for. But they're also some more interesting, cooler use cases that I wanted to show. So if you take advantage of the trick I described earlier about canceling inheritance, you can basically create your own custom properties that set multiple other properties at once. So here, because until very recently you needed and still probably for Safari you needed the Web kit prefix for the path. And instead of using autoprefixing or something like that, I defined the CSS variable. And now I can use dash, dash clip path. Instead of having to use two versions of the same property. And because I have defined that on every element its initial, unless I will actually explicitly set it, then both Webkit clip path and clip path will be set to the initial values. Unless I use them explicitly.
So let me try to demonstrate this. It's kind of hard to write clip paths on stage. But I will try. And if it fails, please don't judge me. So we're trying to do a diamond. Okay. This seems to be working. And then zero 50%. Okay. That worked.
[ Applause ]
Thank you. I always worry I will screw this up every time I'm writing a polygon. So as you can see it doesn't inherit. It's like many people when they see this trick they're like, but, clip path will inherit into the children. No, it doesn't. Because we have clip path in the universal selector. That's the trick. If we didn't, then, yes, it would inherit.
So and we can apply this to anything. As you can see. Clip paths everywhere. So we can basically use dash, dash clip path as an alias. And when eventual we stop needing Webkit anymore, we stop using that declaration. We just remove this.
So CSS variables enable you to set multiple properties at once. I think it's pretty cool. Another cool use case is that you can make your own properties that are shortcuts to other properties with somebody's pre fill. So let's say I'm using a lot of purple shadows for some reason. Let's say I really like purple shadows. Don't wonder why. Just go with it.
So I'm using the same trick here to cancel inheritance. And then I'm defining that box shadow is the value of purple shadow plus Rebecca purple. And this is not causing a box shadow in every element, because you cannot have a box shadow that is just rebeccapurple. You need toprovide at least an X and Y of set. So if I'm not setting box shadow, it computes to the initial value and no shadow gets generated.
So here I can just use the purple shadow property and customize the offsets. As you can see. Make an even more horrible shadow. And I can use purple shadow in a ton of places without having to repeat the color anywhere. And even provide a spread radius. Or make it inset.
So tenth takeaway, CSS variables enable you to create property shortcuts with valuables filled in. What programmers would call function carrying in a way. Function carrying is what lets you create a function with some of the arguments already filled in.
So another cool use case is how you can create your own longhand with CSS variables. So this is a bit too much code for a slide. But it's actually pretty repetitive. Defining six CSS variables. One for every aspect of box shadow. And then I'm setting box shadow to all of them concatenated. And I'm specifying default values for all of them except learn. An interesting case is the last one. Notice the default value is a space. That is perfectly valid. Because you either have the keyword or you don't.
So what would you set the default value to? Because by default they're not inset. So you can set it to a space.
And then I can use box shadow blur connection, and set it to ten pixels, and box shadow, set it to rebeccapurple. And so on. And say I want to set it to a different color when I hover. Actually, let's set the offset so it's a more visible shadow. It would look horrible. But or the spread. Yep. That's more visible. Yes, it looks horrible. I know.
But it will be more visible. And now let's say on hover come on. Ah. On hover I want to set the color to something else. Like red. And as you can see, this works. I don't have to repeat any of the other properties.
So essentially took a property that's a lot of values and not a shortcut and created our own longhands for it. So CSS variables enable you to create custom longhands. Something to remember. And lastly, CSS variables allow you to create your own entirely custom properties in some ways. Let's say I I kind of always wanted to have a prepend property that lets you prepend text without having to write the CSS. And you can do it inline or anywhere without an extra rule. In CSS variables you can do that. As long as you have a universal rule to set it to initial, again, to cancel inheritance. And the before element on every element, there is an implied asterisk here that I didn't have to write. It's implied. And sets the property. Doesn't this generate pseudo element boxes for every element? Actually, it doesn't. Because if you haven't set the prepend property to a value, it goes to the initial value, which is none. So it doesn't generate a box. So we can use it like this. You can use it on the inline element on the descendent element. You can use it on every element.
Everywhere you want. And even better, you can use it inline as well. Let's say that seems a good place. Anywhere. So I thought that was quite interesting. So CSS variables enable you to define your own properties. So SVG variables are also be used in SVG, not just HTML. And you can do many cool things with that. So here we have two eyes. Here's the SVG for them. It's a bit much, but you don't have to really process it. Basically these are the eye whites. And these are the irises. The blue and black are just the stroke of the fill. A blue stroke and a black fill.
And I'm also using the eye white path on the clip path so that the iris is actually by the eye, it would be creepy if the iris was overflowing the eye.
And here I'm setting the horizontal center value of the iris. Remember, these are the elements that have the iris class. Here, class equals iris. And also here, class equals iris. So then I can change this. And it looks to different places.
[ Laughter ]
Do you feel watched right now? And let's see. It's 75 pixels to get it to look this way. Or actually that way on the protection. It's this way on my laptop. That's weird. And it's 25 pixels to get it to look this way. So I kind of want to set where it looks without having to care how the SVG is thrown. So I can set a look variable which is which goes from zero to one. Let's set it to 0.5 or something. Zero.2 or something. And then we have a remember, it's 25 to 75 pixels. By the way, these are not real pixels. These are based on the coordinate system of the SVG, which is defined here in the view box.
So I can scale it and the meaning of those pixels changes. It's relative to the SVG. I can say 25. I don't have to say 25 pixels. It doesn't make sense. But Chrome is a bit buggy if I don't use the pixel unit. Like I can set it to 20, but I cannot do calc. Twenty five and 50 just doesn't work for some reason. If I specify pixels here, it works. I think that's a bit odd. But I have learned to live this these bugs.
And then I can go look here and now I can change this and that's all I need to know. I don't need to care whether it's 25 pixels or 30 pixels or 150 pixels, I just change the look variable that defines whether it's looking left or right.
You can also combine CSS variables with JavaScript. And that's actually some those are actually some of the most interesting cases. How many of you do write JavaScript or do know some JavaScript? Okay. Great. Great.
I'll keep it vanilla and it's only like a few lines. Example. So hopefully it shouldn't be too overwhelming. So first off, to get the variable from the inline style of the element you use Element.style.property get property value. We don't use it have often for other properties, we don't say font size, we just say element.style.
fontsize. But because they don't have the version, we have to use this generic function. This will only take the value from the inline style. You have to get the computer style instead if you want to get the value, regardless of whether it's inherited, whether it's set to the style sheet, whether it's set inline. These cover all the use cases. And to set it, use element.style.
property. You don't usually care. That's fine.
Some of you wonder why is it get property? I don't know. It's another API design mistake of the CSS OM, of which there are many. So the first example I want to show you has to do with writing CSS that depends on mouse movement, which is something all of us had to do at some point. Many of us. And usually the way you do it is you set the CSS in the JavaScript. And you generate it there. So with CSS variables, don't have to write CSS in the JavaScript except setting the variables. Like here, I have a mouse move event listener on the document. And I'm setting two variables, mouse X and mouse Y on whose values are the percentage of how much the my cursor is moved horizontally and vertically. And it's a number from zero to one. Why is that the case? Why do I not set them to pixels? Because if there are numbers like this, I can convert to pixels, but I can't do the opposite. And I want to convert them to measurements based on the viewport, I can multiply by 100VH or 100VW.
So here I have the radial gradient. I want the center to vary depending on my mouse movement. So I use calc. And 100% multiplied by var, mouse X. And you can see now it moves horizontally based on my mouse pointer. And I can do the same with the Y coordinate. And now it moves based on my mouse pointer.
And I can I can change the CSS without if it's different people writing the JavaScript and different people writing the CSS, I don't have to go and contact the developer if I want to change the CSS and say, hey, actually I decided that the color stop would be like closer together. And please change this. Sorry. And the developer's like, you always change things. I'm so fed up with you. Can you just please learn some JavaScript and do it yourself. No more friction like this anymore. You tell the developer to set your CSS variables. You use your CSS variables in your CSS to do exactly what you want and you can change it and tweak it as an as you want without having to bother anybody. I think CSS variables are the answer for the React people saying put CSS in JavaScript. You can vary JavaScript on things, actually you don't. Just set a variable and put the styling where it belongs. In the CSS.
[ Applause ].
Thank you.
[ Laughter ]
And remember our SVG demo? So what if I wanted these eyes to actually move based on my mouse? I could actually use mouse X here. I don't think I have to do any calculations. Yep. I could just use mouse X here. I could even remove this. And they just work. I didn't have to set another variable for this. I can just use the mouse X I have. I can use the one event listener and then use it in anything. That's based on the mouse. These are completely different demos and both of them work with exactly the same variable.
So there. Also, another thing I often wanted was to be able to access a value of an input in CSS. And sadly you can't. But if you write a little bit of JavaScript you can set a value variable on the input. So here we're going over all the inputs in the page and we're setting a variable of value on them. And also we're setting an event listener on the document for the input event. And then we're setting we're resetting the value on the input. This is generic. This will add even if you add more inputs. Even if you add more inputs on your page. It's using event delegation. Now I have a slider here. It's I've already applied appearance to it, so it doesn't have the default value, the default look. And I wanted this gradient to move let's apply border. I don't like how this looks.
Okay. Eh. Anyway. I'm not going to be tweaking design now. So I wanted this gradient to move with the slider. Right now it's fixed at 50%. But I can use calc and use the value variable. And the value variable goes from zero to 100. So I need to multiply by 1%. And now it works. Now it changes based on the value. It looks kind of horrible. But that was the simplest demo I could come up with. Anything else would have a lot of CSS just for styling. And I didn't want to clutter the demo.
In effect I talked about in some of my talks a few years ago was doing a doing a typing simulation with CSS. How you could use animations for that. So the main idea was you had two animations. One for emulating the current, which made it blink from a border color of transparent to a border color of current color, which is the default for borders.
And you can see how this works on the current. It's already applied. Because it's kind of unrelated to this demo. And the actual typing was done by animating width from zero to the number of characters you had with the CH unit. The CH unit, the width of the zero character corresponds to the width of every character. So let's show how this works.
At this point no variables are in this demo yet. So let's try to animate from zero to the current width. I'm applying the typing animation. The frame is automatically computed by the current state. And let's say ten seconds. And now if I apply it and unapply it if I apply it again, you can see it doesn't quite work yet because we need this steps timing function and set it up to the number of characters as well. So now it works. However it's not very maintainable. You can do it for the heading of each page, but individually. And you can set it with an inline style, but it's really messy. So the good thing is that with JavaScript you can go over all these elements that have a class of typing and you can set CSS variable of length to the length of the contents. And now I can use that variable here to make this effect work regardless of how many characters my heading has. Or my paragraph in this case.
So here. Okay. And now you might be thinking this looks exactly the same as before. How do I know you're not messing with us? So let's change the text. To CSS variables are. And apply it again. And you can see that that's a bit too slow. But it works. And the reason it's slower it seems slower than before is because the duration is ten seconds regardless of how many characters I have. So I need to also value the duration. So I use calc again with length. And I multiply it by the duration I want for every key stroke. Let's say 0.2 seconds because I'm kind of running late.
So you can see the now it works. Regardless of how much text I have. I can reduce it to CSS. And if I apply it again, the key stroke every key stroke has the same duration. And last demo, because I'm running late. Is so it's pretty popular these days to vary CSS depending on the scroll position of either the whole page or a specific element. And you can do that with CSS variables as well.
So here I'm getting all the elements with the class of scrolling, and adding an event listener on them. And every time they're scrolled I'm calculating the maximum scroll. It's the whole height of the content minus the height of the element. And then I'm calculating how much are they scrolled compared to the maximum scroll so that I get a number again from zero to one. And then I can do a lot of things. I'm setting a CSS available of scroll to the value. I have it here, to 20% regardless of how I scroll. I'm going to use my trusty calc and multiply 100% by the value of scroll. And now as I'm scrolling the gradient varies. And just like all the other demos I can change the presentation without having to do anything with the JavaScript. If I want, instead of this instead of this kind of gradient, to have a progress bar at the top. And I want to set like background size to something like this. And I want to make this red. And I want to make the background not transparent, but white.
I can do that. No need to change the JavaScript. No need to bother any developer if I'm not writing my JavaScript. It just works. So I think CSS variables are revolution for separation of style and behavior. And at exactly the right time. Exactly the time, let's move all our CSS and the JavaScript and let's just have JavaScript consume the entire Web and everything.
[ Laughter ]
So they're set for that. These are the specs. The first one is the stable spec. The second one is the editor's draft, which is like the most updated one. And one last thing, very, very quickly. So CSS variables are the present. Not the future. What is the future? There are many discussions about custom uploads, custom functions, all sorts of things. One thing that is a bit more near function, the @apply rule, it's in Chrome. It lets you do native mixes. So, for example, I can have like a border here. I have two declarations. I'm saying @apply this. And the dash, dash bg is a set of declarations now. I'm applying all of them by using that apply rule. Sadly if I use a variable in here, let's say foo, you would expect that this would work, right? And you would get a red background so you could have mix ins with parameters. Sadly, it doesn't work. What works is if I if I put foo here. So variables are resolved based on the defining scope and not the calling scope, which I think is very unfortunate. Thankfully this is pretty early stage. Maybe we'll change in the future. I don't know. Anyway. That's all I had for you today. Thank you very much.
[ Applause ]
>> CLAUDINA: Thank you. Awesome. Great talk. Lea, we I wouldn't worry about sitting down over there. We are short on time. But I have one question that came up. What's like the performance implementations of handling CSS variables? JavaScript and have you done any performance work?
>> LEA: I haven't measured performance, but I have used them extensively and haven't noticed a slowdown.
>> CLAUDINA: Are you using them as a mass sort of scale of completely like rewriting all of your code ifyour components and doing it this way? Or using it just in smaller examples?
>> LEA: Mostly smaller things. I'm kind of dipping my toes in it for now.
>> CLAUDINA: Do you have any projects down the line that might be bigger that you're working on? Yes?
>> LEA: Yep. But I can't talk about that yet.
>> CLAUDINA: Exciting. Well, we look forward to that. Thank you very much. Great talk. A big round of applause.
[ Applause ]
>> LEA: And by the way, you can find my slides in that URL over there. And they have the slides themselves are using CSS variables in a number of places. So that's even more examples there.
View Slides

Sara Soueidan

SVG IRL

Coming soon

Henri Helvetica

The Hateful Weight

>> HENRI: All right. I guess I'm using the mic. Not wireless. It's all good. I can make it happen. Actually I'm just going to do this. Sorry. I like to pace around. So I'm just going to hold on to it like this.
Maybe I won't. Okay. So okay. I guess everyone can hear me. Man, so I just wanted to address one thing real quick. Oh, my god, what's going on here? Okay. Well, I guess it's not super bright. No sweat. What was that? Okay. I can't tell. Okay. So basically yes. My name's Henri. I'm French. And my sorry. My handle is Henri Helvetica. I thought it was interesting and had a good ring to it. But a lot of people believed it was my real last name. So I'm here to say it's absolutely not my real last name. And now I felt weird. I thought I was having this Obama birther movement. People are like, snappy last name. I'm so bummed, whatever. People kept asking me. I'm sorry. Mean Santa Claus. So I just wanted to get that out of the way.
But that is my Twitter handle. So you can hit me up all day. Anyway how, yes, I'm from Toronto. I do run. I enjoy that quite a lot. And in fact today's Tuesday, so if I was back in Toronto I'd probably be running with my running club tonight. So in an ode to that and my coach, she likes to do this thing. It's actually pretty cold in here. If I could get everyone to join me in a bit of a hand clapping situation.
[Clapping]
That's what I'm talking about. So we're going to have some fun. I'm here to talk about whoa. What's going on here? Oh, there's Kanye. There he is. I couldn't tell if he was around or not. Kanye approves.
So I'm also going to do this. I'm going to give away some books later on today. I'm a big fan of books. I love reading them. So if you want to sort of take this down, you can take a screen shot of it or whatever, picture. You want to Tweet that later on during lunch, I'll be giving away these books and just hit you up. Yo, come check me out. I have a book for you. Obviously it's related to all this. Anyhow, let's get cracking.
Normally around this talk I used to kind of show this video, but especially today since I'm short on time, I'm not going to get into it. But it's basically a very well-known developer, asked what's going on with the Web and what's going on. And he went on a rant, it needs to change. It's Kyle Simpson. Very well-known JavaScript developer and this is what he had to say. The Web is primarily being built by a group of people that take for granted and you can see the rest. And he went on to add something like this. Sorry, guys. I'm trying to get comfortable. All right.
And then, you know, he chimed in some more with something like that. Actually, no, that was me. And, honestly, this is the reality. And I know somebody talked about this yesterday. But this is actually Tim's desk. He's got a great 11 inch Macbook Pro Air, I believe. And the awesome ultra-wide LG screen. Those are signed of sick. I'm trying to get my hands on those. But these are beautiful devices. And this is kind of like what we're working on. But it's not the reality of the planet. The world.
Outside of North America it's not that gangster. Yeah. And Kyle Simpson added with more details here. This is absolutely true. You know, the way we are crafting the Web there's quite a few people outside of North America in these emerging markets who are not going to get what we're doing. And in fact this is part of a a blog post that on Facebook engineering page. And they talked about how they went to Africa and they were trying to get a sense of what was going on in the hand sets and how they were trying to make their sites faster.
So this is a promise that they have made as well. Now, getting back to Tim Kadlec, he talked about this. I think it's a cultural thing, primarily. Cultural. And I want to talk about that as well. There are two things that I think are very important. And one of them is accessibility. One of them is performance as well. And with regard to the performance thing I also believe that it's cultural. If I have to do one thing and one thing only, I want to make sure that everyone leaves here with the idea that they need to craft the Web with performance in mind.
Because, again, I'm going to get into some examples. Once you get into developing countries it gets very tough. And we're going to talk about images. And images pretty much are the lowest hanging fruit when it comes to performance. And speaking of fruit, anyone from the West Indies here? I'm pretty sure I'm going to see no one. But I have to ask. Anyone been to been to the West Indies. Okay. A couple. Pare down. Anybody been to Jamaica? Okay. This is a fruit from the ackee tree. And essentially when not cooked properly this is actually deadly. And I've compared performance to dieting quiet often. And this is pretty much a very good parallel. You mishandle images, bad things will happen. And we're going to get into that.
So like I said, performance pretty much dying and we'll see some parallels. So I want to welcome everyone to the hateful weight. I guess you guys hadn't seen that. I thought I posted it. But I thought I was going to have some fun. Word play, et cetera, et cetera. But we're basically going to explore some of the challenges that images are making. Some of the challenges we have with the Web. And images. So the hateful weight. This is a five part tragedy. Man, this has got to be a bit better. Act zero, we're going to talk about how we got here and you're going to see it's actually a lot more common than you believe. We're going to get into the implications, UX, the networking that's involved. You're going to see that as well. The main characters, the villains in the tragedy. And we all know who they are. And then get into the denouement. And then credits, et cetera, et cetera, et cetera. Anyways. Let's go.
How we got here. Man. I don't know sorry, guys. I'm so like not comfortable right now. So it starts in a place that pretty much is here. And if anyone knows what this is, it takes you pretty much to Buffalo, New York. Right outside of Toronto, in fact. And someone by the name of Obama was not there. But the gentleman on the left, does anyone know who that is? That is Steve Sasson. He basically created this. The very first digital camera ever. About 77, 87, eight pounds. Zero.01 megapixels and photos tyke like 23 seconds to transfer to that cassette. Some of you guys might remember how data used to go to cassettes back in the day. Back if the day. And this was pretty much how big it was. Imagine putting this in your pocket. If you could.
But it progressed, about 25 years later, to something like this. And now we have something like this. And if you've not seen this, this is 7 plus with the two cameras. Gets like god, like 60 some megaphotos when you do the panoramic. And you can actually ask Mr.Snook somewhere around here. He brought his. Anyhow. But the point is that it's become very cultural to just have your camera with you and snap all day long.
And essentially these photos are finding their way to the Web. We love pictures that tell a fantastic story from sad moments to very scintillating ones as well. Now, anyone familiar with photowalks? Any photographers here? Anyway, photowalks are a group of people that get together and they man may just go on walks together and snap photos all day long. And you'll see it's very somewhat in the 20, 25, 30 age range kind of. And they're snapping photos and sharing them online. And this is sweat pants Steve. One of the leaders of this community. But here this is happening also overseas. And you can see right here people, again, taking photos. Same area. And with the goal of sharing them a little later. We share experiences.
It is cultural. Rest assured. In fact Facebook, 105% more comments when the post is associated to a photo. Anyone knows what this means? Yeah? I guess so. This? This. This. Again. This is all cultural. We've become accustomed to sort of sharing our stories with photos all day long.
2012, 500million photos were shared daily. In 2015, that was 3billion. All right? And it's not slowing down. Anyone familiar with Unsplash? It's kind of like a high res photo stock image sight. They're out of Montreal, actually. Great resource if you want to get some stuff. Anyhow, each month 1billion images viewed, 5.5million photos downloaded.
And again, this is about the sharing process. Since the Web is a great sharing medium, we end up with heavy page. But it's not you, it's cultural. Like I said. Anyways, get into details. 2012, it was 20 megs, and today, manageable. 2012, 50 requests, 696 kilobytes. And 2016, 57 requests, 1.5. Not that many more requests. And 64% of the pages are just straight images. You can imagine this is going to be significant weight. Part of the issues as well is things like responsive Web design happened. And no matter how you slice it some complications have come about with that as well. And one of them is retina images.
We all know retina images to an extent. It's about three to four times the actual amount of pixels that you need for displaying. And then you have things like this. Device fragmentation. Now this is 2015 and every little block there represents a device out on the planet being used.
So things are pretty complicated. Hey. Seventy two% of pages send the same content to mobile. Just think about that one. Raise your hand if you're trying to be part of the 28%. Oh, people doing their math in their head. What? What is he talking about? Yes, you want to win.
And, again, you have situations like this. Now, I like to hang out in the network panel quite often. I don't know if you can see that, but you will when I push the slides out. You have quite often improperly sized images. And in fact when I was speaking to someone in a conversation, so, what do you think is the most common issue in terms of, like, image management? And he's like, pages I mean, images are being sent down to the right container.
Here's a Tweet from just about a year ago. So, again, imagine asking for a tall coffee and being charged for a venti. This is pretty much what's happening right now.
And you can tell down there, 280 crass, but the sent one that was about a 1,000 across. So you basically have an immense amount of useless pixels being sent down the pipe to the client.
So, again, users, we don't like page weight and we're going to deal with it. So what are the implications of this? There are some serious implications in fact. There's user experience involved. There's network. So the Web is slowing down. Yeah, kind of. Because think about it. The Web is very rich. The applications we're sending down, the Websites, JS, it's like animation. It's page weight. It's render images. Things are slowing down. And what are we really after? Designers, developers? Very good or fantastic user experience. And user experience is also for usability. Because you know when that site comes up and you're kind of seeing stuff happening, but you're not sure what's going on, that's an unusable page. And part of the issue is some of the page weight that we're dealing with.
Now, in some very recent stats, and this came out last week, 53% of visitors will abandon a page when it takes three seconds or more to load. They're saying the sweet spot is somewhere around 2, 2.5 seconds. But at 3 customers are gone. Imagine that. Three seconds. Here's another stat that was pretty interesting. Any sort of like blog or media site sort of practitioners here maybe? This is important. For you, anyhow.
And then we get into some perversions, even. Obviously that's going to be important. That's where you make your money. And this is from a couple years ago. And you can see some of these stats on it this Website, WPOstats which is a site that's being cure rated by Tim and Tammy. Great performance engineers. And she mentioned that sessions that converted had 38% fewer images. Fewer images. So let's talk about this money again. Netflix very common, very well known brand saw 43% decrease in their bandwidth bill after turning on Gzipping. It's compression. Imagine turns on gzipping, compressing the data and almost cutting the bill in half.
Back to Unsplash here. Anyone here host their clients themselves potentially? Or yeah, kind of. These are things that you want to think about as well. Now, Unsplash, that site I was telling you about, 2016 hosting costs in one month. The bandwidth alone was 10 grand. So, again, imagine slicing that more or less in half if you could. That's what I'm talking about. But it's not enterprise only. So this is Dave newton who's actually a senior Dev over at Shopify and this is something that happened to him. This is fairly common. People hit their data cap and they can't do much. He was so angry well, then again he was talking about some sites. But he was so angry he took it to Twitter. And I said, dude, this is so gold, this is going to be a slide one day. There it is.
And, again, this is something else that Facebook commented about. And they realized that it's very important to optimize images, to make sure that your users are not blowing caps just because they're on your site. I actually keep an eye on my data as well even though I'm good with it.
Just so that you know the idea that you might blow that data cap is becoming more and more common and people are using these all the time. Now, one of the challenges out there is the fact that the Devs I'm not saying they're not doing their job but browsers realize this is a big problem. So now we have these things called well, this is called browser interventions where basically they try to save the day. This is Opera, ye of 250million users in Europe. They have a suite of apps that are there to basically help you with data savings. And you can see right here is a screenshot, again, doesn't come up super clear. But over on the left hand side you can see that they'll tell you what they have been saving for you in terms of data. And over on the right you'll see some extra details. Like right here.
And you're actually able to sort of manage the images that are coming down the pipe because they realized a lot of the times they're not coded properly. Or optimized properly. And that's just to show you right there. And again, how does Opera turtle work? It shaves off image pixels. They realize the data caps are being blown through images mostly. Google Chrome, in fact, is thinking about implementing lazy loading within the browser.
Because I could get into greater detail, but, again, it goes back to the idea that why load an image if the user is not going to look at it? But right now that's happening as we speak.
And, again, getting back to the idea that there's also a networking element to it, the network from the 4G, 3G, 2Gs that are all over the planet, they're not always our friends. This is a shot of and this is from Facebook as well. This is a shot of connectivity across the world. And I don't know if you can see this well, but yellow is 4G. Blue is 3G. And 2G is red. Now, it's predominantly yellow in North America and that's really it. And when you have 4G or 3G or 2G, t it's never like 100% 4G, 100% 3G. It's sort of 3G ish, 2.5, what? These are things you need to take into consideration.
Now, something happen?
[ Laughter ]
So, again, they want Facebook to work for everyone no matter the region, network, condition, or mobile device. Now, these are the things that you can look at yourself as well. And this is a Tweet that I had from who knows when. But you can go and someone talked about this yesterday. You can actually go into Dev tools and network throttle the page. So that you could actually test this yourself. You know, you might be at home, like, oh, man, I got my whatever. But you go in and drop it down and you have a bunch of settings so you see how the page will load in a browser with limited bandwidth. And, of course, with some latency as well. So those are some of the implications on a UX level. Dollar level. And also networking.
But now let's take a look at the main characters. Again, 2016, 2.4 megs, that's the average site. Fifty seven requests. 1.5 megs. Of those 1.5 megs, 1% SVG. These stats are coming from HTTP archive where they get data from the top million sites. One% with anyone familiar with WebP image format? When we leave it's going to be all hands. You like that, my man?
24% GIF. We're going to talk about that in a hot minute. Twenty% PNGs, and obviously 44% jpg. Which is, JPEG, the most common format.
Now, let's talk about the GIF. The most antiquated format for sure. Format, it's lossless. It was a bit of a fade for quite a while. It had the alpha channel. Transparency. Extremely well supported. Been around the longest. Ironically fading in popularity. A lot of people like to use animated GIFs. But quite often these animated GIFs are not animated GIFs anymore. And some of these GIF purveyors and merchants are giving you mp4s. As a format they are too big, get very heavy and sort of falling out of preference. But like I said, it's antiquated.
And some would actually tell you that it's actually a completely useless format. Everything that it does, there's another format that does it better. That's the bottom line. So my recommendation to you is no dice in the GIF. GIF, GIF, whatever you want to call it. So you look at the PNG. Or PNG, portable network graphic. Part of what I'm doing right here, actually I'll get into that after. So, yeah, 1996. The PNG came after a battle with the GIF and became a bit of a better format. Raster format, lossless. And there's some lossy compression involved. We can talk about that. Alpha channel, support, and to this day, the PNG is a bit of a trade for the transparency element. Phenomenal support. You can see right across it's green.
And everyone here is familiar with can I use the Website, yeah? Just plug in whatever you want to check and see what the support's like. It's grown all around. Obviously the PNG is a great format. You can get some animated PNGs. But here's one thing you have to keep in mind.
Actually this format and the JPEG which I'll get into a little later, they both contain Exif metadata. Hands up if you're familiar. Hands up if you're stripping it out of the files. Okay.
So let me show you something right here. This was a shot I took while at Starbucks testing a site. And I was like, man, let me see what this metadata is seeing. Well, this is what's in fact this is only a part of what's embedded in the picture. So you'll get god. You'll get like the device name. You'll get obviously the size, the pick, the geolocation, why you are, et cetera, et cetera, et cetera. In fact you can look this up, but crooks have been caught just off the EXIFdata from photos which is totally wild to me. Anyhow, this is the kind of stuff you have to strip out. Because in fact this can take up to 15 to 17% of your image alone. If you had a 100K image that had Exif data in it, you're talking about saving potentially 16 to 17Ks, very important especially if you're taking this to scale.
Now, let's talk about the SVG. I'm going to race through this quick. There's some very, very knowledgeable SVG people in the place here. And I would not feelcomfortable skipping over details. You can check with them. You know who you are. Anyhow, the SVG, fantastic format as well. Now, even know it's only 1% of the top million sites, I think this is something that's going to change. I mean, top million, you're talking about, you know, there are some antiquated sites in there and whatnot. But vector format, very important. This is something that's going to be resolution independent. You're also talking about it's really good for logos, icons and illustration. As Sara Soueidan mentioned earlier, there's decision making with the SVG. If the image is way too detailed, it's a good chance the SVG is going to come out too heavy. But these are things you have to figure out in your meetings.
Now, SVG, again, fantastic support. You can look at it right here. Green across the board. And, again, in terms of sort of like compression, does well with gzipping, SVGO and a great tool to compress it. Even though it's at 1%, it's growing in had popularity. And conferences, everyone is talking about it. Oh, man, I got to put an SVG here. It's totally working. You definitely want to keep the SVG in mind.
Now, let's get to the WebP. Sorry, guys. Now, very, very recent technology from Google, of course. Lossy and lossless compression. Has an alpha channel. You get some transparency. And you can get some animation out of it. Now, what are the challenges? Poor support at current. And there aren't the most encoding tools for it. There are a couple that you could use. But I'll get into that later as well. Also with the WebP it's a bit of like a buzz saw. You get fantastic data savings. For now, I kind of want to expand on that. The WebP came out, whatever, man. I'm going to talk about this. Firefox, Mozilla, they weren't really stoked about it and felt the JPEG still had room for optimization. Which it did. But one thing for sure, you couldn't deny the WebP. Any hockey fans in here? All right. Does anyone know who this is? Probably not. This is Willy O'Ree, a Canadian, the first African American in the NHL. 1957.
So I just took a quick screenshot and I was on my phone. And this was about like 1.5 megs or so. And this is the kind of compression that took place. And I don't know if you can see this real quick, but again, you'll see it in the slides. The original ping was about 6 megs. So I went down to a loss list, WebP, which was 3.5 megs. Like no no size differences in terms of like dimensions.
Then I went down to an 85 quality JPEG, an 85 quality from like Photoshop. That came out to like 1.1 megs. But at 85 the WebP came out to 340 kilobytes. Now we could get into the, well, you know, we have to check out quality. And the quality thing is a much different conversation. And I mean, I'm going to talk about it about is at the end as well. But these are significant savings right here. And, you know, what ended up happening is basically we figured out that, yes, it's going to have a promising future.
Even though you have a situation like this where you don't have a lot of support. But that's all going to change. Because this happened earlier this year.
Now, I'm a big Safari fan. You can boo me all you want. But I still use Webkit all day long. They actually had WebP support in beta for like a week and a half and then pulled it. Well, you know, we're just experimenting or whatever. But this is actually very significant. Because this is likely coming back. Now, I mentioned earlier that Mozilla, Firefox, they池e like, well, you know, we're really about the JPEG, et cetera, et cetera. But this happened.
The same bug essentially reopened the bug for WebP implementation. And it looks something like that. So basically what's happening is this. You have the major browsers outside of obviously Chrome who implements it, or should I say Blink Engines which also includes Vivaldi. Is Molly here? She's not. You're going to have in the near future a lot more support for WebP. This is something to keep in mind. I don't have the slide up, but look at browser share across the planet, Chrome is between 50 to 59%. So six out of ten people across the planet are using Chrome. Again, significant savings for your users. Now let's get to the workhorse, the JPEG. We know it very well. Lossy, yes, lossless as well. And I can get into those details. Fantastic support. That's, again, without a doubt that's not being debated. The most common format by far. And as well this is the format that's coming out of all your cameras. So, again, this is something you want to keep in mind.
Now, best for photographs, obviously. And the Exif data you have to strip out. And when I say it's capable of extreme compression. So without getting into the real heavy computational conversations, but you're able to get even more savings by doing this thing called scan layer optimizations. And what you thought was on optimized JPEG, there's room to go. And I will have notes about that later. You're drawing blood from a stone essentially.
The interesting part about the jpg, interesting variants. The JPEG 2000, unfortunately it's Webkit or Mac supported only. Losses, great compression. The same thing happened with the jpg xr. Again, another format that came out of Microsoft. Pretty much the same details. Great compression, lossless, but also an alpha channel. Now, what ends up happening is this: when you start to serve these images and depending on the browser you might be able to serve a jpg2000 if you know it's a Safari client or a jpg xr if it's that client. Some are doing it as we speak. You may not know is as a user. You may not care. You want the image to come in as fast as possible. So those are the main characters. Now the denouement. So what does this all mean? Again, what you have is what I was trying to basically convey by having all these formats and laying their strengths and weaknesses is the decision making that you have to go through with your team. So when you're sitting down with designers and developers and UX people and all in between, you can make the proper decision as to which image format is going to be used for which perfect, say. If you have an illustration the chances are you're going to look at the idea of having like an SVG. If you have a very crisp picture you might be like, okay, maybe this is going to be a good JPEG or a PNG. Who knows?
So there is decision making in this whole process. So what I'd like to say is always keep performance in mind. This is super, super important. Again, the emerging markets, they're all coming in on mobile phones. And mobile fines can't handle what we've been sort of like shipping out current because, again, in America we're very comfortable. We got the 4G, you know, LTE networks, et cetera. But we have situations like, say, in India, which is the fastest growing market as we speak.
And in fact I'll give you a quick story. I was at velocity last week. Anyone know velocity? It's a conference, they talk about DevOps and performance. Ran into a gentleman who said he was having issues with images. Okay, let's talk about it. Out of nowhere they actually start to get a bunch of traffic out of India. And they're like, okay, cool.
But they also realized some of the issues they were having because some of their users were constantly having problems accessing the content. So dude was just pulling his hair out. And that was part of the reason he was at velocity. So you need to keep performance in mind at all times. Plan your image strategy.
Like I said, sit down with your team, figure out what you need to do. Have these conversations. Maybe it's a situation where you might not use a particular image if you think it's going to give you a hard time.
Again, be kind to your users. Understand where they're coming from. Look at your analytics. See how you can improve the user experience in light of their situations. Optimize as much as possible. Obviously that goes without saying. Maybe you want to offload some of the work. Use a CDN. Depending on how big your project is. And, of course, use the tools at your disposal. Now, this is I'm not going to say this is like super easy, but something that I do all the time. I literally live in the network panel. And, you know, Safari, Chrome, Vivaldi, Opera, they all have it. And you can always take a look at what's going on at your image management. And your site, really. And, you know, something like this you can see clearly with the it's like kind of like a waterfall chart in a sense.
Now, I know I raced through this. But this is pretty much the end. I know we are behind schedule, so I was trying to accommodate all as much as possible. Now, credits, resources. These are some of the people that I think you should follow. Again, I'm going to put the slides up. Tammy Everts, amazing out of Vancouver, Google, Steve Souders, the pontiff of performance. Then there's some other guy. And a bunch of other people who I think do great work. I'm actually going to give away the two this one right here. So if you're Tweeting me I'm going to get at you.
But these are actually also all available. That one's online. You can read for free. Designing for performance is a great book as well. You can read that for free. If you want to get really nerdy and get into some compression there's a book on the far right which came out just maybe a couple months ago. And I also want to talk about this book right here. This actually is on its way out from O'Reilly as well. But it's a joint venture. And they talk about some of the issues in much greater details when it comes to images and how to ship and how to deliver, et cetera. And I'll be giving away that book as well. Extra readings you'll see. And that's really it. Thank you very much.
[ Applause ]
>> CLAUDINA: I thought you lived in Toronto. You said you lived in the come. Let's have some questions.
>> HENRI: That was funny.
>> CLAUDINA: You might have to leave that one over there.
>> HENRI: Oh, man, come on, now. Miriam took the wireless one. What can I say?
>> HENRI: Inside the Actors?Studio.
>> CLAUDINA: Inside the Dev Studio with Henri and NCCS. All right, what are your techniques to handle images responsibly and responsibly and responsibly?
>> HENRI: I mean god. I didn't talk about like the picture tag or anything like that. But that's something you definitely want to keep in mind. Source that. Again, I just believe it's beyond I actually think that people just grab pictures from the net and just throw it in their pages. And I see some head nods. I'm not calling anyone out. I'm just saying, you know, these are the kind of mistakes that I see. So I do believe it does take a bit more planning outside of just finding a photo you like and going ahead with it.
Now there's some changes taking place as we speak. You know, I did talk about the picture tag real quick right now. And source set tag. But there's something called client hints that's coming around the corner. It's like going through an implementation right now. It's in a flag. But they realize it's gotten a little complicated and they're doing the best to, you know, it's almost like a browser intervention again. You know? They just want to lessen the load for develop developers and all the decision making they have to do. So yeah.
>> CLAUDINA: And lastly, do you have any image PDNs that you like to use or recommend?
>> HENRI: The thing about the CDNs is they all actually have their own qualities. There are some big ones, obviously. But even some of the small ones, they tend to sort of like have their own sort of little services and whatnot. So these are conversations that you literally have to have with them. And depending on what you need. But for the most part they're out there to help you with some of these issues. Especially if you're going to scale. Because, again, on, you know, a I don't know. Like a small mom and pop shop you might be able to handle this yourself. But once you're dealing with much bigger companies I do believe like a CDN is somewhere you want to go to and have the conversations and see what they can do for you in terms of their services and whatnot. Because they have a lot more, you know, under the hood than you do essentially.
>> CLAUDINA: Great. Thank you so much for talk.
[ Applause ]
View Slides

Miriam Suzanne

Sass Map Magic

>> MIRIAM: We're going to do some noise experiments. Yeah. John Cage shit. We're going to do that. All right. Do I have this working? I do. Oh, yeah, so this is my book with Hugo. And I guess you can Tweet hey Henri Helvetica. Or Tweet it, Hugo. I think that's funnier than Tweeting to me. But you can CC me if you want. I have a copy of the book. I'll give you a copy of the book.
So I was doing my debate prep last night and I thought this was a pretty great idea. So I'll just I don't know stand. I was trying to figure out our declaration of independence. So this is the how of Web design on a blue screen. Maybe that's my background. All right. So, yeah, Sass maps. I've got the best Sass maps. No one has Sass maps like mine. Mine are great.
[ Laughter ]
So now I'm going to dodge the question and talk about design systems. I didn't build this. But it's a great design system. Design systems are really popular right now. So this is the lightning design system from sales force. And MailChimp has their grids and Lonely Planet has their colors. And there's these numbers five through eight here. Those come from the New York Tran sis Authority. Graphic standards manual which Gina gave me. That was published in 1970. So these aren't a new thing. The style guides, pattern libraries. The great part of that one is it comes with this. Which is how do you build the sign that the numbers five through eight are going to appear on?
And I love that page. Because my question is, okay, I see your pattern, how am I supposed to build it? Because consistent designs have to have consistent code behind them. You're not going to get consistent output out consistent input. So that's what I'm going to talk about. There's various ways to build things. You can get creative. Sarah Drasner talked about that. So there she is. And the context matters. If you're consulting, need different tools. Are you InstaFace? A lot of the systems that come out that are popular come from these huge companies and we're not all huge companies. We don't all need these solutions. Keep that in mind when you're pulling in tools. Is it 1970? If it's 1970, there are different solutions. This was not 1974, this was sometime in the 80s, 90s. I also have one. That's my team before I started. I said that's '94. I think we're doing a card sort there.
This is the team now. OddBird. We're doing consulting, moving quickly from project to project. That means we need tools that will move and adapt with us. It's different from what Twitter or Facebook needs. Because our product is the good architecture. We're working very quickly to develop a starting point for a client and then hand it off to their internal team. So what we're developing for them is less the product and more the architecture that they will work with.
So we need Web patterns. And Web patterns start with code. And this is a great system if you just put the math in your Sass. And this is what we were doing back in the day. This is based on Natalie Bounds fluid systems. And that's ugly. And meaningless. So patterns are there to add meaning. And that's what we're going to be looking at today. Is how do we add meaning to our code? And how can Sass maps help us do that? Sarah Drasner said something like code is communication. So that's good. And in case we're confused, CSS is already for pattern making. That's the reason it was invented. We have a problem where we didn't have patterns in our code, so we invented CSS. What using classes were for. Somebody else said the cascade is your friend. That's an anonymous quote. I won't out them here. But we're going to look at how to use Sass to do this.
Because Sass is specifically to help add more meaning to our CSS code, like you saw with the grid system. So we're going to try to create meaningful abstractions. So the first thing we'll look at is theme configuration. This is one thing I use Sass maps for quite a bit. I need this. I need a brand color palette. How am I going to represent that in my code?
I wish I could use these variables. That's not what I'm going to do. But here's the sort of the old system. Individual variables for each color. And maybe some naming system to say that they're all colors. These are brand colors. And then individual ones. Right? So that's a fine system. And I can access those pretty easily. I can just call the variable. But maps can help us make that a little more meaningful.
Here I've got a map that's got various colors in it. And each one defined. So maps are just a variable type in Sass. Like having numbers or strings or lists. You can have a map. And it works in a similar way. And inside of it, it can also have those different types. It may look familiar. It's very similar to a JavaScript object or a Python object or any other language. These are known things. We worked with them before.
And it looks a lot like CSS. If any of you remember CSS. We used to use it back in the '90s.
[ Laughter ]
You have a selector. And then your properties and the values. And it's very much like that. The selector is replaced by a variable name. And then we have parentheses instead of curly braces. Key value, similar to property value. But limited.
So you can do anything you want inside of a map. They can get a little bit crazy. And I dare you. This is a terrible idea. There is no reason to do most of this. I love this one. You can use math as the key. And you can actually call that yeah. You can call that here map get OMG stop, 8. Eight is the result of that math. It works. You can use emoji, you can use anything you want in there.
To get something out of a map like you saw, you use the map get function. So this is a little bit less direct than a variable. So this is one of the down sides of maps. Is to get anything out of the map we have to both call the map and the key. So it's a little bit less direct. But map get color is brand blue does get us the color. And there's ways to add extra sugar around that which I'll show you. So you can also merge maps together. So let's say we have a map of our cools and a map of our warms. Map merge, cools warms. That will push them together. And we get this. One map with both of those keys.
So what happens, then? That's a good way to add a key and value pair to your map is to merge two maps together. There is no other way to do it. That's how you do it. If they have the same key, so here we've got brand colors blue and pink. And over there, theme color's pink. It's a black pink. It's sort of a blackish pink.
[ Laughter ]
But if you merge them, what do you think you're going get out of that? Depends which order you merge them in. So the second map that you put in map merge, that's the one that takes precedence and we'll end up with our blue and our black pink. So the pink is overridden in that case.
So one of the interesting things the reason maps exist is because everybody asked for dynamic variable names. Being able to automatically generate a variable. And Chris and Natalie said no. And instead they added maps. So maps exists for this ability to automatically create a name and give it a value.
So here we're just doing a loop. Each name color in colors. So that's going to take each value. And we're going to create a new key request a new value to add to that map. To in the end we have after running it through that we have now a compliment for each color in or map. So you can automatically generate from one set of names you can generate more and keep adding to your map. Which can be useful. Here's the problem.
If I want to reference one color and base it on another color. So here I've got a gray that's a desaturated version of the brand blue. But the problem is I'm going get an error there. That variable hasn't been defined yet when I'm trying to call it. So that's a problem. If I'm trying to represent my colors in a map. What am I going to do about that? So I have my work around. You can decide whether it works for you. I wanted to be able to do the first part of it is self reference. So here I've got a brand pink. Which is pink again. So that's good. And then Escher, researching that, and Bach, and good old Kevin Bacon. At the end I want Kevin Bacon to give me the pink. So I made a self reference. I made a color function that looks up and grabs the color if it's there. And then it checks again to see if that color is still a key in the map. If it is it goes and calls itself. I have this self referential function that keeps looking at the map until it gets to the end.
So that's a good start. The other problem, then, was making changes to it. So I wanted to de saturate it by 80%. So what I do is I define that in the map in just my own syntax and then my color function knows how to make that change. So that's my solution right now to using maps that can do self reference and can make adjustments to themselves is that you define it now like this and you calculate it later in a function. And that works pretty well for me. I get my Kevin Bacon color. Right there.
So I feel pretty good about that hack.
[ Laughter ]
But a lot of people tell me that it's over engineered. So I feel a little worse about it. But the thing it, you got to know the tradeoffs. With every solution, with every hack there's tradeoffs and there's reasons to use it and reasons not to use it. So one of the reasons that I like this is because it makes my code readable by both humans and machines. People can look at that. All of my colors are in one place. They're inside of one single variable and the computer understands it. I can have my computer loop through that map and give me back all of my colors and do things with them. And that's useful. I can access them dynamically like this. In a way that I can't with with variables. I can't dynamically call a variable. But I can dynamically call a map key.
So I can write mix ins that access it. I can also export it to JSON which is super useful. We use this all the time for generating our style guides. So because it's in a map we can just pass that map to JSON. Pass that into our doc theme that understands it and we have a style guide generated automatically based on the same code that's giving us our colors.
Other people like to use modular scales. I've played with them some. If you believe in magic you can use the golden ratio and make adjustments up and down the scale. We have heard about this. But here's a map of named ratios. We've got an octave and a major seventh. People like using these musical ratios. And then a map of sizes. And, again, we have self reference and adjustments. So I want to take the root and take it a fifth up.
And so I have a size function that does that. So it can grab gutter. Gutter knows to look at rhythm, takes root and bumps it up a fifth. I also use maps for typography. I put all the information about a font in a map and there I have a nested map. I've got a map. The key is body, and the value is another map. So I do that with each of my fonts. And that has all of data that I need for my font. And at the end of that I can automatically import all my Web fonts because they're all listed in one place. And I can call the body and it knows to grab the name and the stack. And it knows what variations are available.
And then having both sizes and typography in maps I can, again, export them and access them directly from my style guide generator. So there I get as soon as I have the map set up I have automatically my font specimens.
So is it overengineered? I don't know.
[ Laughter ]
You've probably heard this a few times today and yesterday. It depends. It depends on what you're doing. So here's another thing. I have a project called true. It's unit tests for Sass. So it gives you an output of successful tests. And true uses maps for data storage. Which is not something that you ever are going to need in designing your Website most likely. But Sass is a complete language. So we can write all sorts of programs.
So in this this is what tests look like. We've got a test module and a test name and various assertions. And it's all written in Sass and it all runs in Sass. But this is the database for it. We've got a variable that has the number of runs, the number that have passed and the number that have failed.
And we start them all at zero. And then we just increment them. Every time we finish a test we run this true update. And it runs through that map and updates it by one. Again, we have the dynamic key call there. So we can say whatever result we got, update that one by one. And then I wrote a mapping function that goes through each key and each value and increments by one. So then the true output can be this. We have our database and we just call the various parts of our database and return them.
So that's using Sass maps for our database which you won't need.
[ Laughter ]
We did some more things that you won't need in Susy. And again, because we're developing tool kits, it's different than what you need day to day building a Website. I think it's fun.
When Sass maps came out we were in the middle of building, and I rewrote it from scratch because maps changed everything we can do. Stick around if this talk about how you don't need grid systems. She's right. And you probably don't need Susy. But it's there and does some cool things with maps. So I'll show it to you.
The first thing is configuration. That's a really small footprint. We have one variable that's public that you can use called Susy. And all of your Susy configuration goes inside that one variable because it's a map. And then we have another map that's the Susy defaults. So that's where we give our factory settings. And then you can also pass the inline override. So every function in Susy takes a map argument. So everything can happen on the fly if you want to. So then to find the current settings we just have a function that takes any list of maps and merges them together in a row. So we start with the factory defaults, merge in the user defaults and merge in any overrides and we can do that as far as we need to. And it gives us back one map that is all of the settings adjusted however they need to be.
So you can actually, then, in Susy have multiple maps that are different configurations for Susy and you can keep them all around and pass them in on the fly. So you can say in this case we'll use the defaults here for the first one. But then inside of this media query we'll pass in the completely different configuration. And inside of this larger media query we'll pass in another configuration. And you can create arbitrary, complete configurations inside of maps however you want. And then pass them into the system and it understands them.
So I found that pretty useful. I thought that's a great way to do a lot of user control. A lot of configuration on the fly.
We also decided to do language parsing. And part of the reason for this is Susy is a grid system. Susy doesn't have an opinion about what kind of grid system you use. Doesn't care if you're using floats or Flexbox or tables or it doesn't matter. Susy is just there to do the math and doesn't care about the system. So there's lots of different configurations that you could want. And we didn't want you to have to do a list of arguments where if we add one argument for asymmetrical grids that's going to get in the way of you when you're not going asymmetrical grids, that's a pain. That's not a great UX.
So instead we created a short hand syntax that looks more like CSS short hand values where we created keywords for things. So instead of three comma golf, come a ma container spread wide, you can say first three of 12 wide. And we did that using maps. So here's the first attempt.
We have an options variable. And we have each setting that we want location and spread that we want keywords for and we listed out the keywords. And I forgot a comma there. You're going to want that comma there. So here we have these three keywords are going to attach to this. That's not very performant. It looks great. But it actually performs a lot better when we switch to this, which is list out each keyword as a key in the map. And then say what setting it should attach to. And that's a little bit more redundant as code. But it performs much better because we don't have to do two loops. We do a single loop to access it. And that looks roughly like this. This is a super simplified Parse function that takes in a list and it pulls it apart. And for each item in the list it checks that map and if the keyword is in that map it replaces it or it assigns it to that setting. And in the end we get something like this. So here's our options. If we parse first wider it will return this map that says we've got location is first and spread is wider.
So, again, we started with a map, passed in a list. We got back a map. And this is how we do everything in Susy. It's all maps getting passed around. They're great for storing data like this. So we take this map oh, if you're wondering what spread is. I have it here. Spread is the fact that when I say span three you don't know whether to include that gutter or in gutter. So we have narrow, wide, and wider as options.
So the next step that we need to do is normalize it. Because spread is actually how many gutters do we have in relation to our span or in relation to our columns. So we want narrow to mean minus one. We want wide to mean zero and we want wider to mean one. So, again, we've already parsed out that the spread is wider. Now we to want know what does wider mean? We use a map to grab that and return it. I guess I've got some overflow issues here. Sorry about that.
So in the end we can Parse it, merge it, and normalize it. And we get back we have passed in last three of six wide by 140 pixels and it Parses and normalizes all of that and returns a con fig map that the Susy internals can understand. All of the things, even not passed in, edged down to the factory default. And now we know everything we need to know about the grid based on this short hand that you passed in. Yeah. So then we take that map and we want to convert it into a map that represents CSS. Chris Epstein hates when I do this. And he has good reasons for that. But I do it anyway. He doesn't always get what he wants.
And the usefulness is that I can pass around this pseudo CSS and make changes to it. And I'll show you why. But here it is. We've got a get gutters function that returns a map of the gutters we're going to want. Based on whether it's split or not split. So if it's split we get a margin left and a margin right that are both half the gutter. And otherwise we just get whatever position was set either left or right. And we just return that.
So the results are if we wanted split we get margin one rem and margin right one rem. And if not, if we asked for margin left we get it all on the margin left. And then I can just render that.
And rendering is a pretty simple loop. I asked for the key and the value. And I output the key as a property and the value as a CSS value. And suddenly I've just dumped my map directly into CSS. And there's more complex versions of this. You can have a rendering function that would then do nested rendering. And you can do great complex Sass rending that way.
So that's what it looks like. The reason that we use it is for something like this.
We have multi directional site support. So we want to be able to pass in from the user is this left to right or right to left? And Susy otherwise just talks about before and after. So for the rest of the calculation Susy is just thinking before and after. And then once we get to rendering we look at replace. We say, okay, if the direction is right to left, before is on the right. And after is on the left. Otherwise before is on the left and after is on the right. So we can right at the rendering stage switch those out.
So that's useful. Now we can just say we want gutters right to left and we have margin right 2M.
So why does Chris care that I do that and I shouldn't do that? It's because in Sass they have a very strong belief that CSS should look like CSS. And that's useful.
I think they're right in most cases. It's you want users to be able to come into your code and code is communication. You're communicating to the people that are looking at this later. And when they see CSS is should be CSS. And when they see Sass it should be Sass. And there's a reason those two have very distinct syntaxes. And this breaks that rule. So keep an eye out for the content function. They're working on a way to actually manipulate CSS directly in Sass. Then we won't need to do this.
Another thing you can do is store your break points in a map. And this is the way this I came down it. Initially I was doing very complex break points. Stored here. And I decided complexity should be moved out of the map and instead I'm just going to document the most basic data, which is where is the split? And then I can put together more complex media query strings out of that data. But basically I have a break function that's like the other functions I showed you. Recursive. So that I can reference different numbers in that map.
And then these prepositional mix ins that just give me the shortcut to below, above, and between for min, max, and both. And then I can call named queries using those. So it's just a really simple way to keep online media queries in one place and access them by name.
So there's a lot of other things you can do with maps. You can remove pairs. Map remove is really helpful. When you need to do that. I actually don't need to do that a lot. But there it is. You can fire me from the conference. Just map remove CSS speaker and I'm not there anymore.
You can also do some introspection. There's map has key, map keys, map values. So you can return a list of all the keys and values. You can check to see if a key exists. Those are all handy. All of the list functions in Sass work for Sass maps. They just treat the map as a list of pairs.
And you can find out more from Hugo and Una and other places online. There's a lot of other good ideas for using maps.
So that's it.
[ Applause ]
>> CLAUDINA: Map, map, map, map. Come. No more experiments, so we decided to go about it this way. Fascinating. Mind blown. Map blown. Question, do maps add to compile time?
>> MIRIAM: Not that I've noticed. Nested maps are hard to access. Nested maps does add to compile time quite a bit. A normal map function call shouldn't.
>> CLAUDINA: Can you talk a little bit or share your philosophy around the tools, especially accoutrement? We were working on these together and I was very interested in that. That would be cool for folks to know.
>> MIRIAM: Yeah, my philosophy is you should over engineer things. That's how I start. I think it's great. You take something that you're doing repeatedly in your code, or something that you think can be like turned into a component. And you turn it into a component. And then when you try to reuse it you'll find all the places that you overdid it. That you got too specific. And in the end you can slowly weed out. The more often you use a component like that or a tool, every time you come back to, you can find where did I get too opinionated. And in the end a lot of my tools end up very functions only. As few mix ins as possible. Because mix ins are where the opinions happen. Where you're generating CSS code. Most of the tools I want to take from project to project and have the actual output be different, but have the logic blind it be the same. So I get lots of functions that figure things out and I can use them however I need to. Adding the CSS later.
>> CLAUDINA: Mix ins are where the opinions happen. That's a great quote. And a wonderful soundbite to close out this first half of the conference. Thank you, Miriam for your talk.
View Slides

Zach Green

Webpack and CSS

>> ZACH: Can ya'll hear me? Hello, hello. How about now? Okay. So I'll just stand right over it like this. Yeah, sort of covered it. Zach Green, my Twitter handle, Z green underscore. On GitHub @zgreen. I'm a senior UX Devs at Alley Interactive. We work with large companies and we're a remote team. And we use Webpack for all kinds of things. And Webpack it a really powerful tool. You can do a lot with it. And today I'm going to try and hone in as best I can on how we use CSS and Webpack together.
So we're going to talk about a few things. One thing we're going to talk about is obviously the build process. If you don't know, Webpack is sort of a build tool. You can use it to compile and transpile and do all kinds of crazy stuff to your files. We're also going to talk a little bit about community and ecosystem. When I say community I'm sort of talking about, like, I feel like there are some technologies that reach kind of a critical mass of adoption and also have a really good sort of lucky timing. And they become really useful because of those things. And Webpack is one of those tools. It sort of rose as React was rising and now it's like developed into this there's a really, really large ecosystem of plugins and loaders and docs and tutorials for kind of covering all manner of use cases.
Which is very cool. We're also going to talk about Webpack kind of as a gateway to other frontend technologies. This isn't really a talk just about Webpack. It's sort of about the modern frontend stack in the context of Webpack. And I was trying to think of an apt metaphor and I couldn't. But I sort of thought of like if frontend weapon development is one of those shitty carnival fun house rides you go on, Webpack is the car you're stuck in that takes you through it. It sort of works because Frontend feels like it was built by carnies and gets shut down every six weeks.
[ Laughter ]
Whatever. And we're going to talk about performance and some ways that Webpack may be able to help you solve some common performance problems. And we're going to talk about workflow. I'm actually sort of glad the timing of this presentation worked out well because a few folks have touched on this and a few other aspects of my presentation but they didn't go too far in the direction that I'm going to go. So I'm hoping this will be a good compliment. Sarah Drasner touched on this yesterday. This idea of flow, right?
Where flow is kind of that feeling that you're just in the zone. You're enjoying what you're doing and you're having fun while you're coding. Right? There's a really good talk by Bruce Hauman, a very talented closure script developer called literate interactive coding with Dev cards. I stole a lot of the ideas for this presentation from this talk. You don't need to know closure have script at all to dig what he's doing. But I highly recommend that talk and his work in general.
One big takeaway that I got from it is that he argues that the primary mode of UI development is endless tweaking. And it's the idea that most of the time if you're building and maintaining UI you're just tweaking tiny little values and checking your work and tweaking another value and checking your work. And you do this forever. Right? That's it. That's your job. Like you just tweak things forever and ever and ever. And I feel like this maybe is no more true than in CSS, right? Where you're kind of constantly updating and changing values and checking how they look.
So we're going to talk a little bit about how Webpack can kind of grease the gears of this workflow a little bit and maybe make it better for you.
This is from the Webpack docs. What is Webpack? Webpack takes modules with dependencies and generates stack assets on those modules. Like one of the first things on the Website. I don't know about everyone else here, I kind of find this description to be opaque and hard to understand. I have been preparing for this presentation for a few days, I'm still not 100% sure what this is saying. This is a criticism leveled at Webpack, it's hard to doc, it's dense and hard to understand. There's some truth to that. Documentation is super hard, just like everything else. And the Webpack team is looking for help with updating their docs. So definitely check that out.
But I thought maybe instead of trying to parse this statement we could do a little walk through of Webpack and see if we can understand it a little bit better.
So basically Webpack can be used as a CLI. And it looks for this file. This Webpack.config.js. You read from the command line. The config. It might be really long or kind of short. A lot of stuff goes on in there. Not going to look at all of it. It would take all day.
But we're going to look at a couple things specifically. Mostly we're going to be down here in the objects that's getting exported, right? The entry point, here, is like what's getting bundled. In this case just a single file, app.js. And then more specifically we're going to look at the plugins array that gets passed and also this loaders array that gets passed to the module object in the Webpack config. Don't worry if this doesn't make sense yet. We're going walk through it.
So a quick crash course in plugins and loaders in Webpack. Loaders basically pre process files. That's kind of the idea. They use the require or import statement to work. They're very similar to tasks in other build tools. So if you're coming from Grunt or Gulp or who knows. There's all kinds of cool stuff out there. These are loaders are kind of like tasks, right? And I sort of always think about them as, you know, it's code that ingests files that you give it and just applies a series of transformations.
So here we are this is kind of stretched. Can you see this? Yeah? Cool. I don't want to stand in the way. This is the just an example of require an import statement, right? There's nothing going on here. This is native JavaScript. Webpack isn't doing anything in this case.
But what Webpack does is it kind of hijacks or rides along on top of the import. So if I wanted to apply, for example, a Babel loader to a JS file I would do it with this kind of syntax here. Babel, bang, and then the file. Babel might do all kinds of crazy stuff in my JavaScript if I wanted it to. So that's how that would work. The cool thing about this approach is that now you can import file types other than JavaScript. You can ingest in JavaScript syntax file types like CSS or HTML or markdown. Really there are loaders for almost anything. And then Webpack can be made to understand them. So in this case everyone can totally see this? I can't see it at all. Is that yeah. Yeah. Share my screen there.
Is that better? Cool. Right on. Yeah. So we're doing a couple things here on these CSS files. We're just applying two loaders. The CSS loader and the style loader. You see them change here and they're separated by bang. You can also pass query parameters to your loaders using this syntax here. So in this case we're passing the minimize parameter to the CSS loader to make it minimized from the CSS that I'm feeding it. This gets a little hairy if we do this everywhere over our code base. You can imagine if you had to keep track of all the loaders you're using on the files you're importing and some use different loaders, that's kind of no fun.
So most of the time you're going to set this up in I don't know why it's doing that. Let me do a reload here. See if that works. Anyway, most of the time you're going to set this up in your Webpack.config.js. This is a slow load. Reloading bundle. I'm probably not on the right thing. I'm not. Cool. Internet woes. Sorry.
Cool. Do, do, do, do, do. So I will there we go. Well okay. That kind of stinks that it's doing that. I don't know why it's so cut off. Can you see? Cool. So here we are in Webpack.config.js. And we're doing are egx test for a file type, down here. And we're running a pair of loaders, CSS and style loader. That way we don't have to pass that to every import that we run. You can tweak these and apply loaders on demand to you can disable the default by using a double bang at the start and applying the ones that you want, like this. So if I just wanted to use CSS and style here, I could do that. If I wanted to enable some other features, here, I could do that.
I'm not going to talk a ton about plugins. Plugins basically ingest custom build script, custom build steps into your build. And we're going to look at one plugin specifically that makes that work. And that is the extract text Webpack plugin. If you've ever used Webpack and you've used it to compile CSS to a style sheet, you've probably used this plugin before.
Use it basically like this where you're just requiring it here at the top and now we're going to pass it into the plugins array that we discussed earlier. And then down here in our loader we're going to call extract on extracts test plugin and run the loaders that we want. What this is going to do, it's going to extract to CSS that's getting compiled into a style sheet, main.CSS that we can then use.
Just a quick difference. Webpack 1 syntax and Webpack 2. Webpack 2 is full release or beta. It's been a while since I checked. But keep an eye out for that. And here's how that works. Here we are in app.CSS. This is the gradient that's being applied. Burlywood and cornsilk. We import it here in app.js. Import the file. And then it compiles and reload it here. We link to it in the head. And we can change that if we want. So if I want to go in here and maybe update that to, like, a value a value that's a little bit brighter I can save it. We can go back over here. It will update for us.
And then we're going to reload. And then we're going to wait. And wait. And wait. Just made a CSS change. Okay. It's back. Cool.
So that's how that works. It's pretty easy to switch on SCSS too. You can use the Sass loaders to do that. You see down here, passing Sass loader into our loader chain. And here we are in app.CSS. The other change is we're updating our regx config. So it's both CSS and SCSS files. And if we go into that file, extract at CSS, and we save a new gradient, that'll get updated and then we'll reload. And we'll wait. And wait. Made a CSS change. Just waiting for it to load. Cool. A little brighter. Nice.
It's pretty easy to do. You just need Sass loader and Node Sass. Those are the two requirements for this.
Let’s look at the next thing in the loader chain, CSS loader. CSS loader does things that you expect it to do, like minification and source maps. And some things you wouldn't expect like enabling CSS modules. The minification piece is powered by CSS nano. It's a powerful tool. It's got great CLI, PostCSS plugin. All that kind of stuff. So an example. Here we have a CSS file. There's six, five selectors. Z indexes getting set. Setting up a counter. Pretty simple. And when we run CSS loader with minification, it's going to come out like this. This is what Webpack deems safe. It minifies everything. And it's changed the counter to just a single character. That doesn't matter. Right? So it shortens fewer bytes that way. This is a safe transformation. We're not going to break anything doing this.
You can enable unsafe transformations in CSS nano by passing additional query parameters to CSS loader. In this case, minimize and the Z index reducer to the CSS loader. And that's going to actually run a reduce on our Z indexes. So a thousand becomes one. 2,000 becomes two and 1500 no, 2,000 becomes three. And I'm doing that wrong. But you get the idea. Sub, sub, middle, middle. Does that make sense? Sort of? Cool.
So that might be all that you need if you want to start using Webpack to compile some CSS. This is how I started using it. If you just want to try it out and get it to write some CSS files for you and see how it feels, you can do that. Just with extract exploit. There's a but here, though. And the but is what we're doing is sort of moving against the grain of like what Webpack is meant to do and how it's supposed to work.
Extract text plugin is kind of a bummer. It's a useful bummer. It's writing CSS files for us. But Webpack really understands styles as data and wants to manipulate them and handle them that way.
You might have noticed that there's one, like, real problem here, which is that every time we make a CSS change we have to reload our page and it's really slow. It takes forever. It's taking a particularly long time because I'm actually throttling the request for demo purposes. But this is an interruption to your flow, right? To change one line of CSS and then wait for a reload is kind of a drag. You can automate this a little bit using a live reload plugin. I'm showing you an example here. So that when you save a CSS change it will automatically reload your browser.
But even then you have to download everything again. You might have a bunch of app code that runs. You might be on the local server that's got a bunch of other stuff coming into it. And like to iterate on a user interface with this kind of a flow is pretty is pretty bad. It's not fun. And it really it really breaks up your flow as you're trying to work.
There's another problem too, is that we're render blocking. We have this style sheet in the head and we have to wait for it to download before we can see the page. So that's not cool.
Webpack can fix this. And we fix it actually by just taking things away. We just stop using extract text plugin all together and we just use style loader. So let's take a look at how that works. If I go into my file and I update a value and I save it. You'll see it just update. Right? Now, this bundle is a little large so the update will take some time depending on how big or small your bundle is. But we've, like, eliminated the reload just by no longer using extract text. Right?
And this is a small example. But once you start using it to write all of your CSS you'll find it, like, so much nicer. And all of these kind of road blocks go away. You stay in the zone a lot better. And it's actually just more fun to write it this way I think.
This is what the Webpack config looks like inside case. Pretty simple, right? And this is how it works. It's a two step process, basically. We are loading a JavaScript asynchronously at the bottom of the page. When it loads it injects in style texts the styles that you want. Just like that. Which is pretty cool.
This is a quote from Jed Schmidt, who is a talented JavaScript developer. He said the worst things about CSS are cascading and sheets. I'm not arguing in favor or against that statement. I wanted to put it up here to give context to what we're looking at.
But what we've done here, obviously, is we've removed the sheet, right? There's no sheet anymore. Putting in style text. So we've solved a couple problems. We're not render blocking anymore, which is really nice. You probably want to pair this with a critical CSS solution to you can get some styling at the top of your page. We're hot reloading, which is really nice. And I want to emphasize, like, you don't just use for CSS, use it for everything. JavaScript, HTML, you can hot reload all your code if you want to.
And the other thing that's really cool about this, you don't need a framework to make this work. You don't need to be writing React or Angular, don't need to be in a single page application. You can just use this on a plain HTML page. Or All IE, where I work, this is a solution we often use for loading styles. I think when a lot of people think about Webpack, it's in the context of React and single page applications. It's powerful enough and flexible enough to let you work outside of those environments.
We're also kind of keeping it simple now, which is cool. We've removed the extract text plugin from our config. We've removed our style sheet. Everything is still working. And our flow has improved. At the same time you're kind of like deleting things and everything still works and you're actually working faster. Those are like kind of good code smells, right? This feels good.
In that vein we should talk a little bit about PostCSS. Which I think can kind of help you move in the same kind of direction. PostCSS you enable with a loader just like other things in Webpack. Turn it on here. See? We're just chaining it in the loader here. PostCSS then CSS, then style loader. And now in addition we're going to pass a method into the exported object here, PostCSS, which returns an array of the plugins that we want to use to transform our styles. And what I've pasted here is kind of like a boilerplate set of plugins that I often find myself using when I'm writing PostCSS. When I'm writing CSS and using PostCSS to transform it. So let's take a quick look at how that might work.
If we're here in app.CSS, this is not an SCSS file, just a CSS file. But we can import other CSS like in Sass. We can set custom properties. These are not real custom properties. These are just variables in the context of PostCSS. They don't work like C property will. We can use basic math too down here. And here's what the transformation looks like. Again, this is going to get inlined in the document head, the style tag. Here's the styles or the CSS file that we imported. You'll see everything got nested properly.
Our custom property got transformed into a static value. Our math was performed. That's kind of a cool thing. It's like a calc reduction here. It's just dividing 10 by 16 to get an end value. And we're also getting some other prefix or action going on there.
It's kind of cool. This was kind of like a little ah ha moment for me when I hit it. Oh, this is kind of like Sass, but I'm not using Sass anymore. That's neat. You can use them together if you want to. And a lot of people do. If anyone uses Sass and uses autoprefixer, you're already doing that, because autoprefixer is a PostCSS you can chain the loaders in Webpack if you want to. You might not need to, though, which is cool. There's a few reasons. PostCSS can be faster than Sass. Your mileage will totally vary. It depends on the size of the string that you're transforming and the nature of the transformations that you're making. But you may find it to be significantly faster when you build. I certainly have.
Another thing that's cool about PostCSS is that the same transformations as Sass are possible along with many, many more. Because PostCSS has a plugin based architecture. You can write in transformation that you want. It raises the question, if you're already using PostCSS for something like autoprefixer, why not go the extra mile and simplify your build by removing Sass altogether? And then the last point is something I've thought more about recently in the last year is that, like, this idea that maybe a tool like Sass was giving me more than I need.
I don't like to use, for example, like mix ins or extends in my code. Miriam talked about how they come from mix ins. I think that's totally true. Writing Sass and coming up with custom short hands for things that had mix ins which was a bummer. I wrote a lot of that code. I learned from my mistakes. With PostCSS you can define the transformations possible in your code through Webpack. So if I only want to use a certain amount of transformations, I can explicitly define those. And any other Dev that jumps into my project bumps into those same directions. This is the idea that some restrictions, especially with a large team and a large project, a restriction can be a helpful opinion and can help keep your code base behaving in an expected way.
So let's take a look at some fun stuff too. CSS modules. A few people touched on this. I just wanted to take a quick look at it. CSS modules comes along with CSS loader. You enable it as a query param right here. And it kind of works like this. In our app.CSS we have a selector. You can import that in your JS file. And this is ES2015 template literal where I'm just adding class here. And then when you compile it, it's going to turn your class name, my class, into this crazy hashed class. Which is just as gobbledygook of characters. Right? And then you would get the same thing in your template.
That might look super weird. But it's actually kind of awesome. Because what's happened here is we've locally scoped our selector. This is guaranteed to be unique. And we are not going to have any naming collisions. We don't have to rely on a naming convention to guarantee that our selectors are unique. We're moving our CSS out of the global scope entirely.
That example wasn't super readable. Which was kind of a bummer. But you can enable that with a separate query param like this. I'm not going to go into what all of those keywords are. But this comes from the Webpack docs. And then instead of that long hash string that's really, really hard to read, you're going to get a selector that still is readable and has the context that you gave it, but is also still guaranteed to be unique and localized.
So now when you kind of, you know, inspect your styles you'll still be able to see where I'm coming from. I'm fairly certain there's a way to enable source maps with this too. I find often source maps are more trouble than they're worth because they slow down the build. That's a personal preference. That's really cool. Local scoping in CSS is nice. Yeah, it's changed the way I started thinking about CSS. I'm bringing us back to the Jed Schmidt quote where he talks about not liking the cascade. CSS modules eliminates the cascade. You don't use the CSS selectors, and all of the class names are unique, the cascade doesn't matter anymore. I know people have different opinions on whether that's a good thing or not. I kind of think on large projects the cascade behaves like a bug.
So far I've only showed you examples in JavaScript, which is cool. But like maybe doesn't have a ton of real world application. So we should look at PostCSS modules too enabled in Webpack. And this is going to let us use CSS modules on the server, which is also really cool. So instead of passing the modules query param to the CSS loader here in our Webpack config, we're going to enable this PostCSS modules plugin and pass the scoped name down here. And that's going to do all of the same things that CSS modules did in the last example. But in addition it's going to output a JSON file where the keys and values are the key names that you defined, and the hashed class names from CSS modules. And you can see in the super contrived example I threw together. Imagine you're in a P HP and wanted to read the JSON and output the hashed class in the template file, you could do. That's just PHP, but if you're writing in another language other than JavaScript that can understand JSON, you can use CSS module server side. I haven't used this in the production environment, but I think it's cool. The server side piece. So we're sort of experimenting here. And one more thing, post HTML. PostHTML is a new technology. It's similar to PostCSS, the idea is you take an HTML or an HTML like file and you apply a set of transformations on to that file through plugins.
So in this case we're using the PostCSS loader here in Webpack along with some other loaders. And down here we're using this postHTML CSS modules plugin and passing in that JSON file you saw here. That means we can do cool stuff like this. Where in our input HTML we can define a CSS module here and we can perform a transformation on it and get the hash class name on the output HTML. Kind of cool.
Yeah. So that's sort of the spiel of Webpack and CSS. And like Deving on the frontend with Webpack. If anyone has any questions, please come and get me afterward or up here. And thank you. Appreciate it.
[ Applause ]
>> CLAUDINA: Inside the Dev studio.
>> ZACH: Thank you.
>> CLAUDINA: Yeah. Two Mics. Doesn't work yet. Keep this thing up. Sweet. A couple questions for you. Are you using Webpack with HB2?
>> ZACH: I tried to do it on a project recently. And actually got bit by another problem altogether which is that the project that we were building for wasn't wasn't going to be running HTTPS. And you can't use HTTP2 without HTTPS. I still have yet to actually hit a large client project that I can use HTTP2 on. I'm waiting for it to happen. I'm sure it will. But I still feel like the technology hasn't caught up with it. Especially if you're working with clients that serve as a lot of ad code is not secure and doesn't even let you run HTTPS. So it won't even be possible.
There's been some really cool things written by con academy about HTTP2 and Webpack. So check out what they've written.
>> CLAUDINA: Are you doing any type of bundling in your JS, splitting it out and making use of Webpack's features that let you create smaller bundles.
>> ZACH: That's one of the coolest things. I was going to talk about it, but it would take too long. It's huge. You can break up your JavaScript bundle so you have one common bundle that's getting load the everywhere and based on routing or other sort of conditionals you can load asynchronous bundles on the fly and help the performance and cut down on the build time.
>> CLAUDINA: It's great for performance. Getting over the bundle and everything. How you get over deciding how to split your bundles?
>> ZACH: Yeah. It depends. You can kind of manually do it if you want to play around, here's a condition where I bundle once and here's a condition where I bundle again. More often than not, the simplest way, split out vendor files. Libraries, split those into a commons chunk or something like that and then load that. That's what we're doing more often than not. If you're really building like a large like SPA you're going to want to do something more involved.
>> CLAUDINA: Are you using this type of budgeting in con junction with any other techniques? Preload where you might load one of your bundles on the home page and start pre for the other ones?
>> ZACH: That's a good question. I'm not. No. I think that's a cool idea. I haven't had a chance to play with that. But I'm super excited about it.
>> CLAUDINA: I am too. I haven't had a chance to play with it. Seeing if you knew. I've been chatting a lot with folks about Webpack. We're using JS, and I want to move us over. But are you using Webpack in conjunction with other build tools?
>> ZACH: When we use it we run the tasks in NPM. So you just set up the command that you want to run in NPM and run it that way. Because you can do a lot of your steps in Webpack, a lot of it ends up getting contained there. So if we're linting we're doing that in the Webpack build. And obviously any transpolation is going to happen in there. Webpack is going to handle it all. We might have custom Web scripts for things. But mostly it's happening in Webpack and writing the tasks with NPM.
>> CLAUDINA: You have gotten rid of gulp or grunt. Were you using those before?
>> ZACH: Totally. Those were great tools. No, I remember the first time I use the grunt. This was so fun and great. And Webpack feels like an evolution of that for me.
>> CLAUDINA: Yeah, the thing I'm slightly reticent about with Webpack is the configuration. And if you're coming from grunt, all right, configuration. Gulp for me was, great, screens. So nice. It's like the one part.
>> ZACH: I agree. The config is the most hated thing about Webpack. And there's some justification for that. But I want to emphasize like it doesn't have to be super complex. There are good boilerplates up there. I have one on my repo, on any GitHub that I use for personal projects. It doesn't have to be a big thing that everyone knows about and manages. It can be a lightweight thing. And the Webpack, the docs, while they are sometimes difficult to Parse are super, super thorough. So do check that out.
>> CLAUDINA: Yeah. I definitely found the docs a little like, whoa, what's going on here. So you had a slide up about community and Webpack. Community is something so valuable around open source tools. I'm big in Sass. Been to meets, a badge of a community and a sign of what we believe in even more than a technology. It is a technology. Can you tell a little bit about the Webpack community?
>> ZACH: Yeah. I don't know I don't want to speak specifically for the repo maintainers and stuff. I'll talk about it in the context that I kind verify encountered it. Which is like as someone who wanted to try out these tools and then started using them and then started using them with client projects. I found that there was, like, just such a wealth of information out there. And that information comes from, like, sort of official sites like the doc site. And also just people posting tutorials and write blog posts how they started using Webpack to do X or Y. And I feel those technologies that can reach people that way and get them to offer those thing up online, open source, that makes a really big difference to someone like me who's just trying to find my way in the dark. Because mostly that's how I learned how to do things. Change this, what works? What breaks? Help me.
>> CLAUDINA: That's the best part about coding. It's not really broken. Like in the moment in time it's a little broken. So do you have any thoughts on how, like, Webpack will revise itself as some more of these tooling cot into the browser. System loader is one for ES6?
>> ZACH: Yeah. Some. There's been some written recently about how, like, Webpack's bundling logic may be kind of making the bundle size larger than it needs to be. So like specifically if you imagine like you're importing like the same the same module like multiple times throughout your code, Webpack may not be optimizing that in the way that it should. Webpack two adds tree shaking. Which is the idea if a bundle gets imported twice it shakes the tree and then drops the reference to one of the modules because it doesn't need to be there. Which should dramatically cut that size.
There's a sort of alternative out there right now called rollup that people are using which looks really, really awesome. And I know there's been some discussion in the Webpack repo about merging roll up into Webpack. They take the performance implications of that seriously.
>> CLAUDINA: We use rollup. Definitely a tool to check out for reducing the size of your bundles. It's kind of crazy. Talking about weight, the size of our repos and bundles and the NPM node modules folder. And in some ways, like at all this stuff now.
>> ZACH: Yeah. It's true. Yeah. If you open your node modules folder you're going to be terrified. And that's kind of a problem, I think. People are starting to think about that a little bit more. But yeah. I don't know. Like I was sort of saying, like the carnival fun house ride. I feel like Webpack, it contains the madness a little bit for me and kind of lets me take advantage of the parts that I like and it's helpful and not have to fight with my tools. Which I don't like to do.
>> CLAUDINA: On that, is the only way to get hot reloading with style loader and if that's the case, does that mean that one has to go this route of basically injecting your styles in the page?
>> ZACH: I think that it's impossible to get hot reloading with extract text plugin. I tried for a while and failed. There's a different loader called extract loader which is slightly simpler. So maybe it's possible with that?
But I don't think that's as good as compiling as the extract text plugin is in so my answer in my experience is, no, there's no way to write a sheet and hot reload that. But there are smarter people out there than I am. So maybe they solved that problem too.
>> CLAUDINA: So does that affect performance in all on the page? Because if JavaScript is loading A sync, you have the complete DOM, document, so it's just inserting it and it's not really
>> ZACH: Yeah, that's exactly right. Loading asynchronously and ling the DOM download, pair with a critical CSS for sure. Otherwise you get totally unstyled content for a while. At least the content is there. You haven't blocked the render with your CSS. Which is still good.
>> CLAUDINA: And how does this work? One of the good things of having the sheet is the sheet is cacheable. Are you also caching your HTML pages or not because of dynamic content?
>> ZACH: That's a valid criticism. The projects I've worked on, the benefits from the style loader loop outweighs that potential problem. But I think it depends.
>> CLAUDINA: It always depends. Right. The like flowchart of making decisions in weapon. Just like, well, there's an option and then there's the it depends option.
>> ZACH: I feel like to a certain ex tent, you have to be allowed to make bad decisions. This is the only way I can learn.
>> CLAUDINA: So what bad decisions have you made with Webpack, oh, my gosh, never going to do that again.
>> ZACH: You can set up the config to do all kinds of crazy things and separate entry points. And the node scripts. It can be a disaster for someone coming in to try to look at it and use it. That's a problem I have bumped into in the last year or so. It's just too complex. So I'm constantly trying to make that better for people and make sure it's simple and easy to reason about when you jump into it.
>> CLAUDINA: Great. All right. Well, thank you so much. Really enjoyed your talk.
[ Applause ]

Emily Hayman

It's Time To Ditch The Grid System

>> EMILY: Sorry, I had technical difficulties earlier. I'm back. I'm Emily. I'm here to talk about ditching the grid system. I'm an engineer. A San Francisco startup. So it was a long flight here. My Twitter's right there. So if you disagree with me, feel free to send me a disparaging Tweet. That would be really awesome. I'm here today to talk about something I'm super, super excited about. I know most of you have probably messed around with it before, but Flexbox. I feel like for a long time now we have been focusing on one certain way of laying out things that's been pretty rigid. And I'm really excited to sort of rethink everything and sort of shift our paradigms and allow us in the end to have a little bit more flexibility with our layout.
Okay. So before I really dive into it I want to talk about where we've been. So back in the dark ages this is what Websites used to look like. Basically tables for were the only method of laying elements. In the row, and inside the row, a cell. And inside the cell you had your under construction GIF and that was your Web page. There, you're done. But then things got a little bit better for us. CSS became a thing. That's why we're all here, which is awesome. As part of that CSS spec there's a thing called floats, right? You have an image, it sees a boat. It's floating. You had an image and you floated it. And then the text floated around it and that was great and meant to emulate print design. But then everybody said, hey, maybe we can use this for layouting. And it worked pretty well, actually. Most of you probably recognize this grid. It's pretty standard. Twelve column, Bootstrap foundation. Sort of the last shot to the grid. You have cells that are in rows and they're all floated and then that row is cleared. And it's actually when you think about it pretty similar to tables. It's definitely a step up, but still very much focused on you're predefining the width of your elements. It's not content focused. It's, again, just width focused. It's responsive, and clients are like, well, it's responsive. It does that well. Overall you have to know a lot about the content that's going to be in there. So if you have a CMS and your CMS user is like I'm going to put a bunch of copy in and use this thing. Why does the page look like this? Because of this. We can do better. And the awesome thing is that Flexbox is going to help us. Other things, CSS grids are awesome. A lot of people talked about. Flexbox is here and it's really going to help us out. How many people have played around with Flexbox thus far? Awesome. Cool. Very exciting. How many people have used it in production? I was worried this next slide was going to be controversial. But that's capacitating.
So global support is at 96.92%. There's that weird yellow 13% color and that represents like IE and like prefixing and weird stuff. But like this is CSS, things can be kind of weird. But that's a pretty big number. That's really exciting. The times now we can start uses in production. Don't be scared. Don't be like what about the I9 users. No, come on. So what's the big deal? What's so exciting about this?
So I actually grabbed this sentence from the specs. So full disclosure. Flexbox is an efficient way to align and distribute space for dynamic items in a container along an axis. That's a lot of words. I want to reiterate this. It's about dynamic items. That's items that have a content based width. And take the whys and align to each other and distribute the space between them. And this is so, so different from that like pre call six, it's like a row. It's so different. But it's awesome because it is that different. And really opens up a lot more possibilities.
So I know a lot of you raised your handle with Flexbox. But I wanted to give a quick overview to maybe some of those who aren't comfortable with. Flexbox is about the container. Have display flex on the container, and the children are going to get a flex context. And one of the great things, you can do a lot of the layouting you needed to just on the container. So you don't need to worry about the children elements. It's about aligning the items and reading the space on the container. A little bit of background. Flexbox, the axis. The main axis, by default, the X, and the cross axis. And you can flip them using X direction. Flip them around and reverse and all those things, reorder things. Which is great. And you can also set the flex route. And as I mentioned, again, it's all about aligning and distributing. We can have the justify contents. And you can have the justify content along the main axis. You can start at the beginning, start at the end. You can do space between. You can do space around. Also, tease are some of the best named properties. It literally puts space around things. That's so straight forward. And you can center things. When you align things, you align them on the cross axis. Again, this is about aligning items with each other. So center items, start at the end. Baseline. But one of the cool things, stretch. The default value is stretch. And what this means, out of the box you're going to get equal height columns. Which is amazing. How long have we been waiting if that? I want to show a quick component. Logo on the left, navigation on the right and they're aligned to each other. And all this takes is three lines of CSS on the container only. So right here, display flex. Justify the content to be space between. So that basically means take the left thing and stick it over here, right thing over here. And align to each other. Which is a different shift from the old way of doing it. The old way, you would have the row that was cleared and the logo and navigation floated and then some sort of weird magical number to add a top margin to it or something like that. And again, in this case you're very focused on the children elements. Whereas with Flexbox you're more focused on the container. And, again, no mention of numbers. So if somebody came in later, insert this huge logo everything would still work. Whereas in the old case the margin would no longer be centered and weird things would happen.
There's also some children properties that can help you do things. So flex sets grow sets the size relative to the siblings. The default is zero. Often you're finding yourself setting this to one. Depend on the use case. And then flex spaces sets the initial main size. This is sort of like a width, but not really. The default value, auto. And that's awesome is what that means is the default width is going to be the content. What does that mean for us? The example, the logo on the left and stuff on the right. We set the space flex, justify the content to have space between it and align the items to each other.
So what about this search field contained over here? I wanted to make it as CMS users added more links that this search of input would continue to grow. And sure if anybody changed the size of the icon or the padding on this that the search and the input would have the same height. And it's easy on Flexbox. And right away out of the box you have that default align item stretch. Which means they're going to be the same height. Then all we need to do is add one line of flex grow one on to this search input and it will continue to grow to fill the remaining space. So, again, pretty straight forward and nothing should look too crazy here. But what about when we move into other component types. So here's this grid that we were talking about before. What if we boil this down to really all we're looking for is equal width comps, right? We don't care about one, one, one, or two, two. We say only container we set something that then says we want all the children to be equal width.
So I this container class display flex and then on the media children we set flex grow one, we want it to be equal. The relative size to each other is going to be one. And then flex spaces to zero. That's saying, hey, go ahead and shrink as much as you need to shrink. I don't care about your content. I had a contrived example to show everybody what that looks like. Obviously didn't put much effort into the design of this. But we have three columns and they're all equal height and width. And we have the cat in here and everything looks good. Depending how you see things.
So what about when we want to add some margins, right? Things are getting a little bit more complicated. Margins on the left and right. And for the first and last child we have reset that margin to zero. It's looking a little bit better. Things are more spaced out. Everything is equal height and equal width.
Okay. What about mobile? Let's make sure when things get down to mobile size they aren't getting squished. Right, in this particular case oh. I don't know how to de squish this. So this case, if you were to shrink it, everything would continue to squish like this, right? But we to want make sure that at a certain point on mobile things stack. That's pretty standard. That's sort of the grid concept of things decrease on width and start stacking. So what we do is we add in a media query. What we're going to do is change the flex direction to column on mobile.
So that means rather than the main axis being the X axis, we're going to change the main axis to be the Y axis. And then resetting to main sure the flex space is reset to auto. So things aren't stacking. And then the additional option. If you would shrink this you would see they start to stack. That's a huge chunk of code. That was lot. Why would I keep writing this? Seems like we're kind of back where we started and things are not looking good. That's a good point. Okay. So let's put things into Sass and see how we can put ourselves back in a place where it's pretty straightforward. Can everybody see this? Is this sort of readable? Maybe? Okay.
So anyway. So we've created a mix in, Flexbox equal column. And in this case I have a 20 pixel parameter. I've created a parameter for the white space, the element name and a parameter for the calm gray point. This is pretty much the same code of what we just wrote, just parameterized. You'll see the padding is now half of what that padding value is. So we no longer have to think about that. Here is the same logic. The break point has been set, we have the media query. And we made it a little bit more flexible and usable for ourselves. So what does this mean?
So we can use other parameters. This is it's not necessarily, oh, just padding or just media query sized. Potentially it's usable to set if you wanted to reverse things, add a column break point padding. Really the sky's the limit.
The key takeaway from this is it's time to start identifying component panels. I want the children to interact in a certain way. And there's a common underlying structural logic between components of different types. Identify the lodger and refactor that into a mix in. And with that mix in, create parameters making it easy to plug and play, again, at the container level. So now the main takeaway here is creating a responsive, equal width, equal height column at the container level is now reduced to a one liner. All we have to do is call the mix in and put the padding we want and put where we want that break point and we're good to go. Don't have to think about, okay, what about this and this? We're just done. The other logic could be reused for additional components.
It is worthy to note, though, that we should find the middle ground here. So each mix in should focus on reoccurring differing use cases. Within a component type. But if you're going to a point where the mix in has 20 parameters and a million nested if loops and what is going on and just becomes a black box, that's probably the sign of a problem. You want to make it to be consistently able to be reused. But not to a point where somebody else who comes into the code base is going to be like, what is this gobbledygook. So in all things, moderation.
So I wanted to walk through a few component types that I've identified and that I've created this set of mix ins for that proved to appear again and again in certain template types. One particular component type that most people should recognize is a fixed width section on the left. And then a section on the right that's meant to take up the remaining space. So as the user resizes the screen the left section, that filter section, is going to maintain its width. Whereas the right is going to shrink. We want there to be enough space for the filters. In the older system, call three, call nine. And then the filter would have shrunk, and maybe get cut off. Wouldn't have been the greatest user experience. We're going to create another mix in. This one I'm calling two column fixed. We have a couple parameters here. One of the parameters is going to be the fixed column, and the other is that fixed column's width. So here's the code for the mix in would look like. So we have the fixed column. If it's left, we're going to set the flex spaces to be the first on the first child. And the right, and the flex spaces to one. The other element is going to take up the remaining space. And flip that logic for the last child. So pretty straightforward.
The cool thing is, though, that once I get to a point where, hey, I recognize this component type, all you have to do is have one liner and you're done. So another one is two columns. One with a content based width. And another one with the other one taking up all the space.
So in this case I'm saying, hey, this image is really important. This always be the size of the image. And the remaining content should fill up in the remaining space. Again, created a mix in, the parameters are the mix in and the padding. This is super similar. There's some overlapping of logic here. But pretty straightforward. So there's also another one of two columns, both percentage based width. That's another I've noticed a lot. And the pattern is arising, creating a mix in. Two column fluid. We're inputting the first column width and them the padding. So what this means is that the first child we're setting that first column width and then on the last child we're doing 100% minus the first column width and setting the margins appropriately.
Another one is a grid. This is a pretty standard three columns. Starts wrapping. And the cool thing about this, if we didn't have that last Alice over there, it would just stop. There like there would be a it wouldn't take up that many spaces just stops. Which is what we want. I've created a Flexbox grid, and we're going to input the number of columns I want. We have at column number and I've added a flag called reverse. Once we input it we can set the flex wrap to wrap reversely. So this is a case where we might have, oh, the markup's one way, but we want to reverse this. Again, this is another example of a parameter you might want to set to make things a little bit easier for you. And the element, set the flex space assignment to be 100% divided by the column number. Okay. So what about you're like, okay, this is great. But seems like we're putting a lot of stuff inside mix ins, maybe don't need to. Maybe too abstract. What's the point of this? I found myself doing a lot of copying and pasting. That's why I started to extract this. I wanted to give a more complicated example how this might be a little bit more useful in your day to day. This is a case of a larger component.
And there's this sort of main section. We've got the professional, the data, the plan sponsor sort of call outs. And then we have this sort of column section for academic and for non member. And there's a few things we want to make sure happen here. We want to make sure the academic and non member always take up the space next to the other columns. No weird space between them or them to not appropriately align. We want this to happen. And make sure they have equal columns on the left. And make sure the buttons say at the bottom no matter how much content is in the other buckets. This is difficult to achieve with float. With Flexbox as straightforward. So on the outer container we decided that this section should be 75%. And the other remaining sections should be 25%. All I've got to do is using the mix in we created, set the column to 75% and set the pattern between them. And what that's going to give us, right away, the main layout of a box over here and a box over here that's 75 to 25%. Not that exciting yet.
Okay. So what about the left column? So the left column, right, we said we wanted to make sure these were all equal widths and heights. All we need to do now we have created the mix in is include the Flexbox mix in. May include padding depending on needs. But it's straightforward. And finally the right column, make sure they are flush against the other bucket. So in this case we set it to be display flex and set the flex to be column. And make sure the children are going to fill up the remains space with flex grow one. That's going to give a decent layout that pretty much matches the spec we do. The final thing they mentioned is we wanted to make sure, right, that the copy at the top was always at the top and despite differing copy all the buttons aligned at the bottom.
So what we have to do is for these particular items, set display flex and change the flex direction to be column. And use that justify content to give us the space between. So we're going to have things going to top and things going to bottom. Okay. So what's the main takeaway here? Again, Flexbox, it's all about it's about content based width. It's about dynamism. Not forcing things to be in a rigid structure. It's about letting things take up the content. So see elements as more dynamic and then align and distribute them on the container level. Focus as much as you can on the container because it's going to keep your code a little bit drier. And finally for reoccurring structural logic, so a lot of times we have logic related to padding or children properties. It might make sense to create a Sass mix in for that. Pull out that stuff you find yourself continuously copying and pasting. And create a one liner for the component types and appear and reappear. Finally, utilize the parameters to handle everything within that particular component type. Thanks.
[ Applause ]
>> CLAUDINA: Great. Love Flexbox. Love me some flexing. Are you using Flexbox, here's the question for any layout things beyond components, or just using it for components?
>> EMILY: So right now I've been using Flexbox for everything in production. Obviously when grid comes around it will make more sense to use that for the outer wrapper and then the components. But I think the Flexbox is the best bet when it comes to layouting.
>> CLAUDINA: That's cool. We do that on our site. So it fun, reorder this easily. And also Twitter. Have you been playing with any grid stuff as well? Like experimenting with it even though it's behind flex? Or stick so good flex?
>> EMILY: Definitely, there's a lot of value there. And it's awesome to stay on top of that. But unfortunately browsers are a thing. So it limits us to what can be done in production.
>> CLAUDINA: Anything that trips you up about Flexbox? I still sometimes have the CSS tricks, everything you need to know about flex. Oh, sometimes I forget which ones these are.
>> EMILY: I think IE10, and recently relate to heights. This doesn't match anything that should be happening. And then refresh and page turns. Yeah, exactly.
>> CLAUDINA: I love the repo flex bugs by Philip Walton. Are you aware of it? So good. Saves my life when I deal with a cross browser. What is this? You have answered my question. Cool. Well, that was our flex talk. So thanks, everyone. Thank you, Emily.
View Slides

Justin McDowell

Bauhaus in the Browser

>> JUSTIN: Before I get started, I want to call out the transcription service, it's been incredible this whole time.
[ Applause ]
When I wasn't mesmerized by Sara Soueidan's talk, I was watching. And she got every word. So impressive.
All right.
Let us therefore create a new guild of craftsman. Free of the divisive class pretensions that endeavored to raise the prideful barrier between craftsmen and artists. Put this up a little bit more.
This was the manifesto of Walter Gropius, founder of Bauhaus in Weimar, Germany.
His manifesto called for the collaboration of artists and craftsmen which ushered in that balance of form and function that we now call modern design. Bauhaus was a German art school founded in 1919 and it existed briefly during the tumultuous peace between World War I and World War II. Visionaries at the time saw opportunities to use art and technology to advance society. And it was with this outlook that Walter Gropius founded Bauhaus. His goal was to redefine the way that art was taught across the country. If you wandered through Ikea or Target today, a tubular steel chair or flat pack furniture may not seem all that special. But in the early 20th century these were revolutionary ideas for the mass production of goods and it stemmed from Bauhaus. Gropius and the other masters turned their noses up at art history, taking an ahistorical perspective to painting. The educational tradition was to copy the works of classical artists like Rembrandt, da Vinci, and Gentileschi. And the masters there ignored this tradition and their attitude pushed the boundaries of what art could be. Instead they explored the concepts of color, shape, and medium as if they were in kindergarten discovering it for the first time. Abstract and graphic, non-objective art intentionally invaded the sensible taste of the bourgeoisie. And this attitude still persists today. Our most notorious artists are still often the most subversive. Think about Marina Abramovic, Ai Weiwei, or Banksy.
This focus on basic forms and primary colors also applied to graphic design. And the rules of Gestalt layout and typography that were established from the stripped-back approach to creativity are still studied and practiced by designers to this day. When I was in Berlin last year I got to visit Bauhaus Archive which tells the history of the school and collects and exhibits artifacts from its past. And it got me thinking about how I could apply some of their ideas to the Web. The designers of the avante-garde experimented with new tools, new revelations in psychology and science and new means of production. And this landscape was prepping them for a burst of creativity and innovation. Today the Internet has once again changed the fabric of our society and you have already seen some pretty great art coming from that over these last two days. Think back to Sarah Drasner's amazing color animated paintings and undulating fire. It’s very cool. Yet nearly a century after the fact we're only just now able to apply even some of the simple concepts of the Bauhaus to the Web with some new specifications from the W3C. There are five topics that I want to explore today. Viewport units, yes, again. Transforms, grid, shapes, and blending modes. And I'm going to apply these to various works by artists of the avant garde. So starting out, let's talk about Kurt Schwitters. He was a dada artist who used psychological collage, which he called Merz, to reject the reason and logic of the bourgeoisie capitalist society in order to make sense of the world using found objects. And these collages for which Schwitters is best known can get pretty abstract. So I'm going to focus on something a little bit more down to earth. When I was at the Vancouver Art Museum I got to see some of Schwitters’ work up close, including this issue of “Merz,” which was typeset by El Lissitzky who was a frequent collaborator with Bauhaus. I thought it would make for an interesting typographic experiment for the Web. So I spent an afternoon putting this Web based reproduction together. It's pretty close in reconstruction. But the real beauty of it is that it's shockingly consistent at any screen size which I will show you now in Firefox.
All right. So we've got the page here. I have it designed. And if we switch into responsive mode. Let’s grab this one. Maybe. Let's do the iPhone 4. Since that one's is a short one. There we go. So you can see that when I resize it then you can see there's a breakpoint in there. But the text stays exactly in place.
So in order to re create this magazine cover and make it so fluidly responsive I used viewport units. Keith Grant covered these pretty well yesterday. But let's recap for those of you watching from home via YouTube. Or maybe Vimeo. I don't know. These are units of measurement that are relative to the width of the viewport. Basically one viewport length is equal to 1% of the screen length. There are four kind of viewport units, but today I only have time to talk about two. VH is relative to the viewport’s height, and VW is relative to its width. And so you can use viewport units to size all kinds of things which you will see throughout the presentation. But has a particularly interesting effect on typography. Are you sensing a trend here?
Sizing type based on the viewport offers a much more nuanced type size because it isn't given a specific pixel height, nor is it relative to any other font size like you may be used to with Ms and rems. And instead it gets bigger and smaller based on the dimensions of the viewport. So let's think about the old way of sizing type for the screen. There's kind of a lot going on here, so just focus your attention on the main part here. Here I've sized my text in points, not viewport units. And I’ve designed this for mobile first. So on an iPhone-size display, looking pretty good. But when that screen size increases, the line length increases while the type stays the same size. And with this justified type it clearly just looks wrong. We can't fix really with this breakpoints because I need so many of them because I want to make sure this looks fine at every screen size. And the instance I start increasing the width, then that justification starts to get out of control. I'm trying to be especially picky to stay true to the typography of that original. And I want this to look as good as it can at every screen size. So as you saw when I sized with viewport units instead, that text acts almost like an image or an SVG when it's being resized. So a lot of attention to detail that I put in here that I don't have time to dig into right now. But it holds true at any screen size no matter what size it is. And that justification is constant. The design is consistent. And, again, I'll show you real quick in the browser.
See, it's almost like it's resizing an image instead of actual text. But you can select it like actual text.
[ Applause ]
Thank you.
So that said, let's talk about accessibility. Sara Soueidan has covered this a bit, and so did Keith. Basically I’ll just read this quote out for you, “I've gotten some constructive, highly appreciated accessibility feedback from my blog readers about using vw for font sizes. Basically, don't.” Generally I agree with that. I don't think you should use them for most texts. Most of the time you should use something more like Keith's M based modular system. But I do think there are scenarios such as this one where art direction demands that text flows in a certain way. But these are also going to be scenarios where you're more likely to sweat the details. So you really should make sure that it's readable at all your different supported screen sizes. And again, as Keith and Sarah talked about, another way to mitigate this problem is to combine viewport units with a text-based unit like Ms using calc. So for the viewers watching at home, be sure to check out those other two talks by Sarah and Keith.
Another place that viewport units come in handy is that sidebar on the left there. Its width is set to 20vw. And the content inside has been rotated which I'm going to cover in a little bit. But just know that its height is also set to 20vw. So they are both using, now, a relative unit to that viewport width. And so the height of the contents is responsive to the relative widths of the container. This isn't something you can do with percentages or pixels.
It’s unique to viewport units. Browser support is pretty good, Internet Explorer and Edge don’t support Vmax, but everything else does work. Other browsers are pretty good, but Opera mini doesn't support them unfortunately. If that's a browser on your list, you’ll need to figure out how that's going to fall back. You’ll see viewport units used throughout this presentation, but now I want to talk about transforms. Transforms are CSS functions that you can use to manipulate the geometry of elements. You can rotate them or skew them or move them around in your design. They have been standardized for a long time now, but it’s still not something that I see on the Web all that often. And I wonder why that is? I think part of it is transforms can be tricky to work with. When you apply a transform it doesn't affect the document structure around it. So you can sometimes run into problems like overlaps. And so this is why it's important that that sidebar container width matches the content’s height. Because that sidebar is actually kind of acting like a dummy column and it’s reserving space for us to transform content into.
So took a little bit of engineering to make this happen. And I'll walk this through you Sara Soueidan-style. For those of you who don't speak German, I will fill you in. This is publishing information. And so therefore I put it in the footer element. And when I optimized this design for mobile I decided that the footer should go at the bottom of the page. And as screen sizes get bigger, I can move this information into the sidebar to match that original design.
I'm going it to run through this fairly quickly, but I’ll stop at the places related to transform. Here we go. All right. So here I've rotated the issue information on the left using the rotation transform. And the transform origin is the point where the element would be rotated around. Normally that’s in the dead center of the element. And I changed it here to the top left because that keeps the text positioned inside the row that I created.
All right. So now I've rotated the whole thing minus 90 degrees. And once again, I’ve changed that transform origin so that the element rotates around the point that I need it to.
And the next thing I did was slide it down its full length. And I did that with a second transform called translate. This is the same transform that Will Boyd used to make those fish move back and forth yesterday. Using translate is similar to moving elements around by their margins except remember that transforms don't affect the document flow. So it doesn't affect the elements like margin does. Keep in mind that even though we're moving this element from top to bottom, we have to be considerate of its axis, which hasn't changed. So what we think of the top right now is still the right end and the bottom is the left. So if we’re moving down that means moving left along its X axis. And so that's why I've used the transform X function to move left the full width of the footer element. And notice how the translate function is added on to the same transform property as our rotation transform. You can see we can have multiple transformations on an element.
After that we’ll finish up with some extra margin. And voila. So in the end we have vertically oriented text with viewport units and transforms. But that's enough about Kurt Schwitters. Let's move on to one of my personal favorites, Jan Tschichold. He was a German typographer who was so inspired by the Bauhaus of 1923 that he became one of the leading practitioners of modernist design. He would eventually go on to write the new typography, create layouts systems for Penguin Books and design posters for Phoebus Palast, a movie theater in Berlin. So take a look at his movie poster for a German film called “The Woman with No Name.” Check out that title. It looks like it’s zooming off into the distance. We can replicate that to some disagree using transforms. And to do so we're going to switch up into three dimensions with a transform called perspective.
There are two ways to apply perspective. One is on an element by element basis, again, using the transform property. In this way each element has its own perspective or its own vanishing point. The other way is to declare perspective on a parent element using the perspective property, not the transform property. Every child element transformed inside this will share the same vanishing point, so they all kind of co exist in the same world.
In re creating Tschichold's poster, let’s start with the title. There are two parts to it, the title, “The Woman with No Name,” and the sub heading in red, which says “Part Two.” So, yes, there was a part one before this. These two elements share the same vanishing point. We're going to share a perspective property on a containing element. When you use perspective you have to set its length. But it can be a little bit tricky figuring out what that should be. That length indicates the simulated distance you are away from the 3D plane. Which is just really a kind of complicated way of saying that it sets the intensity of the 3D effect.
So a high perspective value as you see in that second item there, that mean you're further away from the 3D plane so the distortion is low. And a low perspective value like in the bottom, means that you're closer to the element so that distortion is a lot more noticeable. Perspective is different than translate Z in that perspective doesn't really change the apparent size of the element. Translate Z changes how far away from you the element is. So an element that's further away, for example is going to looks smaller. That doesn't really happen with perspective. And so me I like to think of it as zoom versus dolly. When you zoom in, you stay in the same place and the lens closes the distance to the subject. That picture is going to change slightly depending on how far away you are. That's kind of like perspective. Dolly-ing is a fancy term for physically moving the camera back and forth. And that's translate Z. When you combine them together, you get a dolly zoom. This is sometimes called the vertigo effect after Alfred Hitchcock's movie. But it’s been used throughout film and television to emphasize something disconcerting. Here you have Frankie Muniz in “Malcolm in the Middle” to good effect. And now we’re going to recreate this using CSS. I don't have a lot of time to go into the detail now, but I wanted to show you a quick example that I threw together. Let’s see.
Are you ready to enter the Frankie zone?
[ Laughter ]
So this is a pretty simple demo. You hover over it and it does a little bit of a dolly zoom effect. So I tried to do somehow more disconcerting than Lea Verou's creepy eye demo that she had yesterday. And dolly zoom is good for that. If you look at his nose, for example, it is actually on a separate plane so it comes a little bit closer to you.
[ Laughter ]
And his ears, also, are on a separate plane so they kind of go behind and they blur as they come out of focus. So pretty fun little thing.
[ Applause ]
Let's get that off there so we don't accidently see that again.
[ Laughter ]
Except in our nightmares. Okay. If you want to know more I did write about it on my blog. So go to revoltpuppy.com and you can hunt it down in the archives. All right. So getting back to the poster design at hand, for my header I set the perspective and stacked up a couple transforms for the optimal look that I was going for. Here's the result. The text now has some perspective. This isn't exactly the same as Tschichold's perfect vanishing point because he was simulating a perspective, and we're using a real 3D perspective. We would have to extend the lines basically into infinity in order to make them meet. And that brings whole batch rendering issues of its own. But it still does create an interesting effect and foreshadows the surefire adventure of the woman with no name. I also added a transition so that when you hover over the graphics the perspective animates and some of the images come into focus. Similar to the Frankie zone.
So I'll show that to you. So here we have especially if you look at the top right photo. When you hover over it, then that sharpens up and comes into focus. Kind of a neat little effect there going on.
All right. So transforms can be challenging. But at this point browser support is really good. Internet Explorer has a caveat with nested 3D elements. But other than that I think we're more than ready to add this stuff to our toolbox. Moving on let's talk about Piet Mondrian who in 1922 could still get away with that mustache. He’s probably the most widely recognized artist of the six presented here today. He was a notable member of the De Stijl movement, and his paintings of rectangles are the model of modernism in two dimensions. Mondrian’s composition paintings create a graphic tension and balance with nothing more than basic shapes and primary colors laid out into a grid. And I felt this was the perfect example to try out CSS's first true layout system, Grid.
So if you'll recall from Jen Kramer's talk about Grid, you’ll remember that designers have struggled for years to hack Grid layouts together using tables, floats and Flexboxes. And we’ve gotten pretty good at it. But Grid is coming. It's a new and easy way to create real, two dimensional grids on the Web. Your grids can be pretty complicated, but the CSS can be quite concise and more predictable. For this composition I started out with a bunch of divs and then I put the new display grid property on to the container. And next I need to specify the dimensions of my grid area so I’m going to count up the columns and rows and size them to fit. So in this case we're looking at three columns with three specific measurements and four rows. Writing this out in the CSS is pretty straightforward. I put each measurement into the grid template one by one and separate them with a space. And finally I specified the grid gap, which keeps the grid cells from crashing into each other. You can specify the horizontal and vertical gaps seperately. So finally we have a grid system free from cantankerous collapsing margins and double padding issues and all that junk. The browser automatically assumes each grid section will be one unit, and it flows automatically from left to right, top to bottom. If your grid sections fit where the browser expects them to fit, you don't need to declare them. Take a look at A, there, it's the first section that fills up a single column and a single row. We don't actually have to tell it to do anything in our CSS. If your grid section spans more than one column or row, so take a look at E which spans two rows, then you need to declare the start and end values explicitly. And the end values are the number after the column or row you want to expand. So if you end on row four as we have done here, you declare grid row end five. The final code that we need to create this grid is pretty clean. And in a lot of cases we don't need to explicitly declare some of the values. So remember we don’t have to declare anything for A. We also don’t have to declare anything for F and G. For B we only need to declare the start values. The end values are automatically assumed. And for E just the row values because those column values are handled automatically by the browser. And you can clean it up further with the shorthand grid column and grid row properties which, again, Jen showed you. So check them out, viewers at home. This is basically all that’s needed to re-create Piet Mondrian's composition two in red, blue and yellow. And I'll show you that in Firefox Developer Edition. If I can find my mouse. There we go. Come on.
All right. There you have it. And, again, I sized these grid sections with viewport units. And so no matter how you size it, they all stay perfectly proportional no matter what size or dimensions, as Mondrian intended. And no scroll bars. So viewport units are pretty cool. And so is grid. And we'll just go back to Mondrian there.
All right. So the good news is, Grid is actually supported in Internet Explorer 11, believe it or not. The bad news is, it and Edge are the only that support it in a usable way. And it’s using a prefixed legacy syntax. So it was kind of like what happened with Flexbox where they jumped out of the gate and they had a good implementation and then the working group said now we’re changing everything. Poor Internet Explorer, they finally won a battle.
So as far as the other browsers go, Safari has it unprefixed in their technology preview. So it's got to be coming soon, right? And Chrome and Firefox have been sort of following their implementations. And those are also getting pretty of close. You can use grid for both of them today as Jen told you if you enable the right developer flag. So Grid has been a long way coming. I think I first heard about it in 2010 or 2011. I was super jazzed about it, and now we’re coming up on 2017. So I share your frustrations, but this is something that is very important. We need the browser vendors to really take their time and get it right the first time.
Bauhaus was an important school in design history, but it wasn't without its flaws. Women were encouraged to attend but often discouraged from pursuing their passions and they were rarely given proper recognition. Marianne Brandt managed to push through the gender barrier and eventually became the first woman to join the metal working program and eventually she even became its deputy head. While her male counterparts were prolific after World War II, Brandt remained in obscurity until after her death. She worked in many different media, but she isn’t known for graphic design. So instead of recreating something that she made, I thought I would design a page out her and show off a particularly notable creation of hers, which is this gorgeous tea infuser. So this design brings everything together. It's using grid for layout, viewports for grid unit sizing and there's a transformation tucked away in there. And I've also included the last thing that I'm going to talk about. Take another look at the teapot, and just because it's a beautiful product, but because the text flows around it following its roundness. That’s because I've created a shape. Shapes are a new way for text to render on a Web page. Instead of strictly following the edge of a square or rectangle only, shapes allow us to flow text around and inside of circles, triangles, and any other arbitrary shape we can think of. The specification breaks these concepts up into a few modules. But I'm just going to cover the first one because it’s the only supported by any browsers right now. If you have been in this industry long enough, circles probably still feel a little bit magical.
Thankfully we have moved from stamping them out in Photoshop, and border radius has become a reliable way to turn all of our social media avatars into circles. Of course, border radius is only an illusion. Even though these images appear perfectly round text still flows around the containing square. With shapes a circle can actually be a circle. To create a shape you must first float your element so that text will float around it. And then use the shape outside property to define your shape. Your shape can be based on any shape box, including the content box, the padding box, the border box or the margin box.
And you can even just use the shape box as the shape definition. So, for example, if I set border radius to 50% and the shape box to content box, the browser now uses the circle as the shape. So that's pretty nice.
Some of the shapes that you can create are ellipse, circle, of course, or inset box, or you can create something more complex with polygon. Similarly to when Lea created a polygon clip path yesterday, same kind of thing. Text will ignore regular margins, but you can set a shape margin to keep from text from crowding your shape. And shape margin intersect with the shape box. Meaning that shape and shape margins go outside the shape box. But anything beyond the shape box boundary is going to be ignored. So look at that A there is not being pushed back by the shape margin. That's because it's outside the shape box. So in a way shape margin actually makes our shape look a little bit more like this.
So the shape I use here is pretty simple. But it makes a nice impact on the appearance of the design. If a browser doesn't support shapes, and text still flows around it like a normal float. No problem. Looking back at Tschichold's poster, he used a triangular or trapezoidal shape to present the theater information in the lower right hand corner. In the future we will be able to put text inside shapes like these using inside property, but right now no browser supports this. But nevertheless I've still managed to replicate this effect by thinking outside the box a bit. Instead of using one triangular shape, I’m using two triangles floated in either direction, and the text flows around them giving them the illusion of being inside a triangle. Here's the final result. So it doesn’t have the trapezoidal shape with the box. But at least the effect kind of comes through a little bit. Shapes are under consideration for Edge and Firefox but are supported in other browsers. And, again, it’s easy to start using them today as a progressive enhancement because they just fall back to normal floats.
Herbert Bayer is counted among the second wave of masters who taught at Bauhaus. And as a group they distilled the theories of the old masters into teachable concepts that they could integrate into their own coursework. Bayer essentially helped the school walk the talk by ushering in German standardization and the new typography, including his typeface Universal which I’m using throughout this presentation. This is a calling card Bayer would leave behind when he wanted to make a connection. And it is by far not one of Bayer’s most notable works, but when I saw it I thought it was the perfect excuse to talk about blending modes. Blending modes are one of those things that have been in Photoshop for a long time but have finally come to the Web. Technically color blending applies mathematical operations to the color components of image pixels on overlapping layers. I apologize to the transcriptor there. But what that means to you is that you can create some textural effects. There are five groups of blending modes. Darken modes create darker pixels. Lighten modes will lighten pixels. Contrast modes will both darken and lighten at the same time, increasing contrast. Composite modes are based on the components that make up a color where it’s the color’s hue, saturation or luminosity. And there’s also a color composite mode which uses both hue and saturation of the source. So it kind of combines two of those into one. And finally the comparative modes are a little weird. You probably won't use them that much. But they’re often used to compare and align two images. There's a lot here. But I'm going to share a few with you that I think are especially useful. And I’m going to demonstrate on one of Bayer’s later works called Chromatic Twist 1970. This is going to be our bottom layer which I’ll call layer B. And I'm going to blend this texture on top of it. And you'll see how the different tints and shades change based on which blending mode you choose. We'll call this layer A. So first let’s take a look at the multiply blend mode. This mode is called multiply because it literally multiplies the colors on the top layer with the layer below it. And this is how that function looks. A is the top layer, again grid of grays that I showed you. And B is the bottom layer, Bayer's colorful screen print. X is the resulting color once the two colors blended together. X equals A times B. This is done breaking up the color components into red, green, and blue, converting their luminosity values to a scale between zero and one and then multiplying those values together. And then the browser converts back into RGB and recombines the new RBG values into the new color. So this might be a little hard to discern. That's not Black. It's kind of a dark blood color.
[ Laughter ]
But, yeah. The point is all this creative stuff is just math underneath. More practically, though, what you need to know about the multiply blend mode is the darker the pixel on top is, the more likely it is to show through at the value. If the pixel on top is black, it becomes completely opaque, and if it's white, it becomes completely transparent and the image on the bottom layer shows through. Everything else in between darkens to some degree. So you can kind of think of it like casting a shadow across the bottom layer. Shadows always darken and never lighten. The opposite of multiply is called screen.
And as you can see in this demonstration, the top layer pixel that’s white is opaque this time, while the black will become completely transparent and everything in between becomes lighter to some degree or another. This is like shining a bright light on your subject. But if screen is the opposite of multiply, why isn’t it called divide? If you look at the math, you can see we’re not actually doing any division here. Instead it's taking the inverse of the inverse of A times the inverse of B. Getting back to Bayer's calling card, it consists of three images offset and superimposed on top of each other. Each time the image is reprinted on the card, the ink is mixed together, covering up more of the paper which means it makes the result darker. And so that means we’re going to use the multiply blend mode. There are two ways to apply blending modes in CSS. Mixed blend mode is a way to blend HTML elements together. And background blend mode blends between multiple background images on a single element. So let's try it. I couldn't find the original source of Bayer’s calling card, so I found another portrait of a European man that we can try this out with.
[ Laughter ]
Here's how it looks in the CSS. So I've positioned them similarly to the way that Bayer did. Using the translate X transform. And then I blended the images together with mixed blend mode set to multiply. And that's it. Here's the result. So with blending modes I can change the particulars of this effect. I can shift them back and forth and change the blend mode if I want. And I don't have to go back into the graphics editor and reprocess a new version. And I’ll show you one more example. Judit Karasz was a Hungarian photographer who applied the modernist ideals to photography employing strong use of lines and bird’s eye perspective. She was interested in both social documentary and industrial landscapes. And this is especially evident in her portrait of a fellow student with the Bauhaus facade superimposed on top of it. It's makes for an interesting effect, and it’s one we can replicate today with yet another blending mode. And this time we’ll use the one called overlay. This formula is starting getting pretty complex. But if we look closely its constituent parts actually look pretty familiar. What it's saying is that if a pixel is dark, use multiply, and if a pixel is light, use screen instead at half strength.
You can kind of see that working out there. Looking at this example you can see that the darker pixels make the image darker while the lighter pixels make the image lighter. And there's a block on the right that's 50% gray. Can't see that now. That's become completely transparent with this blending mode. So with this photo here, Karasz has overlaid one photo on top of another. Both layers have pretty good contrast so I'm going to use overlay to ensure that I have strong darks and lights and they don't completely overpower one another.
And again I didn't have the original negatives that were used, so I dug up a photo of Adi Berger who was tragically killed in Auschwitz. And I also found a public domain photo of the balconies of the Bauhaus building in Dessau. And once again I position my images the way that I want them and then blend the images together with the overlay blend mode. And here's the result. So it's a pale shadow of Karasz’s original, but you kind of get the idea. This is just the beginning when it comes to blending modes. If you’d like to learn more I have another talk online about them and other ways to mix color on the Web, it's called painting the perfect sunset. And I have written a couple articles for a list apart about this subject. So you should check those out too. Browser support for blending modes has been decent, but Edge has been slow to implement. Currently it’s listed as on the backlog. Safari supports both mixed blend mode and background blend mode, but it doesn't support the composite blending modes which are the hue, saturation, luminosity and color.
These artists of the early 20th century avant garde and many more showed the world the way that design was done. But they didn't just create the frameworks by which we still design today, they were gleefully experimental, interdisciplinary and subversive. They collaborated together and argued with one another about best practices and it pushed art and craft into a new century. We are well into a new century ourselves and I encourage you to follow the examples of the modernist masters. Not just in re creating their works. But in exploring the possibilities of how art and technology can create better designs. Thank you very much. If you have any questions, please come up afterwards, I would love to chat with you. My name is Justin McDowell. My website is at revoltpuppy.com and you can hit me up on Twitter @revoltpuppy. Thank you very much.
[ Applause ]
>> CLAUDINA: Test, test. Great. Test, test, test. This one? So many mics. I got three mics. Only one works. Not sure what works. That was great. Really pushing us to see things differently.
Cool. So until this mic situation gets resolved. Do this back and forth. But how do you see, like, this type of design perspective making its way to the Web? And what were some of the problems and surprises that you ran into as you tried to apply this to your work?
>> JUSTIN: Well, I think I was replicating a lot of the works of the old masters. But there's someone Jen Simmons is doing great work. More practical work. I recommend checking out her talks. She does a Mondrian with grid and her implementation is very different. It's worth checking out how that works. The issues that I ran into, I mean, there's a lot. There's like one for every thing. Like with blending modes one of the big issues is like you'd love to blend the background with mixed blend mode and then have text on top of it, you know, stand out. But that text ends up getting blended in along with that element. And so I mean, there's that would be so great to be able to isolate the child elements, the text elements and so that they stay at the full normal blend mode and the background overlays that. That's one example. Doing the Frankie zone thing I had to do different things depending on the browser because like Chrome's rendering of the animation when it goes back and forth, it just starts cropping off text in bizarre, unexpected ways. And I just chalked it up to a browser bug. So I had to disable a certain I think I disabled maybe the blurring on it so that it would work correctly. So they've all got issues that need to be sorted out or solved in some other way.
But there are also a lot of them fairly new and experimental.
>> CLAUDINA: Makes sense. Be really cool to see how that could inform our design. Obviously not for every Website use case. But really neat ideas and how to get the Web different. One question from the audience, how does transform perspective and properties handle screen sizes?
>> JUSTIN: I could have showed the Tschichold movie poster in responsive mode. It's something you have to test. But when I was doing it, it actually held up pretty well. And I think maybe because I was using viewport units in that as well. When I sized it down, the image is squished a little bit more closely together. But there are using perspective is something that you're going to wrestle with because it'll change, you know, where on the page your element is and then you'll scale it up and have to move it and shift it around to get it exactly where you want. Again, more challenges there.
>> CLAUDINA: You seem to handle them very well. Thank you so much, Justin, for your talk.
[ Applause ]
View Slides

Amelia Bellamy-Royds

The Great SVG RetCon

>> AMELIA: Good afternoon. So as Claudina helpfully introduced, I'm Amelia Bellamy Royds. I write books about SVG and various articles. I have been spending a lot of time this past year working on the SVG standards and every so often I'm actually lucky enough to make cool things with SVG on the Web.
If you want to Tweet me, @ameliasbrain. And these slides are up if you want to follow along.
So I call this talk today the great SVG RetCon. And I'm going to start by defining my terms. All right. So what is great? What is SVG? And what, pray tell, is a RetCon? Well, great in this context is the sense of big. It might also be the sense of good, but you'll be the ones to judge that. SVG, in case you haven't figured it out by now is scalable vector graphic. It's a language for describing images on the Web using markup and style. So it's compatible with HTML and CSS and other Web technologies.
And RetCon, well, that's where it gets a little more complicated. RetCon is a word that I borrowed from the Comicon world of comic books and science fiction movie franchises. But it count stand for convention or conference, it stands for continuity in the sense of a story that continues smoothly. And continuity in the science fiction world is something you really talk about in the sense of broken continuity.
So, for example, maybe you've got a big action movie sequence. And somebody's costume gets damaged. And then the next shot the costume's perfectly fine. So maybe Captain America has an amazing self repairing costume, or maybe they just messed up with many, many shots all being edited together. It's a little detail and lots of people wouldn't notice. But some nerds notice and they have Websites like moviemistakes.com to report all these mixed up errors.
Now, the Ret in RetCon, that's retroactive. Because sometimes you have to go back and fix the past. And specifically your retroactively fixing continuity. You're creating something in your story now that changes how the previous story is being interpreted. Now, why would you do this if you have a successful storyline? Why would you want to change it? Well, usually because you want to move the story forward in directions that you hadn't thought of when you wrote the first episode or whatever it was.
For example, maybe you had a successful movie franchise and decided you wanted a spinoff television show. It it's going to star the favorite character actor who was the supporting character in the movies. There's a little problem. The problem is, you killed off that character in the last movie. Oops. So what do you do? You RetCon it. You make up this new storyline that, yes, he died, sort of. But then he was brought back by this top secret technology. But it was top secret, so either people were pretending he was still dead or thought he was still dead. And that's how come Agent Coulson is dead in the marvel movie universe, and leading a team in the Marvel TV universe. At this point you're wondering what does this have to do with the Web in general and SVG in particular? Well, continuity is even more important in the Web than it is in movies. You can reboot movies. You can have a new Spider Man series and it starts again. Everybody is okay with that. But you can't reboot the Web. The Web is out there, it's existing, it's continuous. You can't just change it all at once.
This is different from other programming environments. If you're programming on server side or building something to compile as a binary to ship to your customers you control the environment and the language you use. You can switch any time. So it's different from JavaScript libraries. Even though JavaScript libraries are on the Web, you, as the Website developer, get to decide which version of a JavaScript library you're pulling in. And so the libraries can update with new versions that have breaking changes. And as long as they warn you there's breaking changes, you, as the Website developer can wait. And when you have time to refactor to the new version, then you can update. But you can't reboot and version and break the content that's actually going to be read and interpreted by the browser. Because you don't control which browsers see your Website.
Now, rebooting the Web has been tried before. That's basically what XML was. Suddenly a bunch of serious programs looked at the Web in the '90s and said we have to get structure in here. The problem with XML, all of the browsers still had to support HTML because they had existing content on the Web they wanted their users to access. And all the Web developers had to support old browsers. They also continued to use HTML. Because after all the other option was opting into beautiful error messages like this. Or like this. And these were kind of useful in the world before Dev tools, but they were kind of awful if you made one typo. And this is what your end user saw.
So XML kind of died. And Web standards makers learned from this. They learned that you've got to focus on continuity. You can't just tell everybody to upgrade to a new version of the Web. So new standards are always built in this focus on continuity. The browsers, as much as possible, unless there's major security concerns, still support all the old features. And new features, as much as possible, are designed to allow good fallbacks assuming the people creating the Websites use the options for fallbacks.
For example, we have the picture element. And the picture element is all this cool new functionality, but at its very core it's just a basic IMG element. If you send all the modern picture element markup to an old browser, IE8 or something, it's like the Far Side cartoon you're talking to a dog and just hears blah, blah, blah. Until it gets to the point where it actually understands something. That's your image tag.
Now, this brings us to SVG 2. Which as I said, I spent way too much of the past year working on. Now SVG 2 as of two weeks ago is a W3C candidate recommendation. Which basically means that those of us who have been working on it and people have been working on it a lot longer than I have are done fussing with it and we really want the browsers to implement it and fix up any last bugs and get this stable and usable for new content creators.
[ Applause ]
Yay! SVG 2 has a number of interesting new features which I'm not going to really talk about too much today because they're not out in browsers yet. You can't really play with them much. But there are a few features that you can start. I should warn you, there are also drop features. Which goes against everything I have said about continuity. But the features dropped are all ones that were never Web compatible anyway. Which means there was at least one major browse their either didn't support them or their support was so buggy you'd never dare use it. So lots of these things have been used, but chances are ideals you're a total SVG nerd you won't notice anything missing.
So what I am going to talk about today is not either of those aspects, but rather some more central core changes in the concept of what SVG means and how it interacts with the rest of the Web. Because SVG 1.0 came out it was finalized in 2001. And the rest of the Web has kind of changed a bit since then. So SVG 2 is doing a lot of RetCon’ing, revising how you think about what SVG means in order to fit better in the rest of the Web.
So to start that off we can start with markup. Core of any Web page is your markup. And the core idea of SVG 2, sorry, of SVG 1, the original story, was that SVG is XML. Because back in '99, 2001, when SVG 1 came out, XML was going to take over the world. It was the newest, the coolest. SVG was going come along, would be able to integrate it with all sorts of different XML languages, XML style sheets transforms. Lots of crazy neat stuff. But as I already mentioned, XML did not take over the world. So we need 15 years later a slight new perspective.
So the new perspective, recognizing that HTML has continued to take over the world, SVG is document model. Which can be expressed in the XML. We still got continuity with everything that exists. Or HTML markup. Now, if you already use SVG a lot you probably already use this without thinking too much. Because if you're using inline SVG code in a dot HTML document, that SVG code isn't being treated as an XML markup, it's being treated as a type of HTML markup in the sense that it's being read by your HTML Parser.
So the SVG 2 changes are not so specific to making the new change. It's more tidying up the SVG spec to match the current reality. But an important thing to remember about that I'm going to move this out of the way. Is that if you have a dot SVG file, that is still an XML file.
There we go. So what I have here and this little GIF demonstration two browser tabs, two files with the absolute identical text content. The only difference between these two tabs is that one is a dot HTML file and one is a dot SVG file. The dot HTML file has no problem drawing this Euro character. The dot SVG file give use the yellow screen of death. And that's one error of many in this file because it's actually a horrible, horrible markup that I stole from a stack overflow contest for how few characters could you use to describe this image.
But the HTML Parser has no problem figuring it out, even with the errors. And the SVG, by the SVG file. What do you do with crappy markup? Make hack something together quickly. Works fine in HTML, but you need a dot SVG file? Well, you use the Parser loop. Your browser Parser, the HTML Parser, knows how to turn that awful markup into a good DOM. So you can just take advantage that have. The easiest way is in Microsoft Edge. And click on the SVG on the menu. Does it say picture as like on a Canvass or JPEG. And save as a beautiful SVG file that works stand alone. It's wonderful. And it's only on Microsoft Edge. Some of you don't have windows computers in front of you. So the GIF sequence being shown there, open it up in your Dev tools. You do copy over to HTML, paste it into your code editor. That's cleaned up all your quoting. It's cleaned up all your tag nesting for you. And the only thing you have to add at the end is your XML name spaces and hopefully your code editor has autocomplete so you don't have to actually remember what those are.
So that's just basic hints. If you're going in the reverse direction, if you're going from an SVG file to HTML file, it's mostly good because that HTML Parser is so good at handling weird markup. But the warning is don't do anything weird with XML, especially with XML prefixes. Don't ever put prefixes on your SVG or HTML element names. And there are some name spaced attributes. Always use the standard prefixes. Xml: href, xml: lang. If you're using illustrator, this is going to do this anyways.
But if you're using SVG software you have to worry about a bunch of other XML stuff it might throw in. Custom name space stuff just because it's including all its extra information in case you want to open it up and edited it again. You don't want this if you're cutting and pasting to your HTML file. You want the proper export for Web and then probably throw it through an optimizer as well after that. You'll notice in this one I commented out the actual SVG stuff from this drawing. All the rest there is junk except for the view box on the SVG is the only thing there you need.
But other than that, you know, if you copied and pasted the additional Parser would handle it. Now, that's if you're using a markup button. If you're using scripts, it's a whole different story. If you're using scripts, creating dynamic SVG in the DOM, always need the name spaces. The DOM still needs name spaces. The HTML Parser adds in for you, but if you're using DOM, create that. Two options. You either use the name spaced methods or you use a JavaScript library that under its hood uses these name spaced methods.
So any JavaScript library that's SVG focused will do this. Non SVG focused ones don't. And you'll end up with something that look like SVG markup in your Dev tools. They don't show name spaces. You'll be banging your head and trying to figure out what's wrong. You'll have a whole bunch of HTML elements with just the names, circle, path, rect, but they aren't. The other option is, once again, you can use the Parser loop. You can use the inner HTML property of a DOM element and if you're in an HTML document it will trigger the HTML Parser. The only problem with inner HTML is it was originally only defined on HTML elements and the new browsers all support it on SVG elements. But depending on your browser support you can easily trip up with that giving you an undefined or other problems.
So what I've got there is creating an HTML div and using its inner HTML property to read the markup. So that's markup. And XML versus HTML. The next basic concept when you're talking about Web is links. And links in SVG version 1.1 used something called XLink. Using the XLink H ref to create simple links. It was an interesting specification, this idea you could have one consistent way of defining links across many different types of documents. You could have complex multiple relationship links. You could have a single file of links that connected the relationships between two other files. Video or audio or something that didn't have its own link format. It was really neat and went nowhere with the rest of XML. The only time you bump into XLink or these nasty prefixes, in your SVG file. And SVG only had simple links. And simple links were basically the kind of links you had in HTML for 25 years now without needing any extra name spaces.
So SVG 2 simplifies the story. SVG uses the href attribute to create links. XLink is dead. Cue the Ding Dong the evil name space is dead. What does this mean to you? Not much. I'm sorry, but at this point in time this change doesn't mean much. This is a Tweet that came in last week. XLink is deprecated in SVG 2, but use without it, it doesn't work in Safari. What should I do? And my answer is still use XLink. Because you as content creators have to be worried about continuity and the fact that there are lots of browsers out there that have not immediately updated to the new spec.
So for continuity you still have to use the old one. There are fallback rules in the spec for what happens if you give both attributes. But that would be just introducing redundancy in your code. Why would you want to do that? The only time to use both of them is doing something like this, if you want to do this. A CodePen I created, does your browser support SVG and Href. It has both attributes with different values. You get yes or no. All versions of edge, Chrome, plus stable since April. Firefox 51 plus. Which is currently nightly, might have just hit Dev edition. But right now no support. Estimated time in Safari and in the current stable Firefox. Unless you're using Electron apps or something where you are just aiming for the latest version of Chrome, keep using that XLink prefix.
But you can dream of the day when XLink will really and truly be dead. Next step up for building your Website, styles. After all, this is a CSS conference. But back when SVG was still created in 2001 as I said, CSS was still kind of new. Wasn't sure whether it was just going to be a fad. And the people who wrote the spec decided that they weren't going to require every SVG software out there to be have to implement a CSS Parser. So they gave options. They said SVG styles can be defined with CSS properties. Or with equivalent XML attributes.
Now, it's been 15 years. CSS keeps getting bigger. They have conferences about it now. And this has been a problem for updating. There are lots and lots of new CSS properties. Which would mean lots and lots of new attributes. And there are also lots and lots of new CSS features that don't map to attributes. So there's all these new rules, new pseudo classes. And how do you represent that in XML attributes in and the other problem dealing with a progressive enhancement world, no way of doing fallback in attributes because you can only have one attribute of a begin name on any element. So for SVG 2 the spec has moved all the way on to SVG styles are defined with CSS properties. Some of which still have presentation attributes. So I should say CSS is now required in the spec for software that's interpreting SVG. You do not have to use it in your SVG code. If you're worried about your SVG files being processed by little utilities like image magic for creating PNG fallbacks. Then you might want to stick with the simple attributes. But moving forward the idea is to move all the way into CSS. There will be no new presentation attributes for new properties. Using CSS in SVG. You can use anything that the browser supports.
The CSS in SVG is just the same as the CSS you use in your HTML file. Not every property applies to SVG, but all the syntax that the CSS Parser reads applies. So that means you can use all your usual CSS fallback methods if you're using something new like CSS variables, you can have a previous declaration and browsers that don't understand variables will just use the previous one.
You can do something with an at supports rule if you need to coordinate different styles. And you can build robust applications with lots of fallbacks this way. But one question, you've got all this CSS, where are you going to put it? Really depends what you're doing with your SVG. If your SVG is going to be used as an image, so that's you're using it as a background image or something with an HTML IMG element, that CSS needs to be in your SVG file. Images don't load additional resources, no additional style sheets, no additional fonts or additional image files. So SVG has a style element just like HTML. You can put that style element anywhere in your SVG file and then you can write all this CSS code in there and it'll apply to that image. There'll be no crossover from the main document to the image. But you can do anything you need inside that image file.
For other types of using SVG, if you're using object element, then you get an interactive content that can load external style sheets. If you're using inline SVG then you can have external style sheets, but need to watch that your styles apply to the entire document. The HTML, SVG, any other SVGs. It can be a good thing if you have an icon system to style every SVG with one line of CSS. It's great. It also means that they inherit styles. So your SVGs can inherit the font size and font color which can then use through the current color keyword. Also great. But if you're not paying attention, just like any other Web page component issue you can get style specificity and clashing between different components.
So that's how you apply your styles. But what does it mean to style an SVG graphic? Now, as I said, back in the original SVG spec they didn't make CSS required. But it was at a time when CSS was new and especially this idea, this theory that you should separate your styles from your content. That was a big thing in Web standards. So SVG wanted to go with that. But SVG is an image format. What's style and what's content when you're talking about an image? It's a bit of an arbitrary distinction. But the decision that the spec writers made was that geometry was content and colors and everything else was style.
So that makes sense geometric was defined in the SVG markup. Makes sense with a drawing. This is a great example by SVG essentials by my co author, David. You take the cat and make the styles the same. Change the geometry, the smart ears become longer, and the whiskers are short, and you no longer have a drawing of a cat, it's a rabbit. But if you change the colors, you still have a cat, it's a crazy cat. It's a style versus a content change. In that context it makes perfect sense. But not all SVGs are drawings. There are lots of diagrams and charts. And in diagrams and charts, the geography is symbolic and arbitrary. And you can change the geometry. And the important thing is you have consistency. Anything that represents the same concept has the same geometry. And when you have that sort of thing where you can change it, but you want lots of things to change together, it would be really nice if you could just slap a class on this and have a single CSS rule that changed it all. And currently in SVG you can't do that. And so you end up, you know, needing some sort of scripting tool that keeps everything organized and up to date.
So the SVG 2 story, tweaked with a little bit. Document structures defined in SVG markup. Geometry is defined by new geometric style property or their presentation attributes. So we had a perfect opportunity for RetCon. They had the concept that style properties could be represented by attributes. Yes, all those attributes that existed, they're still supported, they still work. But those attributes are now presentation attributes for style properties that just nobody's known about forever.
So the existing story is explained in a new bigger story. Now, what does this mean for you?
Well, when it's fully supported it means you can do lots of things with geometry that you can currently only do with styles. Like change it up based on media queries or pseudo classes and animations and transitions with CSS animations. But it hasn't been a perfect transition. It hasn't been a perfect transition because attributes are not directly equivalent to styles. Attributes in markup are always attached to an element. And that means they can be defined and explained in the context to the element. Styles should be universal. When the CSS Parser reads your CSS styles it doesn't know what type of element is on. So you have to have the same value always.
And there have been many examples in SVG where the attributes were very context sensitive. And we had to change it up a little bit for converting styles. For example, two different elements had attributes called RX and RY. The radius elements. If you attached these attributes to a rectangle you're setting the corner radius of that rectangle. If you attach these attributes to an ellipse, you're setting the size of the ellipse. That point is not a problem. But there was different default behaviors. In rectangles you could only set one of these attributes. And the other one would automatically imagine you get a circular corner. In an ellipse if you didn't set one of these, the ellipse would be an error and not be drawn.
So we have different defaults, different behaviors. In this particular case it was an easy fix. It is going to be a breaking change once it’s implemented. It's not implemented now. But the ellipses will borrow the rectangle behavior if according to the spec. And so you will be able to set one and the other one will get an auto value, CSS auto and that. And in this case, it's a breaking change, but we're only breaking something that was already broken. Breaking the error condition to create a useful function. And so that's sort of a spec change where we're okay with that.
But there were lots of other cases where it wasn't this simple. For example, we have X and Y attributes all over SVG. And in most cases they're describing a single point that's going to be the top left corner of a rectangle. But on text elements X and Y take a whole series of different values to describe the position of every single character in that text. And this is something where the Parser has to know what element it is to know whether it's allowed to have many different values.
And at this point the decision has been made to not make a decision. So X and Y for most elements are available, or will be available as presentation attributes in your CSS. But on text they're still regular attributes. This is not a great situation. But it's a compromise. It's where we're at now. The story is not over. But because we have to worry about continuity on the Web and preserving things long term, we don't want to jump in and make a bad decision that we're then going to be stuck with forever.
So this is where it currently is with SVG 2. We've got a variety of geometry properties. We've got some elements, shape elements, that you can set those values with CSS. And then we've got other elements, the text elements and graphical effects elements that unfortunately have attributes of the exact same names that aren't tied to CSS. As I said, it's not ideal. But it's dealing with trying to work from what we had and move forward without breaking anything.
And that brings us to the other side of geometry in SVG, which is transforms. Now, because it was geometry in the origin SVG, it was an attribute based thing. And core story, the SVG coordinate system can be manipulated with the transform attribute. Now, Justin talked a lot about transforms. Don't need to go into details. But you can make all sorts of cool designs. You can change and manipulate shapes without going in and changing the individual geometry. You can move entire drawings in different positions and angles and whatnot. And it's so wonderful that CSS wanted to get in on the game.
And so we have the CSS transforms module which some of you might be familiar with. And it was going to be an easy RetCon for SVG 2. Just like the other geometry attributes. The transform attribute would become a presentation attribute for the transform property. But unlike the other geometry attributes there would be an extension that you could use it in the rest of CSS and not just in SVG. So we have this revised story. Coordinates, SVG or not, can be manipulated with the transform and the new transform origin properties or with the transform presentation attribute. It was wonderful.
Or not. If any of you have actually tried using CSS transforms on SVG elements you know that the current state it not very wonderful. CSS transforms in SVG are the perfect example of broken continuity in Web standards. SVG transforms has been around for 15 years. All the browsers have had perfectly interoperable implementations of SVG transforms as long as they've had implementations of SVG at all. But the CSS transform spec was written by CSS folks thinking about CSS needs and not thinking about continuity with SVG. And this is a problem because SVG layout, and therefore SVG transforms were all based on this coordinate system. But CSS doesn't always have a coordinate system. It has boxes which are sometimes floated and sometimes an inline wrapping. And sometimes in grids and sometimes in flex. So CSS transforms were going to be defined relative to the box.
And so if you rotated something it wouldn't be rotating around a coordinate system origin, it would be rotating around the center of the box. Which is all very useful, but the specs never said how this is going to apply to SVG. So different browsers took different solutions. Firefox just maintained continuity and their application of CSS transforms to SVG matched the SVG transforms that have already been implemented. Blink and Web kit went to try to use individual boxes around the shapes. And so far Microsoft has dealt with the issue by not dealing with the issue and not applying CSS transforms to SVG at all. There is hope.
There has been something in the draft spec for about a year now. And there was an agreement by the CSS working group last week to get this and the rest of the CSS transforms in a stable spec published as soon as possible. So hopefully the browsers will implement it as soon as possible. 3D transforms have been pushed off because they have a whole other set of bugs. But the important thing for SVG is something called transform box. Which is going to be a new property. And to explain what that is, imagine a very simple SVG. I've got an SVG element and one polygon in it. And the only important other thing there is I've got this view box on the SVG, which as other people mentioned, sets up your coordinate system. And I'm setting up my coordinate system so it's 70 units wide, 70 units high. But it's offset by 35 units. So the center of my coordinate system is actually or the origin of my coordinate system is going to be in the center of my SVG. Which I'm representing in these images by the dashed lines being your X and Y axis. So with transform box, this new property, you're going to have options. You can say transform box view box. View box referring to the SVG view box attribute.
So now all your transforms are relative to that origin in the view box. And if you have any percentages, they're relative to the width and the height of that view box SVG area. And this is complete lid backwards compatible with SVG transforms.
The other option is to say transform box fill box. And it will create a box around the fill of the SVG is the name for the basic core paint of an SVG shape. So the fill box is basically the geometry box not including the stroke outline.
And you'll use that box as your reference box. The zero, zero point will be the top left corner of that box. But you could easily change your transform origin back to the 50%, 50% default that it is for CSS boxes. And so by changing two properties, if you like the CSS mode of transforming, and that makes sense to you, you'll be able to do it. Versus if you want this SVG mode you'll be able to do that. And it'll be wonderful. When it gets in browsers. It's not in browsers yet. So the question is, what do you do for now? Oh. Here's a final story. Multiple edits, of where we want to be. That's where we want to be with transform, transform origin and transform box in browsers. But it's not there now.
To what are you doing if you want to transform SVG elements for now? For most things, keep on using the attribute. As I said, all the browsers have interruptible implementations of the transform attribute. The if you're using CSS transforms make sure it's a progressive enhancement and make sure you don't use any percentages because that's currently the main disgruntlement between the Chrome and Firefox implementations.
But if you are using the transform attribute and you're used to the CSS transform property, be aware there are other important differences. The SVG old syntax does not use units. It always used numbers that are equivalent to either degrees or pixels depending on the context. And there are also lots of these new short hand functions in CSS that don't have equivalent in the old syntax. So if you're doing this for fallback, you want maximum support, you've got to use the old syntax.
These changes were a good RetCon. The idea is that future browsers will continue to support the old syntax in the attribute. Not in the style property. But in the attribute you'll be able to continue to use the old ones. So for now you should use the old one so that the old browsers can support it.
The other way you would be using CSS transforms on SVG is if you want to, as I said, add in extra effects. Like maybe 3D transforms that didn't exist in the old SVG. So you can create a cool layout with 3D transforms and then you can make a lot of adjustments to this to deal with all the bugs of 3D transforms. Bad in all of CSS, but especially when applied to SVG. So I'm actually fading something to zero opacity at the back there, because otherwise things were getting painted in the wrong order and it was kind of horrible. But it worked. A little adjustment. Funny little effect.
We've got the team Web. Everybody moving. But if you look at that in Microsoft Edge, I've got a 2D layout. And Edge doesn't apply the CSS transforms, but it still applies that transform attribute. The other browsers the transform attribute gets overridden bit CSS. So the fallback doesn't hurt them at all. And the only complication is that I've still got that opacity animation coming through because the you can't use the at supports rule to cancel out your 3D transforms if they're not supported because Edge does support 3D transforms on other elements, just not SVG elements. Goes back to the bit about the universal Parser. The CSS Parser is what does the act supports rules. And it thinks that's valid because it's valid on some elements and then it just doesn't get used in actual drawing.
But in this case I think that's an acceptable fallback that somebody who just saw this would totally think that was an intentional design choice and not the side effect of a hack made for a completely different layout and just built into this layout. It's not perfect. But if you're willing to accept the Website doesn't have to look identical in every browser theory then you can make it work.
And that's about all I have time for today. There is much, much more I would have liked to tell you about. I'm going to turn these into a series of articles about other new features in which you can and can't use yet. But otherwise you can find me or Tweet me or e mail me if you have specific questions. And that's all about me. And thanks for your time.
[ Applause ]
>> CLAUDINA: Bring that mic over. Yeah. Much easier Oooo. So much exciting stuff in SVG 2. So you've had like
>> So exciting. Haven't talked about mesh gradients yet.
>> CLAUDINA: That's like a whole other talk. So you have had a sneak peek into this for a long time. How are you holding your tongue and hiding this information for so long?
>> AMELIA: We haven't been holding our tongue. Please, if you care about this look into the specs. Start playing aren't with the experimental implementations. Like I should have mentioned the geometry properties, there's experimental implementations in Chrome and Web kit. You can play around with them. They're a little buggy for the current spec. But if you're careful with your fallbacks, you can do interesting things with creating alternate media query layers or something like that. So, yeah, play around with them. And also for the things not implemented yet, look into them, talk about this. Tell the browsers you want them to implement them. Because that's the way we're moving forward.
>> CLAUDINA: How do we tell the browsers we want to implement them or that we found a bug?
>> AMELIA: All the browsers have bug reports now. So the different bug trackers at the open source things. Most of them have feature request bugs for all the features that you can upload. And Edge has a separate feature request system from the bug tracker. But both encourage things. And just be vocal on social media, Twitter and whatever. There's lots of browser Dev people that you can harass about this is really important. And I would totally use your browser all the time if it could make really awesome 3D animations with performance. Or wrapping text in SVG is another thing coming. So yeah.
>> CLAUDINA: Cool.
>> AMELIA: Get the word out.
>> CLAUDINA: A question from the audience. CSS properties seem like a recipe for complex, how is SVG 2 going to avoid this, or is this not even a problem?
>> AMELIA: CSS properties. Oh, if you've got, like, multiple SVGs and then you're combining them all into one giant file, yes. That is something that you're going to have to factor in your build tool whether you want all those icons to be styled consistently or want individual control. Then, yeah, you're going to need a naming system and possible something in your build tool that will add extra prefixes to classes so that you can have honestly probably the best situation you have something that takes every class and gives it both as the common class name and as an icon prefixed one. So you can, then, target both ones in your CSS.
>> CLAUDINA: Cool. That's going to be a good thing. So what else besides gradients in your talk is super exciting to you, or another piece to get to in SVG 2?
>> AMELIA: I would have liked to talk about the SVG and open type fonts. There's cool demos out there. And as of August, they have been supported in Firefox for a couple years, now as of August in Microsoft Edge as well. A replacement for the old SVG fonts which are completely dead. They had many problems and browsers that supported them never supported the cool features. And support has been removed. But SVG and open type kind of combines the best of the SVG fonts with the best of all other font formats that are currently in active use. And sort of not a RetCon. A complete do over learning from the past mistakes.
>> CLAUDINA: I imagine you'll be around for the rest of the day.
>> AMELIA: Another hour or so.
>> CLAUDINA: Cool. If you have questions on SVG you know where to find Amelia. Let's give her a round of applause.
[ Applause ]
Also, if you don't know, the creator of SVG is actually here. So you can bug him too.
View Slides

Alisha Ramos

Coding is a Privilege

>> ALISHA: Thank you so much for having me. Can everyone hear me okay? See me okay? Okay. Awesome. Yeah. Thank you, CSS conference for having me. This is my first CSSconf and also my first time speaking at a conference. So
[ Applause ]
Thank you. As Claudina mentioned my name is Alisha Ramos. My talk is called coding as a privilege. So I work at Vox media as a design director based in Washington, D.C. Raise your hand if you have seen any of our brands. Oh, my gosh. Yay. So I don't have to do too much explaining. But we are basically a media and tech company and we own eight brands currently.
So before we get into it I kind of wanted to lay out my two big assumptions about you, the audience. The first is that I'm assuming that you care about diversity in tech. And the second is that I'm assuming that you're interested in doing something about it. So hopefully I'm right.
[ Applause ]
So today's talk, I'll be going over what diversity in tech look like, where we're at today, spoiler alert, doesn't look too good. I'll go over my own personal story of how I got started in tech. The big so what? Why should you care about all of this? And then lastly some simple tips on how you can help.
So this is the thesis of this talk. I believe that access to becoming an engineer should be wide and open to all. But today that's far from the case. And to start I want to demonstrate this with a metaphor, of course.
Swimming versus computer science. This is a photo of Simone Manuel at this year's Olympics. She came the first African American woman to win gold in swimming. In an interview Simone told the reporter that the gold medal wasn't just for me. It's for a lot of people who came before me.
So what exactly did she mean when she said this? Who was on her mind? Perhaps this image and these people were on her mind. This photo was taken in 1962 in South Carolina. It shows a public swimming pool that was closed by the city after four black males went swimming with their white companions. The ones that you see here. Their swim was a demonstration that became part of the civil rights movement efforts. With the passage of civil rights laws in the 1960s, public pools in the south like this one closed rather than integrate. Pools in fact north were drained of public funding that once kept them well maintained.
So you had demonstrations like these that fought for desegregated swimming facilities. The history of swimming in the United States has led to generations of people of color, African Americans in particular, being denied access to safe and adequate swimming facilities as well as swimming instruction. The history of swimming in the United States is simply put, one that's closely tied to racism and privilege.
And the consequences of that are simply devastating. According to statistics released by the CDC African American children and teens are almost six times as likely to drown in a swimming pool. Today 70% of black teenagers and 60% of Hispanic teenagers don't know how to swim. And if a parent doesn't know how to swim, it gets passed down too. There's only a 13% chance of their child learning how to swim.
So why am I talking about swimming in a talk about coding and privilege? Well, in preparation for this talk I read this really amazing book by Jane Margolis, a professor at UCLA. Stuck in the shallow end, education, race, and computing. She compares swimming with computer science and its effects on our society today. She and her team conducted research at three schools in the Los Angeles area with varying degrees of resources, funding, and student population diversity. They spent time in computer science classrooms and among students trying to better understand why is there such a stark racial and socioeconomic gap in computer science education? And these are the three types of schools that they visited.
And her findings showed a couple of things that all pointed to very clear what she calls race gap in computer science education. Many classrooms were technology rich but curriculum poor. They had all the technology, the computers, but they weren't getting the students weren't getting the instruction that they actually needed. Furthermore, only the wealthiest schools offered advanced CSS courses. And on top of that, only a few schools of color enrolled in them. Lastly, there were dangerous belief systems that the students had about themselves and the teachers had about their students and their abilities. And so from her findings she compares swimming with computer science. They're both something that people of color don't do. They're both associated with a certain type of person. And historically they also both began as a white dominated activity.
She concludes that the race gap in computer science education denies students a wide range of occupational and educational futures. And I actually thought this was worth keeping in because it's such a strong statement. It's not just affecting their present, but also their entire future.
So Margolis's research was conducted in the early 2000s. But the picture, unfortunately, isn't any brighter today in both computer science education and what we do. In the tech industry as a whole. Computer science is still missing from American education, as Brian mentioned earlier yesterday. By some estimates in the past year 75% of schools do not offer a single computer science course.
And as Margolis's research found, this was even worse for underrepresented communities. In 2015 only 22% of the students who took the AP computer science exam were girls. And only 13% were African American or Latino students.
And here's a look at the data for the industry in which we all work in as a whole. And it's worth noting that these numbers became transparent only recently. The sample average across top tech companies was that 7% of employees were black and 5% were Hispanic.
For women it falls lower. Black women were at 3% and Hispanic women were at 2%.
So why is there such a big gap racial gap in tech? Well, probably this answer. It's simply a pipeline problem. There's not no talent out there. Some background, the numbers are also throw. The percentage of black and Latino caps off at 4 and 2% respectively. When this data was released Facebook's head of diversity responded with the fact that there simply isn't enough skilled talent in the pipeline. Our students just aren't getting the computer science education that they need.
And there is truth to that statement as I went over earlier. Students aren't getting the computer science instruction that they need. But here's another statistic that's true. There are more minority students with engineering and tech degrees than there are jobs readily available to them. While blacks and Latinos earn nearly 18% of CS bachelor's degrees, they make up only 5% of the technical work force at top tech companies. And so we can see that broadening computer science education is definitely necessary. But it's only one part of the equation. There are so many other factors at play here that are keeping people of color and the underprivileged from working in tech and becoming engineers.
And so with that I want to pause with you and share my personal story. Because I've been technically writing code for eight years. But I didn't really consider myself a programmer until maybe two years ago. This is many when I was young. I'm the child of two first generation immigrant parents. My mother is from South Korea and my father is from the Dominican Republic. Growing up we made ends meet. We were never in poverty, but I do remember I never really had as much as my peers growing up. However, I was lucky enough to have a computer in the house. This was my first computer. I got it in I think 1998 was the year. And this opened a whole new world for me. I first learned HTML through this Website called Lissa Explains it All. I don't know if anybody else remembers that. It was run by another girl just like me and I loved this site and I would learn as much as I possibly could from it.
I created Websites about things that I was personally passionate about. I had many passions. Beanie Babies, Neopets, sailor Moon, dolls. These are sites I made in my teenage years. The left one is my live journal. As you can tell I really loved Lord of the Rings. Super obsessed. And because Brian shared with you his bad code from years ago I'll share this little snippet with you.
I had multiple style sheets and then in the markup I just dumped this. And had import ins on every line because why not?
And around the end of high school I stopped coding and designing. Because I never considered it to be a serious or lucrative career path. This was just a hobby I did on the side. And this graphic is a perception of what I had. And I'm sure my parents had. Of what a career in design and code would look like. I didn't know anyone who did this successfully for a living. I had no idea programming was a thing. Nevertheless a thing that I could do. So I stopped coding and I started spending time studying other things in school. Eventual all that studying paid off. I guess. Because I ended up get a full ride scholarship to Harvard, just across the river. But I still didn't know what I wanted to do in life when I got to college. So naturally I graduated with two degrees in sociology and medieval history.
Turns out those degrees aren't really the best for figuring out what you want to do in life either.
[ Laughter ]
Eventual I ended up taking a job that really wasn't meant for me. I worked at a consulting firm in New York and left after a year. And if you ever wondered what consulting is or what a consultant does, this is a pretty accurate depiction of it.
[ Laughter ]
So at this point I was kind of at a low point. I just left my job. Didn't know what I was doing. Trying to figure out what it is I truly wanted to do. So after some brainstorming I thought, hey, I used to make Websites and I really love that. I love designing code. And there's this new product design thing I'm hearing about. Maybe I can do that. But after arriving at that conclusion I felt a little stuck.
I didn't know how to start or what the right path was. I knew I needed to level up in design and code. But coding boot camps were way too expensive for me. The average cost for a bootcamp was $11,000. I was living in New York City. And attending a bootcamp would eat up all my savings and more. And so I researched as many free online materials as I could. And I'm sure this resonates with a lot of you and I taught myself for a few months.
After a few months of learning on my own and building a portfolio, which if you have questions about I'm happy to answer. I was finally employed as a designer and a coder what I really wanted top. And something really nice happened. This is a chart of my salary increase when I went from consulting to frontend designer. The actual value is obviously not shown. But that's about a 60% increase in salary 60%. It's supposed to play video. This is my reaction. I asked myself, why didn't I know about this sooner? Right? My whole life changed. I was able to pay off my debt, my student loans. I took my family on a nice vacation which we never did growing up. I finally felt comfortable financially.
And my story is not the only one. The average salary of a tech worker is more than the median household income of a black and Latino family combined. This is significant when you consider the existing racial wealth gap in our country. Which is huge. The average net worth of a white family is 15 times that of a black or Latina family. And so this kind of transition into tech can be transformational. The tech sectors high salaries and high demand for employment provide an opportunity for underrepresented communities to build generational wealth. And can help close that massive wealth gap.
And so the opportunity is huge. A little after I was employed I asked myself, if it took me this long to figure out my path to coding, what must it be like for people who are less privileged than I am? Because after all I didn't have the cushiest of childhoods. But I had privileges. I had a computer, I had an Internet connection. Supportive parents. I went to a good school. I had all of these things that made me feel very lucky. But what about others who aren't as fortunate as I was or as fortunate as maybe you were?
And this is really central to why I'm giving this talk. For myself coding has meant mobility and freedom. Part of me wants to give this gift to everyone. Every student, every person who feels that they're stuck. Being a developer is a position of privilege. But privilege should not be the only path to becoming one.
[ Applause ]
Thank you. As Jane Margolis put it in her book, computer science can break the cycle of inequality. The opportunity is huge, but there are many obstacles in the way for a whole sub set of the population. You might be thinking, but wait! I learned to code for free and so did you. All you need is a computer and an Internet connection, right?
This is the response I get quite often when I make the case that coding is a privilege. This person who some of you may recognize Tweeted this out in response to my original essay on the topic. He thinks it's just a matter of putting your rear in a chair and writing code.
So I want to take a brief detour and talk about the difference between equity and equality. Because there is a difference. It's not just a matter of sitting down and writing code. We must all have the same foundation first. But the reality is we're to the all on an equal footing. Some of us enjoy some combination of racial privilege, socioeconomic privilege, male privilege, religious privilege, the list goes on. So while coding free coding materials may have gotten you participate as an individual, it's important to realize that there are many other factors at play here.
So you might be wondering at this point, okay, so what? Why should I care? Why am I listening to you talk about Diversity and access. I'm here to learn about CSS. And I understand. Let me tell you why you should care. Understanding our own privilege ultimately means allowing for more diversity and more voices in the room. And this isn't just good for society. Increasing diversity also means better business results too. MacKenzie conducted a research study that companies in the top quartile for racial and ethnic diversity are 43% more likely to have financial returns above the respected medians. Better business results. You have to have diversity. Who doesn't want that? Increasing diversity in tech is also the more realistic thing to do. Recent projections suggest that by 2040 non whites will form the majority of the American population for the first time ever.
Wouldn't you want to work force that reflects the consumers you're trying to reach? And now let's look at the flip side of things. As Yvonne Hutchinson wrote for the MIT tech review, companies that lack diversity risk building products that exclude their customers. We're in Danger of building products and services that are biased by design. There are just a couple of recent examples from the news and I'll go through a couple of them.
A recent study found that Airbnb guests with African American names were 16% less likely to find lodging. Snapchat has had a couple of stumbles recently. When it came to releasing racially offensive filters. Such as this questionable filter shown here that resembled yellow face. The app Next Door had rampant racial profiling in the crime and safety reports feature. Users of the app were reporting detailed descriptions of someone, including race, but failed to describe them doing something actual criminal.
It's not a silver bullet, but I wonder how this bias may have been avoided or caught early on if these companies had diverse voices on its team able to call out this bias. On the flip side, with more diversity in tech we can all help create better products that work for everyone. This is an amazing app created by Vox called Tonr. Instagram has filters that whitewash the skin tones of people with darker skin tones. It's an Instagram like app that has filters to compliment skin tones rather than brightening or whitening them. This is a really neat app that you can actually use today.
Tristan Walker built Walker and Company to address the needs of people of color in a growing beauty and grooming market. He's found great success by addressing specific needs of this very underserved market and has raised over $30 million in funding to tackle this problem. You can see there's benefits to increasing access in tech to all people. We end up creating better products that way that everyone can use.
So now to share with you eight simple quick tips on how you personally can help make coding and a career in tech more accessible. Tip number one. Support the computer science for all movement. As we have seen computer science education is not open to all. And there's a looming race and socioeconomic gap in our public school system. Two weeks ago the White House announced a CS for all consortium initiative, which is a network of computer science education providers, schools, researchers, all working to support the mission of expanding access to computer science education. So if you go to this Website you can click get involved and find some ways that you can possibly help.
Tip number two, this is my favorite because it's probably one of the most impactful things you can do as an individual is to find volunteer opportunities. This is a list of just some organizations that are doing the work. There are many out there and the number is growing. And I have a GitHub repo if you're interested in accessing the full list or if you want to add more to this list.
You can do a lot of things for these groups. You can volunteer as an instructor, you can help define curriculum if you're interested in that. Or if one of these organizations doesn't exist yet in your area, which a lot of them are geographically very much geographically focused for now, maybe you could help start one in your local city.
Tip number three, if you're a woman, a person of color or a member of some other underrepresented group, making yourself visible as a role model and available as a mentor can go a long way. This can mean different things. If you don't feel comfortable being on platforms like Twitter, try starting small. Like visiting a classroom in your city to inspire students. Because as you know the images that we see in media today that represent tech look like this. And they are pervasive in our culture. They exacerbate stereotypes about what tech is about and who belongs in tech. By make yourself more visible, you can help inspire others.
Tip number four, grow your networks to include people from underrepresented backgrounds. And this is something that I think everyone can do. If you have a Twitter account. These are some lists on Twitter that are pretty easy to follow. This one is called women who code. It's a list compiled by John Resig. This is seriously one of the most hilarious lists of people I follow. Not only are the women so smart, so on top of their game, but they make really good jokes too. That's what Twitter is for, right? Jokes.
D.C. tech ladies is a good one. I'm sure wherever you have there are probably local lists of people to follow as well. Quick shoutout to women of color in tech chat is a great community providing more visibility and support for women of color in tech.
And quick aside, growing your networks in this manner by doing so we expose people or we expose ourselves to people and communities we otherwise would not interact with. And this can lead to awesome effects in your hiring and recruitment. Many companies and employees look inside their own personal network of friends first when looking for job candidates. Because, you know, that makes sense, right? You trust these people. While this can work well in some cases, the flip side of this is that you're going to miss out on a whole pool of candidates out there who aren't in your network.
So growing your network is a really great way to ensure that you're reaching a diversity of communities and finding the best candidate. Tip number five, help create a safe and inclusive environment at work. It's not just a matter of getting people in the door, it's also keeping them there and making them feel safe and welcome like they belong. This is an example from my own team. The product team at Vox Media. We recently released a code of conduct that's online and it's open sourced. As my co worker Mandy Brown wrote, we created this because we truly believe that a strong pipeline is worthless if it leads straight into the sewer. We wanted to not only create
[ Applause ]
We wanted to not only create a safe and inclusive environment for our teammates, but also this is a really great way to show the world that your values are as a company too. We want to show that we are serious about diversity and inclusion and that we're not just talking the talk, but we're also walking the walk.
One other quick tip I want to share with you in terms of interviewing is to re evaluate what cultural fit means in your interview process.
[ Applause ]
Should your next hire really be someone that you want to grab a beer with? Or should they simply be someone who can bring unique value and skills to help make your company better? Just think about that.
Tip number six, lend your visibility. Have you ever been asked to speak at a conference or a panel? Are the speakers there not diverse? You one thing you can do is offer to step down and instead volunteer the name of someone else who may have less privilege than yourself and who would really appreciate that platform. So the next time you see the panel of all white men, yeah, do that.
Tip number seven, support others who are just starting out. When I was just starting out I wanted to feel welcomed in the community. And like I belonged. Also I had no idea what I was doing. And I want to learn as much as possible from people with more experience. So quick shoutout to this really great diverse community called CodeNewbies that's filled with driven people just starting out. A lot of them often ask for mentorship. Or you can offer to hold office hours. It's a wonderful community and it's very diverse.
Last, but not least, tip number eight. Become aware of your own privilege and unconscious bias. Because guess what? Everyone in this room experiences unconscious bias. Myself included. It's how our brains are wired to survive in the world. Our brains have to process millions of pieces of information every day and second. Luckily our brains have evolved to the point where we can make split second decisions based on prior experience and knowledge.
This is helpful for us when you have to remember facts like two plus two equals four or that if you see a lion charging at you, you should probably run.
Unluckily our brains have also been conditioned with cultural stereotypes as well, regardless of whether or not you believe the stereotypes to be true. If you have some time, I encourage you to take this test, the implicit test, implicit.harvard.edu. Testing your implicit bias. It's by researchers at a few universities. The results might surprise you. There are a couple one you can take. But the most famous one is the race IAT test. Luckily we all experience unconscious bias, but we can have some strategies and manage that unconscious bias. This is a really great white paper from a firm called paradigm called managing unconscious bias. And nay offered some really great suggestions on how to deal with this. So some things that they mention are spending time with people from different backgrounds or exposing yourself to them. And setting data driven tools and processes, especially when it comes to things like hiring or promotions.
Coding is a privilege. Having access to a career in tech is a privilege. I hope my talk has opened your eyes to the many ways in which underrepresented and under resourced people face barriers to careers in tech. How you can help and why it matters. We must all become aware of and work together to remove the barriers so that we can create a world where everyone can enjoy equal opportunity and thrive.
As Jane Margolis puts it in her book, providing access to computer science and careers in tech is a civil rights issue for the 21st century. And I can't agree more. The opportunity is huge.
This work that we do, the products that we build, the CSS that we write, can be life changing. It's on us to work together to make sure that no one no community of people is stuck in the shallow end. I hope you agree too and can find some ways to help. Thank you.
[ Applause ]
>> CLAUDINA: So good. So good. Such a great way to end this conference and such a necessary way. I actually like I had to bring this napkin because I started tearing up when you were talking. And I'm probably going to cry up here.
>> ALISHA: Oh my gosh.
>> CLAUDINA: Because this is such an important issue. And I want to thank you for being so honest and true in telling your story. Thank you so much.
>> ALISHA: Thank you. Thank you.
[ Applause ]
>> CLAUDINA: And you are half Dominican. I am too. Yes. All right. So when these tears go away I might be able to ask some questions or have a dialogue. So much of what you said I was line, yes. Yes. You touched a little bit on your code conduct which is a way that Vox created to have a safer and more inclusive space. What are you doing to increase your pipeline, not only diversify the people, but keep working at Vox longer?
>> ALISHA: That is a great, great question. So one other thing aside from the code of conduct that we've done is try to be transparent about our own diversity numbers. And that just kind of helps keep us it helps keep us accountable. So if you go to our site now under our careers section there's actually a diversity tab that shows you not just what our current diversity numbers are, but also the evolution of our numbers. So if you look at I think it starts at like 2008 our numbers were really bad. They are still not super great. But it's really neat to see the bars going up and up and up. And internally our leadership supports diversity which is really important. A lot of companies don't have that. And I feel lucky to work at a place where our CEO and leadership actually take this seriously and mean it. And we've also hired people whose work this is like their job to think about these issues. Because this is real work. It's a lot of work. It's hard work. So I'm really glad that Vox has been able to put money where their mouth is and hire the people who understand these issues best. Because it's very complex and it's really difficult.
>> CLAUDINA: Absolutely. And to also be so transparent about it. Because I feel I mean, I can, the company I'm at right now, I can imagine. Well, here we are at zero, right? And that doesn't look good. But I've heard from many underrepresented folks that even just that honesty and the showing and is what really compels them to be like, yeah, if you're going to be honest about it. I know I can come.
>> ALISHA: Even if your company is at zero I think personally that you should make that transparent as long as you pair it with we know this is a problem and we are going to do something about it. So be honest with yourself.
>> CLAUDINA: That's great. Are there ways that even at Vox, or you when you're speaking with people like kindly call people out when they're saying things that are perhaps not so inclusive? Or let's say four more white male hires came through the door, what do I do? Do you have any suggestions for that?
>> ALISHA: So things will happen in the moment. So our code of conduct kind of lists out as an employee of the company here are those steps that you can take. Usually it comes down to, like, if you don't feel comfortable approaching someone about a specific thing that they said you can always talk to their manager about and it will be dealt with. In terms of hiring, if we hire four males, that's fine. But I think what matters is your process should be as diverse and inclusive as probable. If you're bringing people in to interview, make sure that you're like if you have like a lunch date planned with that person make sure that they're being exposed to diversity of employees at the company so that on both sides they can see what they're getting into. And then on the other side of things a diverse number of people can help vet the candidate.
>> CLAUDINA: Can you share a bit about Vox's hiring process and how it's been designed to help with diversity and inclusivity?
>> ALISHA: It's changed so much. I don't know if I can talk about it officially because I'm no longer super involved at that level. But I can say about a year and a half ago one tactic that we had was we started a spreadsheet of all these different diverse communities that our own employees were a part of. So like I'm a part of this group called D.C. Femme Tech. Hear me code. We have our listservs. Each time a hiring manager would put up a new job, hey, I saw on the spreadsheet you're a member of this diverse community. Would you mind forwarding this out to the diverse group of people? Which was great. We were posting to the usual suspects. And those usual suspects tend to have a very homogenous group of people looking at the job descriptions.
So it helps to mobilize your own diverse employees in spreading the word to their own networks going back to the point about growing your networks.
>> CLAUDINA: That's so crucial. Very, very interesting. Wow. Well I could keep going on and on and on and on with questions as you can tell. This is something so near and dear to my heart. But I know that they want us to take a family photo. So, I mean, this is an incredible first time speaking. First time speaking, everybody.
[ Applause ]
I truly and continue to give this talk.
>> ALISHA: Thank you so much. I will. Thank you so much for having me. You guys were great.
View Slides

The Venue: Laugh Boston

We had such a good time at Caroline's in 2015 that we're continuing the tradition at Laugh Boston ! Opened in 2013, this state of the art standup comedy theatre will be our home in Boston's Seaport district, footsteps from downtown.

Live Transcription

As part of our commitment to accessibility, we're bringing real-time transcription ( CART ) back to CSSConf! We'll be working with White Coat Captioning to provide a live feed of every word of each talk.

Real-time transcription of talks enhances the CSSConf experience for everyone, whether they're a person with a disability, a non-native speaker, or someone who just wants to follow along with the talks, but gets distracted looking at one of the speaker's links!

In addition to presenting the transcription live in the conference room, we're streaming the transcription live here during the conference!

Lunch

We learned very quickly that we couldn't match the level of great food that's within walking distance of our conference venue, so we dropped the cold-cuts and mini-plates in favor of an hour-and-a-half block for you to head out to some place close by with friends old and new!

Here's a non-exhaustive list of ideas, but explore the neighborhood to your heart's (and stomach's) content. Just don't go to the same place as everyone else! All are within about a half-mile of Laugh Boston, and can should be able to get you fed and on your way in time.

Diversity Scholarship

We are constantly seeking ways to make the web development community broader and more inclusive, and our Diversity Scholarship program, which covers a full CSSConf ticket as well as travel and hotel stay in Boston, is an important part of that effort. The scholarship is open to people who self-identify as part of any group that's under-represented in technology. We invite you to learn more . The application period for the 2016 conference has closed.

If you want to help us extend the reach of this program, you can get the word out to groups and people who'd be interested in applying and attending, or your company can sponsor additional scholarships .

Learn More

Sponsors

Sponsorship

CSSConf 2016 is a great opportunity to meet and get to know hundreds of the world's top CSS and front-end developers. Whether you're looking to hire developers, promote your product, or just give back to the community, this is the place to be. Get in touch with us to get involved.

Learn More Reach Out

Code of Conduct

We believe that everyone deserves a thoroughly pleasant conference experience, regardless of who they are. We adhere to the Bocoup Code of Conduct and expect that all of our speakers, attendees, sponsors, and volunteers will do the same.

Learn more