Sara Soueidan

Follow this blog

Design for reading: tips for optimizing content for Reader modes and reading apps

Our content will not always look the way we expect it or want it to. Many apps, tools, and environments that people use to browse the Web strip our content of our CSS and apply their own styles to it. And unless we always keep that in mind, we risk creating incomplete or even broken experiences for users of those technologies or tools. You might be reading this very blog post in a reading app right now, or maybe even listening to it being read out loud to you. In either case, the visual style enhancements I have applied to the content don’t really matter much anymore. My CSS isn’t enhancing your experience. My content—the HTML markup—though, defines your experience and can either make it or break it. Reader modes and Forced Color modes are two common environments where content is typically stripped of our CSS. So a question I think we should constantly be asking ourselves is: Is our content still understandable without CSS? Or are we relying too much on visual styles to put ideas across? Does the HTML layer alone provide a decent and sufficient experience to our users? Is our CSS truly the enhancement it is meant to be, or are we relying too much on our own preferences rather than our users’ to communicate our ideas? The more I consume content in reading apps, the more I am reminded of the importance and the power of progressive enhancement as a strategy to create resilient and malleable experiences that work for everyone, regardless of how they choose to consume our content. The more we think about the Web in layers, the more robust experiences we can design. Designing for reading, there are a few things we can learn and do to improve our users' reading experience (and other users' experiences as well!): 1. If your idea requires CSS to visualize, provide a markup-only alternative. In my previous article about creating creative yet accessible horizontal rules, I discussed how I created the birds-on-a-wire horizontal rule style that I use on this Web site. After the article’s introduction was a horizontal rule, and a paragraph that read: If you’re a frequent reader of this blog, then you’ve most likely already seen what a horizontal rule looks like on here. In fact, if you haven’t seen it before, then you might have just done that. The birds-on-a-wire illustration above this very paragraph is a styled <hr> element. The horizontal rule above that specific paragraph was sort of as a “live demo” for the ideas and code discussed in the article. That horizontal rule is styled in my style sheet to look like a bunch of cute birds on a wire. Knowing that some readers will be reading the article in an RSS app or even their favorite browser’s Reader mode, I provided an alternative or “fallback” piece of content that would only show up for said users when my own CSS is stripped away. In Reeder app, horizontal rules are displayed as plain horizontal lines, so my “live demo” would not be accessible to them. As such, I’ve provided alternative text that reads: "If you're reading this article in a reading app or a Web browser's reader mode, then the above horizontal rule will not appear with my custom styles applied, and you'll just see a horizontal line. Here is a picture of what the horizontal rule looks like". The paragraph is followed by an image of the birds-on-a-wire horizontal rule style. Notice how in the screenshot the reader-only piece of text appears in an Italic font style. Using the emphasis HTML element I am able to visually distinguish that part of the article from the surrounding text in the reading app. Yes, my readers could easily just click through the article’s title and check the horizontal rule styles on my Web site, but they shouldn’t have to. They shouldn’t have to switch contexts just to check out a visual style that I can easily provide them with inside their preferred reading environment. Today, inside my global utilities style sheet, I have a reader-mode-only utility class (that I will probably rename later to something more generic). I use that class to provide alternative content to my readers that would otherwise require my CSS to be understood. That content would always be present by default when my visual styles are not. And when the content is accessed or viewed in an environment where my CSS is used, the reader-mode-only content is hidden with a simple display: none;. The idea here is to improve the user experience. This technique should never be used to shove unwanted content (such as ads, ugh!) down our reader’s throats. I know we’d ideally want people to come visit our sites, but we should respect their choices, especially since our design choices might be questionable—are we presenting too many distractions on the page? are the fonts we’re using unreadable? is the text contrast sufficient? There might be many reasons why our readers might prefer reading our content in Reader modes. Instead of questioning our user’s preferences, we should reconsider our design decisions. Or not! Many people—myself included!—use RSS because it’s a very convenient way to stay up to date with content. The fact that our readers are subscribed to our blogs is but a greater incentive to make sure we provide them with the quality content and experience that they are expecting from us. And if you do have unwanted elements showing up for them when they shouldn’t, make sure you “clean them up”. More on that in the third section. 2. HTML is for content. CSS is for visual styles. Keep content where it belongs: in the markup. I was reading through a Smashing Magazine article in Reeder app when I reached what seemed like a sudden change of topic in the middle of the article. What read as part of the article was actually not. What I’m referring to is Smashing Magazine’s custom “ads” (or content callouts) that appear in the middle of each of their articles. These custom ads/callouts that highlight Smashing products typically appear in the middle of an article. With Smashing’s CSS applied, this section stands out from the rest of the article, and is preceded with heads-up text that says More after jump! Continue reading below! ↓. These styles make the callout section distinguishable from the rest of the article, so you can easily skip over that section and continue reading the article without your focus being affected much. In Safari Reader Mode, however, the experience is not as subtle. The heads-up text that precedes the callout section is not real text. It’s pseudo-content—literally fake content—created and added to the callout section via CSS using a ::before pseudo-element. And since Reader Mode strips the content of CSS, that piece of text is not rendered, and the callout section no longer looks like a callout section. Instead, it just appears in the middle of the content as part of the content and interrupts the reading flow. It's worth noting that I noticed this issue while browsing and reading Smashing articles in Reeder app more than a year ago. But the callout section no longer shows up in Reeder app. I'm not sure why that is. That's why I am using Safari Reader mode to demonstrate the issue. Similarly, the Summary section at the beginning of the article has a “Quick Summary” label that is also generated in CSS. Below the summary is what looks like a horizontal rule separating it from the rest of the content, but that rule is actually just a bottom border style applied to it in CSS. Both the label and the summary disappear in Reader Mode and reading apps. em element) to suggest that it should be.) In order to ensure readers always get a proper reading experience, provide real content in HTML, and leave CSS pseudo-elements for decorational content that is not required for the core reading experience. You may have noticed something else happening in the last screenshot: instead of starting with the core content of it, the article starts with the (truncated) author bio. The bio clearly does not belong there, and yet there it is. Furthermore, the callout section—which is essentially an ad section—also does not belong in a distraction-free reading environment. The main reason people use reading apps and Reader modes is to “declutter” the UI so they can have a “quieter” and more focused reading experience. We can do better to improve their experiences even further with just a tiny bit of HTML sparkle. ✨ 3. Keep the core experience clutter- and distraction-free: Hide non-core content by default and show it with CSS when it’s OK to do so. The reason the author bio and callout sections are displayed even in Reader Mode is because they are markup up as part of the main <article>. Reader Mode is meant to strip away all parts of a document and only present an article’s text and basic images in a clean and uncluttered format, to improve the user’s reading experience. In order to do that, Reader looks for content within an <article> tag, and displays it. (Note that if Safari does’t find content represented within the proper HTML elements, the Reader Mode button doesn’t even show up at all.) “It’s important to ensure that Reader draws out the key parts of your web page by using semantic markup to reinforce the meaning and purpose of elements in the document […] we indicate which parts of the page are the most important by wrapping it in an article tag. Specifically, enclosing these header elements inside the article ensure that they all appear in Reader” – https://developer.apple.com/videos/play/wwdc2018/239/ If you View-Source on Smashing Magazine articles, you’ll find that the author bio and the callout section are both included in the main <article> wrapper. And that’s why they show up in Reader Mode. I've noticed some inconsistencies in the way Reader Mode displays article content, even within the context of the same Web site. For example, not all content inside an article is displayed in Reader Mode. For example, the article meta information doesn't show up even though it's part of the article. Moreover, The drop caps illustration would sometimes show up and other time it wouldn't. I'm not sure what the reason behind that is, and why some elements show up and others don't. If you can move content such as author biographies, ads, and other pieces that are not part of the article’s core content out of the article, then do so. This will ensure that they don’t show up and clutter the user’s reading experience in Reader Mode and some reading apps. If you can’t move the clutter out of the article, you can hide it from Reader Mode using the HTML hidden attribute. The hidden attribute is the HTML equivalent of CSS’s display: none. You can use it to hide content when CSS is not available. It comes in handy in a lot of scenarios which I will detail in another article. But for now, suffice it to say that by hiding the non-core pieces of content with the hidden attribute, you are making sure that they are hidden even in environments where your CSS doesn’t work and they shouldn’t be present. Since the hidden attribute has a very low specificity, you can override it in your CSS using a simple display: block/flex/grid/etc.. So, when your reader is accessing and reading your content on, say, your Web site, you can display those elements and style them in a way that does not negatively affect their reading experience. Flexbox is used to lay out the contents of the Smashing callout section. So the hidden attribute can be applied to the section in the HTML, and it can be overridden in the CSS with a display: flex. Here is a video recording of me first applying the hidden attribute to the callout section in Safari’s Reader Mode. You can see that the section is removed as soon as the attribute is applied. When the CSS is enabled, I re-apply the hidden attribute, thus hiding the section once again. Then, I apply a display: flex to the section in the CSS panel, which overrides the hidden attribute and shows the section again with the necessary styling applied to it. Sorry, your browser doesn’t support embedded videos. By leveraging the nature and weakness of the hidden attribute—by using it the way it was meant to be used—we can drastically improve our user’s reading experience in their preferred reading environments. Outro We have a tendency to always make an assumption about how our readers are reading our content—probably in the browser, with our fancy styles applied to it. But if we make a habit out of thinking about the Web in layers and CSS as an enhancement on top of the content layer, then we can start optimizing and enhancing our users' reading experiences regardless of their context. Thinking about the different ways in which users access the Web only shines light on the importance of a progressively enhanced approach to building for the Web. The more we think about the Web in layers and try to improve the experience of one layer before moving to the next, the more resilient experiences we can create. That’s what the essence of progressive enhancement is about. HTML is powerful as it is. And if marked up right, it forms a solid foundation for a more inclusive and resilient Web. CSS is a fantastic tool that enables us to further enhance an experience on top of HTML, so long as our design decisions don’t break HTML’s inherent semantics and accessibility. The hidden atribute is one of HTML’s underrated features. I’ll dive more into it and demonstrate more practical use cases for it in an upcoming article. Stay tuned. And thank you for reading.

Component-level art direction with CSS Container Queries

Container Queries (CQ) allow us to change the styles of a component so it responds to the size of its nearest container. With CQ, we can change how an element looks based on where on a page it is placed and how much horizontal space it occupies. A lot about a design pattern could change based on how much space it’s got. So Container Queries can be used to do more than just shift elements around in a layout. (Have you seen Jhey’s demo yet?!) But we can only take full advantage of the potential Container Queries offer us if we can use them everywhere a typical viewport media query can be used. Now that we got Container Queries in CSS, I want them in HTML, too. More specifically, I can see them coming in more handy if they were available in HTML to change an image’s source inside <picture>, just like viewport-based media queries currently are. This would enable us to art-direct images instead of cropping them to fit in a layout. Images are typically designed to adapt to layout changes much like other UI elements are. It’s possibly even more relevant for images to change with a layout than other UI elements because of their nature as replaced elements. Take the typical card component for example. Assuming the card’s layout doesn’t change, and assuming the image will always be stacked on top of the content, then it’s usually a good idea to change the aspect ratio and orientation of the image between narrow and wide layouts. A landscape photo might look good in a wide layout, but a portrait photo would suit a narrower layout better. Using a combination of object-fit and aspect-ratio today, we can fit any image inside a container with an aspect ratio that we specify in our CSS. And with container queries at hand, we can create a more flexible implementation, where the image adapts to the size of the card itself, independent of the size of the viewport. This is already a big improvement to the viewport-based implementation. Using the aspect-ratio property in the following demo I have changed the aspect ratio of the image based on the width of the card component. And object-fit is used to crop and scale the image to fit within the bounds of its container in all three cases (because the default aspect ratio of the image doesn’t match any of the aspect ratios I’ve specified in the CSS). See the Pen MWpwvbB by Sara Soueidan (@SaraSoueidan) on CodePen. Since the demo is using Container Queries which are currently only supported in Chrome Canary behind a flag, you may only see one aspect ratio on all three card variations. Here is a screenshot of what the image looks like for 3 different card widths: This is a pretty flexible approach for adapting images in card (or other) components. It is particularly useful when we’re dealing with images that a user might upload via a CMS and whose aspect ratios we don’t know. Specifying an aspect ratio in CSS and cropping and scaling an image to fit within it is a solid approach to handle such images. But cropping and scaling an image is not always the best approach, though, because not all images can or should be cropped. Sometimes cropping an image straight-up ruins it. Take a portrait of a person, for example. Cropping it to any aspect ratio other than the one it was taken in would ruin it. And yet on the other hand, keeping the default aspect ratio might not be possible because of design and layout requirements (e.g. the image needs to be one in landscape mode in wider layouts otherwise it would be too tall). So if we have control over what image(s) to use, the better alternative is to use is to change the image entirely in this case. If I were using a portrait of a person on the site, I might want to use two different shots of that person—one for landscape and another for portrait layouts. To switch between different images we can use the HTML <picture> element. There are many ways <picture> can be used to serve responsive images. For art direction, the syntax might look like this: <picture> <source media="(min-width: 1024px)" srcset="desk--wide.jpg"> <img src="desk--portrait.jpg" alt="My desk setup"> </picture> You can see the above code in action on my Desk page. And here is a screenshot of the Desk page showing two different photos of my desk setup on narrower and wider screens: Accessibility considerations: We currently don't have a way to change the content of the alt attribute when the image source changes. Or, if we look at it differently, we don't have a separate alt attribute for every image source we define in our <picture>. So if you're changing the content of the image, you need to keep that in mind. If your art-directed image is pure decoration, or if your image layout changes (landscape to portrait) but the core of the content is the same, then this shouldn't be an issue. But keep in mind that you may want to avoid art-direction if the content of the image changes and it doesn't match the description provided in the alt atribute anymore. But here’s the thing: the images you specify in <picture> respond to the size of the viewport, not the component they are embedded in. The image on my Desk page changes when the size of the viewport hits 1024px. And that’s fine for this particular use case. But if we’re art-directing images inside components, we’ll want them to respond to the component’s size, not the viewport. After all, this is the kind of responsive behavior that we’ve needed for so long and that Container Queries now provides us with. The next step is, hopefully, Container Queries in HTML. Update: It has been brought to my attention shortly after publishing this article that this features request has been made and discussed back in January. For more information about the discussion involved in making something like this work (or not!), refer to the open issue on Github. There is a way we can currently use Container Queries to art direct images in a component, but those images would need to be embedded in the CSS, as background images. .card__media { aspect-ratio: 2 / 3; background-image: url("https://assets.codepen.io/9674/desk--portrait.jpg"); background-size: 100% auto; } .container { contain: layout inline-size; } @container (min-width: 480px) { .card__media { aspect-ratio: 16 / 9; background-image: url("https://assets.codepen.io/9674/desk--wide.jpg"); } } In other words, the images need to be non-semantic, decoration images. If your image is part of your semantic content, it can’t respond to the container query just yet. And of course, since the image is a background image, we’ll need to use the aspet-ratio on the element that image is applied to, otherwise it would collapse. Here’s a live demo again using Container Queries, so it will only currently work in Canary: See the Pen Component-level art-direction using CSS Container Queries by Sara Soueidan (@SaraSoueidan) on CodePen. And a screenshot of the result: Final Thoughts We’re only scratching the surface of what Container Queries make possible. I can imagine Container Queries coming handy even in quick prototyping-in-the-browser work, as well as more specific use cases. And I’m sure more smart people will come up with even more use cases as they push the limits of what’s currently possible. Let’s continue pushing the Web forward.

Working around the viewport-based fluid typography bug in Safari

I came cross a CSS bug in Safari today that seems to be more commong than I expected. This article is a writeup of the issue I faced and the current possible work-around(s). Note: Less than 72 hours after I wrote this article and filed the bug report, the issue has been marked as resolved fixed! So you can expect this bug to disappear in upcoming releases of Safari. 🎉 The bug Jan Persiel—who I’m currently collaborating on a client project with—reported that the type scale we have set up in our pattern library was not working the way it is supposed to. More specifically, in Safari on macOS, the fluid text wasn’t really fluid—resizing the viewport did nothing to the font size, even though the latter is supposed to respond to the change in viewport width. I am using a fluid typography system and scale that I’ve been using for almost two years with no issues to be mentioned. Instead of writing it from scratch like I did for Prismic’s Slice Machine in 2019, I generated the CSS code for the type scale using the excellent Utopia generator. So I was perplexed at first, unsure what was happening. Following is a Codepen including a reduced test case. Open this demo in Safari and try resizing the browser to see the text not respond to the viewport width changes. Safari Viewport-based scalable typography... bug? by Sara Soueidan (@SaraSoueidan) on CodePen. Unsure what was causing the buggy behavior, I started double-checking my own code at first, making sure no weird syntax issues were in the CSS file. I kept checking and tweaking stuff, but nothing worked. So I started googling. I came across this article on CSS-Tricks from 2017 about creating fluid typography using Mike Riethmuller’s responsive type formula (which I believe is the base of all fluid typography formulas we know today). Reading through the comments I found Mike’s comment in which he noted that there’s a bug in some versions of Safari (and IE11) that means it won’t be calculated on resize. Similarly, Chris had also mentioned the same buggy behavior in another article from 2012 (!) (emphasis mine): When the browser window is resized, the font doesn’t adjust itself according to the new viewport size. [..] Perhaps not a huge disaster as it’s pretty much just us design nerds that go around adjusting browser windows, but still. The font does adjust on a fresh page load. Indeed, refreshing the page on different viewport sizes would render the text in the font size intended for that viewport size. But that was not enough. It was clearly a bug, one that has been reported and supposedly fixed. The workaround Responses to the comment on the first CSS-Tricks article included a few “fixes” to work around the buggy behavior in Safari. And Chris also mentions in his other article that causing a repaint on the element (using jQuery in his article) would help “fix” the issue. I tried all of the workarounds mentioned. The only one that worked for me was the “font-size: 1vw on the parent hack”. I set the font size to 1vw on the root element. That did make the text size respond to viewport size changes, but it had a clear and obvious side effect on the size of the text across the pattern library. What I ended up doing is setting min-height: 1vw on the body element, which should be enough to cause a repaint but have no side effects on the remaining styles whatsoever: body { min-height: 1vw; } Note: After filing the bug report, I learned that this buggy behavior is exclusive to viewport units used inside calc() functions. So even though the above fixes for the previous bug work around this one too, the cause of the issue is different in this case. A better workaround targeting Safari only Unsurprisingly, I’m not the only one who has come across this buggy behavior. Folks on Twitter responded to my tweet reporting that they have had the same issue with their responsive type scales in Safari. Among the replies to my tweet, Martin Auswöger suggested a smarter way to “fix” Safari’s bug using the (currently Webkit-only) -webkit-marquee-increment property. By setting the property to any value using vw as a unit, the text would scale again on resize. Martin was kind enough to create a reduced test case that I included in the bug report I filed. Here is the demo including Martin’s fix: See the Pen Reduced test case + workaround for Safari's fluid typography bug by Sara Soueidan (@SaraSoueidan) on CodePen.

🛠 Redesigning and rebuilding my Web site from the ground up

It’s about time my Web site got a complete makeover. It’s going to be more than just a fresh coat of paint. It’s going to be a complete rebuild + redesign. I’m going to rebuild this Web site from the ground up, starting with a fresh, clean slate—an empty repository, with nothing imported from the old one other than some content, such as my blog posts, list of past speaking engagements, and smilar content that will not change in the future. And some images, of course. OK maybe a few other content elements. But you get the point. A new start. A new Web site. Why start fresh? Because I haven’t updated the code on this Web site in years. I’ve been teaching best practices in front-end development for years, while also letting my Web site fall behind on all of them. I haven’t been making time to update this site much aside from adding articles and speaking engagement updates. My first CSS Grids application was on this Web site when CSS Grid was still a new technology, not yet supported by all browsers. That was probably the last major CSS update I did on this site. Refactoring the current code would take more time than rewriting the whole thing from scratch. The markup needs a fresh start. So does the CSS. And I like fresh, clean starts. I enjoy starting from zero. And I feel like the site is at a point where it would benefit more from a clean start than a refactor. But why am I writing about this? Why didn’t I just rebuild and redesign this site and just deploy it live, announcing the update when it’s done? Because this time around, I am going to go about doing that in the open… The (Open) Plan I am going to rebuild this Web site in public. While I do that, I will be documenting the process of building it from scratch, sharing a behind-the-scenes look at my work. If you follow along on Github, you may see this Web site come to life one small feature at a time. One small piece of code at a time. I have a plan for how I’m going to approach doing it in a way that works for me, and is a little more useful for anyone who follows along. Why? For no reason other than trying out something new. And several people have expressed their interest in my dev process. While I do feel nervous about it, I think the benefits of doing this in the open outweight the disadvantages. The new site will live in its own new repository, separate from the current Web site’s repository. While it is work in progress, it will live on sarasoueidan.dev. So this Web site you’re on right now will still be here while the new one comes to life. Once the new site is done, it will replace this one on the dot com domain. Timeline Since the current site will be live throughout the entire process, there is no pressure to get the new site done quickly. I will dedicate a few hours per week, mostly over the weekend, to work on it. I don’t have a deadline in mind. And I don’t want to create a deadline because I don’t want this work to affect the time and effort I dedicate for my client work. So, no pressure on what will be finished when! It may take a couple of weeks or a couple of months. Maybe more. Maybe less. I am constantly reminding myself that this is my Web site, and I have full autonomy to decide when and how it will get done. “Unhurried Development”, as Bernard calls it. At this point, all I’m planning to do is document the process of building this site from scratch, blogging (hopefully) consistently, in small bursts, as I share the process from start to “finish”. Process All the work on the new site will, naturally, happen in a repository which will be hosted on Github and deployed to Netlify. My favorite part of this entire plan has to be the part where I use Github Issues as a blog. Kind of. For every new feature (or set of features) I want to add to the site—no matter how small, like adding a Favicon, for example—I will open a new issue and create a corresponding branch where the work on that feature will happen. I will basically produce a(n) infrequent stream of short “blog posts” in the form of Github issues. The live code for each issue/feature will live in the issue’s corresponding branch. As someone who tends to do multiple things at once, this will take a lot of organization and discipline, and that’s the challenging part for me. So, each issue corresponding to a feature will be where I dump my brain about everything related to adding that feature. I will document learnings, resources, links, etc. along the way. I will write about the thought process, decisions, and struggles if any (kinda like what I did with the Glyphhanger article). So, if you’re at all interested, you will really be able to follow along with me as I do this. You’ll be able to read (some of) my thoughts, and learn from them if you want. You’ll not just have code to look at, but you’ll get the entire behind-the-scenes of it. A Note on copyrights At this point it is important to note that this opennnes does not mean that I am making the entire repo/site available to copy-paste. It is still not OK to steal other people’s work just because it is out in the open. This Web site has lived in a private repository since the very beginning. And for good reasons. I can’t count the number of times people have asked to use my Web site’s design for their own Web sites. I’ve even seen individuals copy-paste some of my content (like the contents of my Hire Me page) and use it on their own Web sites. While this is a great testament of the work I’m putting out here, it is not acceptable and I am not OK with my content and design being ripped off like that. On the other hand, the front-end code I will write to create the site will be open and publicly available for anyone to use, as long as it does not include the actual content it hosts and is built around. Speaking of content… New content & Styles I want to add content. Lots of it! And I’m not just talking about new articles. I’m talking about new types of content. And I want to remove and archive other content. As for the design, it will change but not drastically. I quite like a lot about the simplicity of the current design, and will mostly be working on adding more personal touches, similar to what I did with the horizontal rule styles. The underlying CSS, however, will be completely rewritten. I want to create a new layout around the content—not the other way around. I’m rethinking the content, structure, and architecture, from the ground up. In fact, I will be thinking less about the design and more about content architecture during the process, and am planning to get a functional site up well before any design is applied to the content. New Static Site Generator (SSG) After a few years with Hugo, I’m making the switch to Eleventy. The current state of things is a little less flexible than what I would like it to be. Hugo’s structure limits my ability to do things with the content that I am planning to do. Thus, I’ll finally be making the switch to Eleventy. (So you can expect quite a few Eleventy content/articles in the future.) I’m not new to Eleventy, mind you. I’ve used it to build a few client Web sites before, including the 2018 Khan Academy Annual Report. For the past few years, I’ve been using and loving Hugo a lot. But Hugo is an opinionated SSG. And for the past few years, that opinionation has worked for me quite well. But at some point, I needed a little more flexibility as I want to get a little more creative, particularly with a few layouts. Sometimes I want a page to use a special or unique layout, and Hugo doesn’t make this very easy to do. Eleventy, on the other hand, does. Hugo is also opinionated in the folder structure it expects. While that structure has suited me very well—in fact, I’ll be using some of the same structure in the new setup—I also want a little more flexibility in the way I organize and create my collections. The new content and layout structure I have in mind needs a more flexible SSG, and Eleventy is just right for that! What’s next? I don’t want to worry too much about what comes after. Do I turn the process into a series of edited blog posts? Do I just import the Github issues into my blog? Do I create a small video course in which I go over everything? Do I create a case study talk? I don’t know. Maybe. Possibly. Probably. But to be frank, I don’t want to think about that part too much. I want to focus on now, and what I want to do next, and worry less about what comes after. You’re welcome to join me on this journey. If you’d like, of course. No pressure. Thank you for reading.

Not Your Typical Horizontal Rules

The HTML <hr> element adds a horizontal rule (or line) wherever you place it. A horizontal rule is used to provide a visual break and divide content. Like other HTML elements, horizontal rules can be styled using CSS (and SVG). This means that they don’t have to look like boring, plain horizontal lines. You can get a little creative with them, adding a nice little personal touch to your content and designs. If you’re a frequent reader of this blog, then you’ve most likely already seen what a horizontal rule looks like on here. In fact, if you haven’t seen it before, then you might have just done that. The birds-on-a-wire illustration above this very paragraph is a styled <hr> element. If you're reading this article in a reading app or a Web browser's reader mode, then the above horizontal rule will not appear with my custom styles, and you'll just see a horizontal line. Here is a picture of what the horizontal rule looks like: Prior to creating this horizontal rule style, my horizontal rules looked as boring as you could possibly imagine. Until one day, I looked at that boring line and imagined a bunch of birds sitting on it (because, well, BIRDS!). And then it clicked! I got an SVG image of a bunch of birds (silhouettes) on a wire, modified it to look like I wanted it to, and used it to style my <hr> elements to look like what you can see above. In this post, I’ll go over how I did it, and how my horizontal rules can possibly be improved further, so that they adapt to various contexts, while remaining semantic and accessible. Semantics and accessibility An HTML horizontal rule is, by definition, not just a visual divider. It has semantics and plays a meaningful role in the context of its surrounding content: The HTML <hr> element represents a paragraph-level thematic break, e.g. a scene change in a story, or a transition to another topic within a section of a reference book. The hr element has an implicit role of separator. As such, <hr> is understood and announced by screen readers. A hr is announced as “Horizontal Splitter” by VoiceOver on macOS. The hr is also displayed as a horizontal line by reading apps and reader modes, where your CSS is typically stripped out and HTML semantics are used to determine how an element is styled by the reading app. What’s interesting is that a horizontal rule has an implicit orientation which is horizontal by default. This means that if you’re using vertical rules to split content, you can inform screen readers that the rule is vertical by setting the aria-orientation attribute value to vertical: <hr aria-orientation="vertical"> <!-- Note that you needn’t & shouldn’t explicitly set `role="separator"` on the `hr` element because its semantics are implicit --> VoiceOver on macOS announces horizontal rules with a vertical orientation as “Vertical Splitter”. In addition to separating paragraphs in an article, horizontal rules can be used for separating groups of menu items in a menu, for example. They can also be interactive. Further reading: ARIA spec for separator Since horizontal rules are semantic elements announced by screen readers, then unless you’re using a horizontal rule to semantically divide content, you should hide it from screen readers using aria-hidden="true". In other words: use aria-hidden="true" to hide decorational horizontal lines. Do not hide them if they are providing semantic, thematic content breaks. Styling <hr>s with CSS Like other empty HTML elements, the <hr> element can be limitedly styled using CSS. For example, you can change its width and height, border, and background color, as well as use gradients or apply a background image, etc. And even though it’s a content-less element, it seems that you can even create simple hr styles using ::before and ::after pseudo-elements, too. To create the birds-on-a-wire horizontal rules used on this site, all I did was set the dimensions of the hr, and apply the SVG image as a background image in CSS: hr { width: ..; height: ..; background-image: url("data:image/svg+xml,..."); background-repeat: no-repeat; background-size: 100% auto; /* .. */ } There’s nothing too fancy going on in the CSS. But the above styles have irked me ever since I wrote them. Generally, I try to avoid using background images for anything that’s not purely decoration. And the horizontal rules, as mentioned earlier, are not pure decoration. I also prefer to avoid using SVGs as background images and tend to inline them whenever I can so that I can take full advantage of their stylability with CSS. An SVG implemented as a background image cannot be styled from its containing (or referencing) stylesheet. I want the hr to be adaptive. I want to be able to customize it for different themes, and have the ability to modify and control its color(s) via CSS whenever I want. I also want to style it so that it remains accessible in user-controlled environments (such as Windows High Contrast Mode, for example). And while I don’t plan on animating the horizontal rules on this blog, I’d still like to have the option to add a subtle animation should I ever want to. After all, SVGs are handy because they are so powerful and flexible—they’re about more than crisp lines and illustrations. To style the horizontal rule to match various themes, I could possibly change the background image on the hr for each theme. This would work. But if the images are inlined in the CSS, then I’ll end with a larger CSS file. And if they’re not inlined, I’ll end up with multiple requests to multiple images, which isn’t great for performance. Not to mention having to create and maintain multiple images, which is not the best workflow for something that could be simpler. Additionally, in Windows High Contrast Mode, we have no control over the active theme colors. So if I want to make sure the horizontal rule always has enough contrast with the background, then I’ll need to be able to change and control its colors in my CSS, which I can’t do if if the SVG is a background image. This means that I might end with a black horizontal rule on a black background, for example. (On the other hand, if you don’t really care about the horizontal rule’s styles in WHCM and you just want it to remain properly accessible, you could just strip away the background image and let WHCM style the hr the way it would do by default.) I could just use a background image on the <hr> and stop at that point. But if if I want the horizontal rule to be truly adaptive, then I need a little more flexibility that the <hr> element itself doesn’t provide… A more flexible and adaptive implementation with inline SVG and ARIA The best way to get the full flexibility of an SVG is by inlining it. But the <hr> element is content-less — it has no opening and closing tags within which you can place other elements. The only way to work around the limitations of <hr> while preserving semantics for screen reader users is to use a div and provide the semantics of an hr using ARIA. Yes, I am cringing at the idea as I type this. But hear me out. I think it’s worth exploring and going down this road if you want to get creative with your horizontal rules while also making sure they remain visually accessible and customizable in various contexts and environments. The alternative approach to creating flexible horizontal rules would essentially look like this: <div role="separator"> <!-- hide the SVG from screen readers to avoid them announcing it --> <svg aria-hidden="true" focusable="false" width="..." height="..." viewBox="..."> <!-- svg content --> </svg> </div> Or, as my friend Scott pointed out, the separator role could be directly applied to the svg, in which case there’s no need to hide the SVG with aria-hidden anymore: <svg role="separator" width="794px" height="51px" viewBox="0 0 794 51" xmlns:xlink="http://www.w3.org/1999/xlink"> <!-- svg content --> </svg> Using the above markup: we create a semantic horizontal rule that is understood and properly announced by screen readers, and the illustration, being an inline SVG now, becomes easier to style and control with CSS. For convenience, the above horizontal rule markup could be wrapped in a custom component, or separated into a template partial or a shortcode, so that it can be more efficiently inserted where a <hr> would otherwise go. With the SVG inlined, I can use CSS custom properties to control what the SVG looks like in different contexts. For example, with CSS custom properties sprinkled inside the SVG, I could then control that content using CSS, modifying and changing its colors. For example, in Windows High Contrast Mode, I could set the color of the SVG to whatever is the current text color: /* IE and Legacy Edge */ @media screen and (-ms-high-contrast: active) { div[role="separator"] svg { --hr-color: windowText; } } /* Using the new standards for forced colors, currently supported in Chromium Edge */ @media screen and (forced-colors: active) { div[role="separator"] svg { --hr-color: CanvasText; } } That way, the horizontal rule will always have enough contrast with the background behind it. If the content of the SVG is multi-colored, you can define and set values for multiple variables in the same manner, thus creating different versions—or themes—of the horizontal rule for different contexts or environments. Further reading: Styling SVG <use> Content with CSS, in which I elaborate more about theming SVG images using CSS custom properties Styling for Windows high contrast with new standards for forced colors (Hat tip: Adrian Roselli) Using this technique: The horizontal rule is styleable and customizable using CSS. It can be animated with CSS and/or JavaScript. It will display like it is intended to (birds on a wire) even in environments where my CSS is stripped off, such as reading apps. Because the it is now an image, it will be displayed just the way it is, as opposed to an <hr> that would be displayed and styled by the reading app. Using the high contrast media query, it can be adapted to always remain accessible with whatever user theme is currently active. Here is a video of me changing the color of my birds-on-a-wire horizontal rule in realtime using Chrome devtools. This is made possible by using inline SVG and CSS custom properties to apply the color to the SVG content: Closing Thoughts Just like using inline SVG for icons is the best practice to ensure the icons remain adaptive and accessible, SVG can similarly provide better resilience for horizontal rules when you want to get more creative with them. Whether or not you use this technique, it’s good to have in your knowledge base, just in case you ever need it.

Accessible Text Labels For All

My talk Applied Accessibility: Practical Tips for Creating more Accessible Front-Ends is now available to watch online. This blog post is an extended transcript for a section of the talk, in which I discuss how to create more descriptive button (and/or link) text labels that improve the e-commerce experience for screen reader users, whilst making sure those buttons don’t fail WCAG success criteria. This, in turn, ensures that the buttons remain usable by another category of users: those using voice commands to navigate the Web. The concepts covered are applicable to all kinds of text labels, including form control labels. Quick overview of the VoiceOver Rotor on macOS and how it can be used to display contents on a page VoiceOver (VO) is the built-in screen reader on macOS. VoiceOver users can navigate the Web using what is known as the Web Rotor. The VoiceOver Web Rotor is a quick way to explore and navigate a web page. It is like power commands but for screen reader users. It increases their efficiency and facilitates their browsing the web. With VoiceOver open, the rotor can be activated with the keyboard shortcut ctrl + option + U. Once open, the rotor will be visible as a heads up display in the middle of the screen. It then presents all items of a particular type in a list. Inside the rotor, there are several lists—or menus— that the user can use to explore and navigate the content on the page. Using the rotor is an easy way to hear, for example, all the links on a page. The user can then jump to any link they want. There is also a headings menu that allows the user to jump to a particular heading on the page. In this video, I am demoing the VoiceOver Web Rotor to navigate and explore sections on an A List Apart page. Pressing the right and left arrow inside the rotor shows the different menus available, and gives a quick overview of the different types of content on the page. Using the rotor, and if the document is using semantic markup and proper sectioning elements (such as nav, header, main, footer, aside, and so on), the user can move from one area of the page to another without having to go through the content in each section. And it is very important for them to be able to do so. Note that the document structure in the rotor is defined by the document structure in your HTML. So, if you don’t provide a heading, it won’t show up in the rotor and so the document hierarchy for screen reader users will be affected. If you don’t use a landmark, it won’t show up in the rotor and the user won’t be able to jump to it to use it. Useful Reading: Voiceover Basics Using the Web Rotor to Navigate a Web Page with VoiceOver We mentioned earlier that the rotor contains different menus, including Headings menu, Landmarks menu, a Links menu, and a Form Controls menu. Knowing how a screen reader user might navigate a page opens up the possibility to optimize our interfaces and improve their user experience even more. Exploring e-commerce product listings using the VoiceOver Web rotor A common design in e-commerce Web sites is displaying a list of products on a page, each with its own Add to Cart button, allowing the user to quickly add items to their cart. To demonstrate, here is the Yeti Web site, showcasing a list of reusable bottles. Each bottle comes with its own Add to Cart button. Some also have a Customization option. The following video is a demo of me exploring the page using the VoiceOver Web Rotor: When you navigate this page using VoiceOver, and use the Form Controls menu, you’ll get a list of all form controls on the page, including the Add to Cart buttons. Quickly scanning these buttons you can tell that they provide very little value, as there is no way to tell which product each button corresponds to. How does a user know which button they want to go to and press if they don’t know which product it corresponds to? You may have already guessed that one way we could improve the navigation is by adding screen visually-hidden, reader-only text that would add the name of the product to its corresponding button. So, technically, the solution could look something like this: <button type=".." class=“.."> Add <span class="visually-hidden">PRODUCT_NAME</span> to Cart </button> <!-- P.S. Don’t do this --> You include the product name in the button’s text label string, so then when the Form Controls menu displays the list of buttons, each button would be clearly labelled to indicate which bottle it is referring to. This is a good solution for a screen reader user navigating using Form Controls, but you do not want to do this because even though it improves the experience of some screen reader users, it excludes users of other assistive technologies and makes these buttons inaccessible to them, and a pain to use… Talking your way through Web browsing with voice commands Inserting visually hidden text in the middle of a visible string of text on a button like that prevents users browsing and navigating using voice commands from interacting with the button. A popular example of Voice recognition software used to browse the Web is Dragon Naturally Speaking. It is software that allows you to use your computer and browse the web using voice commands. It comes with a full usage manual that details how to use it to perform different tasks on your computer and on the Web. Such software is useful for a lot of people, including but not limited to people with disabilities who can’t use their hands, for example, or power users who want to get things done faster (because voice dictation is faster than typing). Seeing it in action is the best way to get an idea of how it’s used. So, to quickly demonstrate how it is used on the Web, Level Access created a video demoing Dragon Naturally Speaking to fill out a form on a page. The following video is a short clip from their video which you can find and watch in full on Youtube. Note: Note that when he says “go to sleep” or “wake up” he’s basically pausing Dragon and reactivating it by telling it to sleep and wake up. When the dragon user (in the video) wants to select a form control, he speaks out the visual text label of that control. This is one of many reasons why visual labels are important in user interfaces. So when we have a series of Add to Cart buttons, a dragon user will speak the label of the button in order to interact with it. This is why adding text in the middle of the string makes it inaccessible. The content in the middle of the string would break the visible label. The user would be telling dragon to interact with a button whose label is not what it visually appears to be. This is why this would fail the WCAG Success Criterion 2.5.3: Label in Name: For user interface components with labels that include text or images of text, the name contains the text that is presented visually. A best practice is to have the text of the label at the start of the name. The following two paragraphs are from the Success Criterion’s page (emphasis mine): The intent of this Success Criterion is to ensure that the words which visually label a component are also the words associated with the component programmatically. This helps ensure that people with disabilities can rely on visible labels as a means to interact with the components. Most controls are accompanied by a visible text label. Those same controls have a programmatic name, also known as the Accessible Name. Users typically have a much better experience if the words and characters in the visible label of a control match or are contained within the accessible name. When these match, speech-input users (i.e., users of speech recognition applications) can navigate by speaking the visible text labels of components, such as menus, links, and buttons, that appear on the screen. Sighted users who use text-to-speech (e.g., screen readers) will also have a better experience if the text they hear matches the text they see on the screen. WCAG Success Criterion 2.5.3 Improving the experience for screen reader users whilst keeping it accessible to speech-input users We still want to improve the experience for screen reader users, but we can’t insert the product name into the button’s visible label. We can’t fix the experience for a group of people and end up breaking it for another group. Challenges like these make you scratch your head and think of alternative solutions. It turns out, there is a middle ground here. We can still add the product name to the button, improving the user experience for screen reader users, without breaking the visible name of the button, by appending it to the end of the button’s name, instead of inserting it in the middle. <button type=".." class=“.."> Add to Cart <span class="visually-hidden">, PRODUCT_NAME</span> </button> By appending the text to the end of the visible name, the visible name is left intact, and the Web Rotor Form Controls menu will show a list of Add to cart buttons with the names of the products they are referring to appended to them. As for the voice control user, when they say “click Add to Cart”, Dragon is going to label the Add to Cart buttons with numbers, like we saw with the checkbox and radio button examples in the video, and then the user can speak out the number of the button they want to click. This works because Voice commands work by saying the name of the input you want to interact with, as long as the name is not “broken” or interrupted by content in the markup. So whenever you need to add additional text to a visible label, it best come after what’s visually shown. Similarly, always ensure the accessible name (announced by screen readers) matches the visual label as much as possible. This means that you’ll also want to avoid adding a label using aria-label that does not match the text label that is shown on a control. Closing thoughts: Provide visual labels whenever possible Knowing how voice control users navigate the Web can also inspire more visual improvements to our components. If the user needs to see a visible label to interact with a control, then what about controls that don’t have any visible labels? What about components that have label-less controls, such as dot navigations (typically used in sliders and carousels)? If a user wants to interact with the dots in a dot navigation, they can’t speak their accessible name because they don’t have a visible one they can see. So they are left with two other ways to navigate: using voice commands to tab through the control, or using the mouse grid, which is the most tedious and least favorable option. It should be obvious by now that the best practice is to always have a visible label for UI controls. But if that’s not possible at all, then the next possible option is to show a label on focus (and hover, too, maybe). Showing labels on focus is particularly important because a Dragon user can tell Dragon to Tab to the next control, but they can’t tell it to hover over it (what’s it going to hover if it has no label to indicate what it is?) Other visual elements that would be more accessible when associated with a visible label are icon buttons. Similar to the dot navigation buttons, if you can’t add a visible label, try showing one when the user interacts with the button. Thank you for reading.

How I set up Glyphhanger on macOS for optimizing and converting font files for the Web

I can't count the number of times I've tried installing a command line tool on my machine, only to find myself going down a black hole of node modules & dependencies, and a seemingly non-ending list of error messages in the terminal. This would go on for a while before I finally give up and call it quits, only to revert back to find myself googling the name of an online app and using that to do what I need instead. Yesterday, the same thing almost happened again. I got into another black hole in iTerm as I tried to install a couple of Web font conversion and optimization tools. I almost gave up before I finally managed to kind of get everything working the way I wanted it to. A lot of googling and “stack-overflowing” was involved in this process. I’m sharing my struggles in this post in the hopes that it might help someone out should they get stuck where I did. I also want to have a reference to come back in the future should I ever find myself installing the same tools again. Yesterday was just another typical work day. I was setting up the foundation for a new client project. The Web site we’re building uses the Inter font family for the typography. So, I head over to Google Fonts, found the Inter family page, and clicked that “Download family” button. As you probably already know, Google Fonts doesn’t supply the fonts in WOFF or WOFF2 formats. When you download a font, you only get TTF font files. Why that is, I don’t know. Jeremy has wondered the same before. And if you’re a front-end developer you should also know that TTF is not the best choice for serving Web fonts, and that WOFF and WOFF2 are far leaner and more performant. So, as usual, I set out to convert the TTF files to WOFF and WOFF2 to serve them up in my project. My previous font conversion workflow Normally, I’d head over to one of the online tools available — whatever comes up first in Google search, because I’ve never bookmarked one tool to use at all times, even though I tend to use Font Squirrel generator quite often. But that has always felt like too much of a hassle. Ideally, I’d be able make this conversion within the folder in which they are located. So the workflow would look like this: download font, unzip & open folder, convert to WOFF & WOFF2, copy to project folder and embed on page. …instead of: download font, unzip & open folder, find an online tool, upload font files, wait for conversion, download fonts, unzip & open folder, and then move to project folder and embed on the page. This has always felt like an clunky workflow. It always bothered me that I had to click and switch contexts as much as I did. So, yesterday I saught the help of the amazing Twitter #lazyWeb and asked my friends there what they use to convert their font files on macOS. Many responded with links to online tools, which is what I’m wanting to avoid. And some responded with recommendations for a few command line tools. I imagined I’d want a nice drag and drop tool for this. But command line tools are also pretty handy, and usually very flexible, too. Once you’ve got one set up, it could help streamline your font conversion process. And since I’m much more comfortable in the command line today than I was a few years ago, I thought it was about time I switched to one of those tools. I was instantly sold on Filament Group’s glyphhanger. “glyphhanger is a useful tool when working with web fonts—it can help optimize your font files very quickly”. Not only does glyphhanger convert font files, but it also subsets them (i.e. it removes unnecessary characters from a font file), which is another optimization step you want to make to serve more performant fonts. (That, and the fact that I love the work of the folks at Filament Group, who have always been big proponents of performance.) The Github repository’s README file includes installation instructions. And that’s where I started yesterday… Installing Glyphhanger I’m going to start with the process I went through and the issues and errors I got. If you’re not interested in that, you can skip straight to the solution. Down the rabbit hole glyphhanger is available on npm. According to the reposiroty’s README, installation is as simple as running: I ran that command. glyphhanger was installed. Yay. So far so good. Following that line in the README is a note that says that pyftsubset is a prerequisite. I wasn’t familiar with what pyftsubset is, so I kept on reading. (Honestly, does everyone know what everything is?) There was a link to another Github repository: fontTools. I chose glyphhanger for its subsetting feature, and the subsetting functionality requires you to install fonttools. So, I had a dependency to install. Reading the README of the fontTools repo only complicated things for me. So, I kept on reading the glyphhanger instructions. (At this point: I couldn’t make the direct connection between pyftsubset and fontTools at first. Later on, I googled “pyftsubset fonttools” and learned that pyftsubset is an OpenType font subsetter and optimizer, based on fontTools. And that’s why you need to install fontTools.) The next instruction is: I had no idea what pip is. I decided to run the command before googling anything. Unsurprisingly, that’s when I got my first error. Oups. OK so apparently I need to have Pip installed on my machine. Not knowing what it is, I started googling. I learned that Pip is a package manager for Python. And that to install Pip, I needed to have Python installed. Many articles mentioned that macOS already comes with a version of Python installed. So I looked for what I needed to install Pip using the Python that’s already installed. For some reason, none of the commands I found worked. So I thought: “maybe Python isn’t installed on my machine?”. So I opened a new browser tab and started googling for how to install Python. ¯_(ツ)_/¯ While I was at it, I was following the rest of the instructions in the README. I didn’t know what depended on what, so I thought I’d try continuing async. The following instructions are about cloning the Brotli and Zopfli git repositories and installing them because they are required to get WOFF and WOFF2 support: As you might have noticed already, these steps require Python to work, and since I didn’t have Python working for me at this point yet, I got quite a bunch of errors in the terminal. Trying to install Brotli and Zopfli like that confirmed to me that Python maybe is, indeed, not installed by default. fontTools is also a Python project, which, naturally, requires Python to work. (Duh.) So it was very obvious at this point that what I needed to focus on was getting Python and Pip set up if I wanted any of this to work. After googling quite a bit and jumping between articles and Stack Overflow Q&As, I learned that there are multiple versions of Python (obviously), the latest (I think) is Python 3. Now this is where the weirdness started. After installing Python 3, if I wanted to run a Python command, I needed to use python3 followed by the command. Not python. According to a nice article I found later, “in order to send commands to Python 3, you will need to enter python3 in the terminal. If you enter python, the command will be sent to Python 2.” So anyway, I installed Python using brew: Yep. That worked. I don’t remember if I had any issues here. But then again, I had so many issues that I don’t remember when and where I got each. ¯_(ツ)_/¯ Here’s a quick tip: If you, like me, want to avoid brew updating every time you use the brew command, you can use HOMEBREW_NO_AUTO_UPDATE=1. I have a snippet setup so that every time I type brew and press TAB, it autocompletes to HOMEBREW_NO_AUTO_UPDATE=1 brew, so that I can run whatever brew command I want without allowing it to update. I learned this a few months ago when I got sick of brew updating every time I wanted to run a quick command. I googled, and found this tip on Stack Overflow and have been using it since. Next, I needed to install Pip. Once again, I found several articles, each mentioning a different way to do it. To be quite honest, I don’t remember which one of those I ended up following. I did learn though that with Python 3 comes Pip 3. I installed Pip 3. At this point, I realized I should have everything I needed to continue going through the README instructions. So, again, I tried installing fonttools using pip install fonttools. After getting yet more errors, I learned that, just like python3 I need to use pip3 instead of pip. That worked. So I got Python, Pip, and fontTools out of the way. To generate optimized WOFF and WOFF2 font files, I needed Brotli and Zopfli. I have no idea why I still got some errors by following the installation instructions in the README (cloning the git repos for each). So, more googling ensued. Turns out, installing Brotli and Zopfli was much easier now that I had Pip installed. I didn’t even need to clone the git repositories like the README instructed. All I needed is these two commands: And Boom! all dependencies were installed. Now when I used glyphhanger to convert my font files, it finally generated the optimized TTF, WOFF, and WOFF2 files. So, to sum up: tl;dr: installing all dependencies and running glyphhanger Install glyphhanger: Install Python 3: Install pip. Python 3 comes with pip 3. Follow the instructions in this article to install pip. Install fontTools using pip: Install Brotli and Zopfli using pip: And then use glyphhanger to subset and create optimized formats of your TTF font files: Zach Leatherman has a post that introduces glyphhanger with examples of how to use it. You’ll want to read his article and the repository’s README for further customizations and usage options because there are quite a few. Optimizing Variable Fonts glyphhanger also generates WOFF2 files for Variable fonts. The file size of the subsetted Variable Inter WOFF2 file generated by glyphhanger is slightly smaller than the file size generated by Google’s woff2 library (302KB compared to 308KB). It does not break the Variable axes of the font like other online tools might, so it is safe to use it in your projects. Useful resources: How to use variable fonts in the real world How To Convert Variable TTF Font Files to WOFF2 — this post explains how to set up the woff2 library and use it to generate WOFF2 from a Variable TTF font file. I’ve found it to be more helpful than the library’s README file. Make sure to follow the steps and commands to the letter. While I finally managed to get glyphhanger set up and can now use it generate optimized Web font files, it still bugs me that I am still getting an error when using it. My terminal looks like this every time I run the command: I googled a lot trying to find what that error means and where it’s coming from. I would love to get a clean output every time I run glyphhanger. I mean, it’s such a great tool. I want the output to be just as great. But after spending quite some time on getting it to work, I wasn’t left with enough patience to figure the solution out. If you have an idea what might be causing it, please do let me know — I’d appreciate it a lot. ✨ UPDATE: ✨ Twitter came to the rescue once again. @GentlyLurk figured out that the issue is coming from the version of shelljs used in glyphhanger, and kindly shared the fix: Run which glyphhanger in the command line. This should give you the path to the folder inside which glyphhanger resides. (My result was /usr/local/bin/glyphhanger; it’s a hidden folder so I had to cmd+shift+. to view it.) Find the package.json file in the folder and change the version of shelljs to 0.8.4, then run npm install (inside the folder) Now the errors are finally gone. 🥳 If I run glyphhanger --subset=Inter-Light.ttf for example, the result I get in the command line looks like this: (Look at those WOFF2 savings!) 🎉🎉🎉 ✨ UPDATE #2 (March 11, 2021): ✨ Zach announced the release of glyphhanger v4, which includes dependency updates that fix the console warning issue that I had and that required the manually changing the shelljs version in the package.json file. So if you follow the installation steps above, you should have a clean console output without the extra hassle. 🎉 More articles on font subsetting How I subset web fonts Developing a robust font loading strategy for CSS-Tricks

"Yes or No?" — One Checkbox vs Two Radio Buttons.

Should you use a checkbox? First, some backstory: I’m currently working on a client project unlike any other I’ve worked on before. The project is basically us building a Web UI that will replace an old, outdated native Windows desktop application. (It looks worse than you probably just imagined.) This is an app used by government employees and is chock full of forms. Actually, it is literally basically just a lot of forms. I’ve never worked on a project so forms-heavy before. I am building almost every form field imaginable. Surprisingly, though, I am enjoying this very much as I’m learning a tonne in the process. My client was giving me a tour of the native app last week so that I’d have a clearer understanding of some of the UI components I was building. I have mockups for most of the UI elements, but of course, I can only implement a control or a component correctly and accessibly if I know exactly what it is, what it does, how it works, how users will interact with it, etc. So I needed more context and insight into why some of the design decisions were made because I wasn’t working on this project during the design phase and was only recently hired to work on it. Learning more about the native app UI was extremely insightful and I had so many questions that led to extremely insightful design and UX conversations, many of which are worth their own articles (or even a talk). We were also discussing potential ways we can improve the native functionality. We did not want to just blindly convert the desktop UI into a Web UI. The redesign and platform change is an opportunity to improve and modernize the user experience where possible, keeping the user in mind and making them the priority. Going through the native app UI, my client told me that there were some “inconsistencies” that we might try to address and come up with better alternaties for in the Web UI. One such inconsistency is having questions with binary Yes/No answers sometimes presented as one checkbox and other times presented as straight up questions with two radio buttons: Yes and No. My client wasn’t sure why those decisions were made. Why are some fields for binary questions presented as one checkbox and others as two radio buttons? Looking at the fields in question, I wasn’t sure why those decisions were made. But it looked like there was potential for unifying the controls there and making them more consistent. But can we do that? Is it really feasible to use either one checkbox or two radio buttons for all the fields we were looking at? What are the UX advantages to using either of these? Why and when would we use each? I don’t remember reading any research that answers this particular question: if you have a question with a binary Yes/No answer, is it better to use one checkbox or two radio buttons? Now, just to clear things up before moving on: I am aware of… the difference between checkboxes and radio buttons: checkboxes are used when the user can select one or more options, and radio buttons are used when the user can choose only one of two or more options. In addition to checkboxes and radio buttons for binary answers there are also toggle switches as a third option. But a checkbox, radio button, and a toggle switch are not the same. To learn more about the differences between these three, you may find the following two articles by the Nielsen Norman Group useful: Checkboxes vs. Radio Buttons Toggle-Switch Guidelines For my client project, I was specifically interested in one specific use case. And I needed to collect more information that would help us make a more informed decision. Collecting input from the UI/UX design community on Twitter I’ve asked the UI/UX community on Twitter for their input on this matter. The answers were overwhelmingly insightful and show just how nuanced this question can be depending on your specific use case. I invite you to read the whole thread on Twitter. But for the sake of this article, I’ve collected the most relevant responses and points that are worth considering when making the decision of which option to use. I know there are scenarios when a checkbox is common, but when would you do separate radios (Yes & No) instead? Thx! Use radio buttons if you expect the answer to be equally distributed. If I expect the answer to be heavily biased to one answer I prefer the checkbox. That way the user either makes an explicit statement or just acknowledges the expected answer. If you want a concrete, deliberate, explicit answer and don’t want a default selection, use radio buttons. A checkbox has an implicit default state. And the user might be biased to the default option. So having the requirement for an explicit “No” is the determinig factor. For me, a checkbox signifies that there a default state (usually unchecked). A radio, however, requires a deliberate choice from the user, so it depends on how optional that Yes/No choice is. — Adam Harris (@Adam_J_Harris) November 18, 2020 A selected “No” radio button means No, but an unchecked checkbox could simply mean that the user missed the question. That might be something you don’t want happen if you need the information you’re asking the user for. So prefer radio buttons if you want the user to actively choose an option (none of the radios is preselected) – so there isn’t a default yes or no. So I work in clinical trials, and for me if you have radio button Yes/No and they pick No... that means no. If you have a checkbox, that means they didn't check it. Could be a No. Could be a missing field. — Evil Blond Dad (@sonofalink) November 18, 2020 If questions are like this: "Subscribe to newsletter?", then its definitely checkbox. If its missed, then, they don't miss something important If questions are like this: "Should we email you the order details for record?" then definitely go for radios. — Muhammad Hanif (@HanifOnline) November 19, 2020 I think if the no option is passive, like no i dont really want to be added to your mailing list. Then i would use a checkbox. But if the user is required to commit to an answer id user radio buttons. Like do you consider yourself Aboriginal/TSI on a employment application — Michael Little (@cleandevelop_) November 20, 2020 I would use 2 radio inputs when I wouldn’t want to infer that one of them is the default. For instance if the question is “Are you a US citizen?”, I would provide Yes/No, rather than a “Yes” checkbox. I believe @leoweigand did some research on this for our signup flow. — Hugo “Kitty” Giraudel (@HugoGiraudel) November 18, 2020 Checkboxes can be suitable for certain optional, opt-in questions that are not required. But in this case it should be clear to the user what not checking the checkbox would mean, too. If the field is required, prefer radios. For a *required* field, both options have to be presented, and I’ll use radio buttons. ⚠️Radio Defaults: Whether or not there’s a default state selected is nuanced and important. If there could be any harm at all to the user by defaulting them to either choice, then NO default. — Taylor dunham (@taylordunham_) November 18, 2020 I work on products that deal with consent and data privacy. I use a checkbox (or a toggle) to collect consent as per definition (under GDPR) it has to be an active opt-in. The absence of action means no. I would use 2 radio buttons when the default option cannot be inferred. — Cyrièle Piancastelli (@cyro) November 18, 2020 Checkboxes or toggles are optional, opt in items. You are making binary selections for each label/check pair, but they are optional. Radio buttons are for question groupings with strict logic this or that, one must be selected. — orgy porgy centrifugal bumblepuppy (@designnotdrum) November 18, 2020 🔘 Radio buttons = required fields ☑️ Checkboxes = optional fields#UX tip for faceted search engines: If you use radio buttons to force the user to only select one of exclusives values, remember to give them a way to unselect it if it’s too restrictive! — Alex Martin (@AlexMartinFR) November 18, 2020 Generally, opt-in toggles such as “Subscribe to our newsletter” or “Show extra columns” would be checkboxes. If the choice is about enabling/disabling then checkbox, if the choice is about answering a question, the choice has semantic meaning and I’d say radio — Jeroen Koomen (@Jjeekkoo) November 20, 2020 It also depends on how the question is phrased. Radio buttons are the obvious choice if the label is a question. Checkboxes are more suitable if the label is a statement (and assuming it is an opt-in field). I agree with @morganc_smith. It depends on how the question is phrased. Are you 18 years or older? Yes / No vs ✅ I am over 18 years old. — Betsy Dupuis (@BetsyDupuis) November 18, 2020 Checkbox - the label is a statement ("I have read the terms and conditions", "Opt me into your mailing list") Yes/no radio buttons - the label is a question ("Have you read the terms and conditions?", "Would you like to join our mailing list?") — Graeme Coleman (@graemecoleman) November 18, 2020 When the field is phrased as a question, it requires the user to read it more carefully. Something to keep in mind if you do want them to read it carefully or not. There will be situations where you don’t want that additional congnitive load. For example, if you want to know if the person if a citizen of a country. Two radios ensure users need to take action, so a field cannot be skipped without considering the options. I would furthermore use an option label like "I am a US citizen" instead of yes / no, so users don’t have to read the question so carefully. — Leo (@leoweigand) November 18, 2020 So, which one should you choose? one checkbox or two radio buttons? The answer is, as with most matters: It depends. Depending on the type of content you’re working with and the kind of information you’re asking for, it could easily either be one checkbox or two radio buttons. The collection of answers above can hopefully help you make a more informed decision. But as with all user interfaces, nothing beats the input you can get from user testing and research. So hopefully the answers above can at least serve as a starting point in situations where you need more to make a decision. Thanks to everyone who chimed in the Twitter thread. And thank you for reading.

Inclusively Hiding & Styling Checkboxes and Radio Buttons

Checkboxes and radio buttons are two common examples of interactive form elements that we desperately want to have full control over styling but we don’t. So we’ve been hacking our way around styling them by hiding said elements with CSS and visually replacing them with pseudo-elements or an SVG image — SVG, of course, being the more flexible, powerful, and accessible replacement. But an SVG image is, at the end of the day, just an image, so while it can visually replace a checkbox, it doesn’t really substitute for it — the user still needs a checkbox to interact with. So, when we attempt to hide the checkbox we want to style, we need to make sure that the checkbox remains accessible and interactive. I’ve recently come across quite a few articles on the topic of accessibly styling checkboxes and radio buttons. All of the articles I read use one or another variation of the visually-hidden utility class which is usually used to hide content visually while keeping it screen reader-accessible. But while this technique works for some content, it’s not suitable for hiding interactive elements like radio buttons and checkboxes that have other accessibility and usability considerations. I learned this when I used the same technique myself to create my own accessible checkboxes a couple of years ago and my friend Scott O’Hara kindly pointed out during one of our chats that they weren’t entirely accessible because they weren’t discoverable by all screen reader users, particularly those navigating by touch. So, in this article, I will cover the different techniques for hiding elements, how each of them affects the accessibility of the content, and how to properly hide checkboxes and radio buttons taking their own accessibility and usability considerations into account to make sure we aren’t leaving any users out. Note that while I will be talking about checkboxes in this article, this technique applies to radio buttons and any other interactive form elements that you may want to restyle using an image replacement, including file inputs, for example. Setting the foundation in the markup Even though styling a checkbox using modern CSS features is currently possible, using SVG to create custom checkboxes remains, in my opinion, the most flexible, powerful, and accessible way. Using SVG, we don’t style the checkbox itself — we hide the checkbox and use an SVG to create a checkbox image. So the SVG is just a visual replacement of the checkbox. So, in order to style a checkbox with SVG, we need to add the SVG to the markup somewhere. You could, of course, use the SVG as a background image (on the checkbox label), yes; but it comes with drawbacks such as: you lose the ability to animate the SVG, which is one of the major benefits of using SVG to begin with, and you lose the ability to optimize the SVG for user-controlled environments, such as Windows High Contrast Mode, so you could end up risking the accessibility of the checkbox in those environments. …not to mention that inlining an SVG has overall more advantages than any other embedding techniques and that you could make use of, such as animations. I like to wrap my checkboxes inside their labels. Placing the checkbox inside the label increases the overall clickable area, which makes it more usable. I also like this approach because it makes the checkbox a more self-contained component that I can customize with CSS variables and use anywhere I need it. Since the checkbox is going to go inside the <label>, the SVG will too. <label for="c-checkbox" class="c-custom-checkbox"> <input type="checkbox" id="c-checkbox" /> <svg width="32" height="32" viewBox="-4 -4 39 39" aria-hidden="true" focusable="false"> <!-- The background --> <rect class="checkbox__bg" width="35" height="35" x="-2" y="-2" stroke="currentColor" fill="none" stroke-width="3" rx="6" ry="6"></rect> <!-- The checkmark--> <polyline class="checkbox__checkmark" points="4,14 12,23 28,5" stroke="transparent" stroke-width="4" fill="none"></polyline> </svg> <span>The checkbox label text</span> </label> The checkbox label now contains the label text, the checkbox itself, as well as the SVG image that will represent our checkbox visually. So, if you think about it, we’re technically going to style the label — or a part of it. A couple of important things to note here: Since the SVG is going to replace the checkbox visually, it also needs to visually convey state (checked, unchecked, disabled), as well as behavior (focus in particular, and hover if you need that). The SVG is used to create an image of a checkbox. The SVG image is not going to replace the checkbox semantically. To address the first point, I placed the SVG image after the checkbox in the DOM. This will allow me to use the siblings selector in CSS to select the SVG and style and animate it when the checkbox is focused and interacted with (checked and unchecked). We’ll do that in a later section. And since the image doesn’t replace the checkbox semantically, the checkbox needs to remain accessible. So when we hide it, we want to make sure we do so accessibly. Hiding Content in CSS and HTML There are several ways we can hide content in CSS and HTML, each with its own pros and cons. Knowing the upsides and downsides of each technique will help us choose the one we need when we need it. Hiding content in CSS There are four properties in CSS that can be used to hide content: Using display: none; Using visibility: hidden Using opacity: 0 Using clip-path: inset(100%) Both display: none and visibility: hidden remove the element they hide from the DOM and accessibility tree, thus making them completely inaccessible. Back in the days when we used to use background image sprites to style checkboxes and radio buttons, we used to use display: none to hide the inputs, which removed them from the accessibility tree and therefore made them completely inaccessible to screen readers. You should never hide content using display: none or visibility: hidden if you want that content to remain accessible. We need our inputs to remain accessible to screen readers, so we not be using display: none or visibility: hidden anymore. It’s also worth mentioning that you shouldn’t rely on background images or background colors to replace essential content (such as inputs) because background images are not accessible to screen readers, not to mention that they are most likely going to be removed when your CSS isn’t applied in user-controlled environments (such as Windows High Contrast Mode) and reader modes. Hiding content in HTML We can also hide content straight from the HTML using HTML attributes. There are two attributes we can use today: hidden and aria-hidden. The hidden attribute is the HTML equivalent of CSS’s display: none, it hides the element it is applied to both visually and from assistive technologies, and is useful for hiding content when CSS is disabled (for example, in reader modes). The aria-hidden attribute determines whether an element is hidden from accessibility APIs (aria-hidden='true') or not ('false'); is useful for hiding decorative or duplicative content (e.g. decorative icon next to text). In addition to the above, we can apply multiple CSS properties within a rule set to hide an element visually while keeping it screen-reader accessible. An example of that would be providing text for assisitive technologies only that can’t be displayed visually. Accessible icon buttons are a common and good example of that. Typically, the styles are applied using a utility class: /*******************************************************************************\ * * * Visually hide any element (mostly text) accessibly. * * Support includes IE9+ * * Source: https://www.scottohara.me/blog/2017/04/14/inclusively-hidden.html * * * *******************************************************************************/ .sr-only { clip: rect(0 0 0 0); clip-path: inset(100%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; } This utility class shrinks an element into a 1px square, hiding any overflow, and absolutely positioning the element to remove any trace of it from the normal document flow. This utility class is ideal for providing screen reader-only text. After going over all of the above techniques, I always ask my talk and workshop attendees how they would hide a native checkbox while ensuring it remains screen reader-accessible. Since we want to make sure the checkbox remains screen-reader accessible, we rule out all of the rules that hide it from screen readers. This left us with the two most frequent answers: Hide the checkbox using the .sr-only class, because it seems like the perfect solution because it hides the checkboxes visually whilst keeping it accessible to screen readers, and this is what most articles online currently use. and Move the checkbox off-canvas, hiding it outside of the viewport using absolute positioning. This, too, removes the checkbox from view but does not remove it from the accessibility tree. It is true that both of these techniques hide the checkbox visually and it will still be accessible by a screen reader, but neither of these techniques are inclusive of users navigating by touch. Hiding the checkboxes inclusively Touch interface screen readers allow users to run their finger over the screen to hear what is directly underneath. This provides the user with a quick sense of an entire interface. — Material Design Acessibility Guidelines Screen readers on Android touch devices give users multiple ways to navigate a screen. One of these ways is exploring by touch. Rob Dodson has a great screencast covering the basics of navigating a page using TalkBack on Android that I recommend watching for a live demo. Exploring by touch means that a mobile screen reader can explore pages on touch screens with haptics — they literally move their finger on the page looking for interactive elements. When you create a checkbox (or any other interactive element, for that matter), the user will expect to find that checkbox by touching the screen where they expect it to be. So the way you hide the checkbox determines whether touch screen reader users will be able to find it or not. As you can possibly imagine now, hiding the checkbox off canvas (outisde of the viewport area) will make it inaccessible to them, because they won’t find it within the viewport bounds as drag their finger around. Similarly, shrinking the checkbox to 1px will also make it very difficult to find and touch. So, while the sr-only utility class is great for visually-hiding static content (e.g. text), it should not be used to hide interactive elements. So, how do you hide a checkbox inclusively? The answer is: hide it visually but make sure it is still ‘physically’ present where it would naturally be present so that touch users can find it with haptics. Technically speaking this means: remove the checkbox from the page flow using position: absolute so that it doesn’t take up any unwanted space (visually), position it (within the label) making sure it is positioned on top of the image that is visually replacing it, optional: set its dimensions to match those of the SVG, visually hide it by making it transparent with opacity: 0, Here is a video demo’ing the above steps. Note that I’ve already styled the SVG to convey state in this demo, which is what I’ll cover in the next section. The CSS that handles the positioning and hiding of the checkbox looks like this: .c-custom-checkbox { /* create a postioning context for the checkbox within the label */ position: relative; /* other label styles here */ } .c-custom-checkbox input[type="checkbox"] { /* remove the checkbox from flow */ position: absolute; /* hide it visually */ opacity: 0.00001; /* */ /* tweak size and position if needed */ width: 1em; height: 1em; /* position it within the label, on top of the SVG */ top: ...; left: ...; /* sometimes you may need to add z-index */ z-index: ...; } So the checkbox is technically still there where it should be, it is still interactive, it is fully accessible, but it is visually hidden so it can be replaced with a more styleable alternative: the SVG. Note I’ve replaced the 0 opacity value with 0.0001 (basically a very small value that’s almost zero but not quite) to make sure ChromeVox announces the checkbox because otherwise it does not read content with opacity: 0. Hat tip to Carolyn MacLeod for the heads up and (once again to) my friend Scott for his findings. Styling the SVG accessibly Since we’re hiding the native checkbox, we will need to substitute for the checked and unchecked states visually, as well as the focus styles. The SVG is placed right after the checkbox in the DOM, so we can select it using the adjacent siblings selector, and style it based on the checkbox’s state. So when the checkbox receives focus, we display the focus outline on the SVG: The focus style can be anything you want, as long as it’s very clear and visually accessible. Similarly, you can add disabled state styles using the :disabled seletor. To mimic checking/unchecking the checkbox in the SVG, we show/hide the checkmark inside it, and change the background color: /* basic styles for the svg */ .c-custom-checkbox svg { /* set SVG dimensions in ems; i.e. relative to the font size so that it scales with the size of the text in the label */ width: 1em; height: 1em; /* ... */ /* apply a transition to the elements inside the svg */ * { transition: all 0.1s linear; } } /* style changes inside the svg when the checkbox is checked */ .c-custom-checkbox input[type="checkbox"]:checked + svg { .checkbox__bg { fill: var(--checked-state-bg-color); stroke: var(--checked-state-bg-color); } .checkbox__checkmark { stroke: var(--checked-state-checkmark-color); } } While you’re at it, you’ll want to take it further and optimize it for Windows High Contrast Mode: One of the many benefits of using an inline SVG is that we have real elements (checkmark and square) with real borders (strokes) that we can flexibly style, so we don’t rely on background images and colors alone to create and convey state/behavior, because background images, colors, and effects like drop shadows are normally overridden in user-controlled environments. This is also why I normally recommend using a real outline versus a fake outline created using box-shadow. And here is a live demo: See the Pen Accessibly styled checkbox by Sara Soueidan (@SaraSoueidan) on CodePen. Adding delight using SVG animations Using animated SVGs is one of my favorite ways of adding delight to otherwise boring user interfaces, particularly form controls. Checkboxes and radio buttons are a great example of controls that could benefit from more fun interactions. In 2013, Codrops published a collection of playful experiments using SVG path animations (a.k.a. the line drawing technique) to create more delightful checkboxes and radio buttons. But the Codrops examples were merely a proof-of-concept for animation and were not optimized to be accessible. If you want to use such animations in your UIs today, you’ll want to make sure you hide the checkboxes using the technique presented in this article. Here is a quick proof of concept of an accessible animated checkbox: See the Pen CUSTOM ANIMATED CHECKBOXES by Sara Soueidan (@SaraSoueidan) on CodePen. Wrap-up There are several ways to hide an element in CSS and HTML. You can hide an element both visually and from screen readers, only visually, or only from screen readers. When you hide an interactive element, make sure you choose a hiding technique that keeps it screen reader-accessible, position it on top of whatever is visually replacing it so that a user navigating by touch can find it where they expect to, and then make it transparent. References and Recommended Reading Inclusively Hidden Inclusive Considerations When Restyling Form Controls + more by Scott O’hara

Optimizing keyboard navigation using tabindex and ARIA

The faster the user can navigate your UI the better. The faster they can get to the content they need, the better. Therefore, the less steps they have to go through, the more efficient their overall experience with the UI will be. And this applies to keyboard tabbing, too: the less tabs the user needs to stop at while navigating, the faster they are to get to where they need. The way we mark up our content has a direct effect on the user’s experience. But we can drastically improve the UX by specifically optimizing the markup for keyboard users. Clicks. Taps. Tabs. Steps. If there’s one thing working with UX designers has taught me it’s that the less steps the user needs to go through their journey, the better. As such, they usually design experiences by making sure fewer clicks are needed to get the user to the end of their journey. As a design engineer, when talking about “steps” and “clicks”, my brain can’t help but think of taps and tabs, too. Because a user could be interacting with the UI in several ways, not just using a mouse. Taps are practically touch equivalents of clicks, so I assume the experience would be as optimized for those as it is for non-touch. But the experience for keyboard users is usually a more than a little different. As a design engineer, my job is to weigh in and provide consultancy and recommendations to make sure the UI design works for users in different contexts. This means that I provide feedback to make sure keyboard user experiences, among others, are also considered. Designs are often tweaked if and when needed based on our UX discussions. But often times, us developers can make optimizations and improvements to accessibility and UX that don’t require design discussions and/or permissions. And when we can, we should. A user navigating and interacting with a UI using a mouse can usually move across the page with little effort — they literally move the cursor to where they want to. The mouse cursor ”hovers” above a page, so to speak. Unless you use a design anti-pattern, there are rarely any obstacles in their way, because most designs are usually optimized for their interactions. It doesn’t matter how many links there are on the page, they can go straight to the link they want, click it, and move on. A keyboard user, on the other hand, can’t go anywhere without going through a series of tab stops that you set for them. If they were a person standing infront of stairs, a keyboard user needs to walk up the stairs to get to their destination (compared to a mouse user who wears a pair of magical flying shoes or uses a Hoverboard to fly up the stairs 😅). The more steps the stairs have, the more steps they need to climb, the longer their journey, and the more cumbersome it can be. There are no shortcuts to go where they want to more quickly and efficiently… unless you provide them with shortcuts. I’ll elaborate on that in another post. In this post, I want to talk about markup and how it can sometimes be optimized for more efficient keyboard navigation. As an example, I want to talk about article listings. Blogs, online magazines and other publications will normally display lists of articles or posts. Browsing such publications, often you’ll notice a familiar pattern in most of those listings: a post entry has a typical anatomy normally consisting of: a thumbnail, a post title, author name, post tags, an excerpt or description, and a “read more” link, give or take one or more elements. So the post may include all of the above elements minus the thumbnail, for example. Or it might be composed of a thumbnail, a title, and a description only. It could also include a link to the comments section on the full article page. And so on. Typically, the thumbnail, post title and Read More link all link to the same page: the full article page, while the author name and list of tags post to their corresponding pages. If you’re a sighted mouse user and you want to read the full post, you click on either the thumnail, the title, or the Read More link to get there. You may even be able to click on the whole post if it is marked up for it. But how does this post anatomy affect a keyboard user? Navigating a list of posts with a keyboard If you use a keyboard to navigate a page containing a typical list of posts, you’ll notice that you sometimes need to tab through the same link two or three times in a row. To demonstrate, I recorded the exeprience of tabbing through the New York Times, Medium, and Forbes homepages: Sorry, your browser doesn't support embedded videos. Posts on the Forbes homepage contain three links per post: the the thumbnail, the post title, and an icon-only version of a “Read More” link. Clicking on any of these links takes the user to the full article page corresponding to this post. So, a user navigating using keyboard practically needs to tab through the same link three times in a row to continue navigating to the next post and whatever content comes after. The more posts there are, the longer the tabbing journey will be. Sorry, your browser doesn't support embedded videos. The New York Times homepage features a list of posts, each containing two focusable elements / links: a thumbnail, and a link that includes the text for both the title and post description. Both of these links take the user to the full article page. Sorry, your browser doesn't support embedded videos. On the Medium homepage, each post is made up of five links, three of which link to the full article page: the post thumbnail, the title, and the post description. Tabbing through these posts means the user needs to tab through the same link three times in a row. If you use a keyboard a lot, you’ll probably start to notice how redundant it is to tab through the same link multiple times in a row. If you’re wanting to get to a section that comes after the article listings on that page, you’ll need to tab quite a lot before you get there. When a list of posts is designed like with such a structure in mind, it is usually optimized for a sighted mouse/touch user. Such a user would have a generous collection of elements to click or tap, all leading to the same page that they probably eventually want to visit. But this design is not optimized for keyboard users. When a keyboard user needs to tab through the same link two or three times in a row they are slowed down because their journey becomes literally 200% or 300% longer than it could/should be. Depending on the post structure and anatomy, we can sometimes drastically improve the keyboard user experience with very little dev effort. Optimizing keyboard navigation using tabindex and aria-hidden Last Fall, I had the opportunity to work on an upcoming redesign of an online publication. I was hired to build a brand new front-end foundation for the design. I put a lot of emphasis on making sure the new design is implemented as accessibly and inclusively as possible. So, naturally, I wanted to make sure the experience is optimized for keyboard users as well. Being an online publication, it contains hundreds of articles, and those articles are displayed as a list of posts on the homepage and other pages of the site. There were more than a dozen article entries on the publication’s homepage. Each entry consisted of an image thumbnail (mostly decorational), a title, an author name, a description (without links), and a Read More link. This means that each entry contained three links to the full article page, and one link to the author’s page. In the process of testing a component at the bottom of the homepage for accessibility, I realized that tabbing through the page to get to that component took longer than I would like it to, due to the large number of post entries on the page. Sure, this tabbing experience is the typical experience on any and all similar Web sites I’ve ever visited. But just because it is the typical experience, doesn’t mean it can’t be improved upon. After a long discussion about usability and accessibility, I made a small addition to the markup that improves keyboard navigation by reducing the number of tabbable links. The number of links does not change; the tabbability of a link does. This means that a user navigating using a keyboard would only tab through one link to the full article page in each post instead of three, thus making the keyboard experience faster and more efficient overall. The implementation is simple: Prevent a link from being tabbed by using tabindex = "-1", and hide said link from screen readers using aria-hidden = "true", because you don’t want a screen reader to expose a link the user won’t be able to interact with. I applied this to the thumbnail images because they are not used to convey any particularly relevant information in an entry (they are more like decorational cover photos), and to the Read More links. Only the post title remains tabbable, as well as the link to the author page. So instead of having four tab stops in each entry, a user now has two. Thus tabbing through the long list of posts is going to be two times faster than what a typical experience would have been. The markup for each article entry looked something like this: <article class="post ..."> <a href="https://sarasoueidan.com/path/to/full-article/" class="post__thumb" aria-hidden="true" tabindex="-1"> <!-- img thumbnail... --> </a> <div class="post__content"> <a href="https://sarasoueidan.com/path/to/full-article/" class="post__title"> <h2 class="h3">Inspirational Website of the Week: Dean Bradshaw</h2> </a> <div class="post__excerpt"> <!-- ... --> </div> <a href="https://sarasoueidan.com/path/to/full-article/" class="post__more-link" aria-hidden="true" tabindex="-1"> <svg aria-hidden="true" focusable="false" width="16" height="7" viewBox="0 0 16 7"><!-- ... --></svg> </a> </div> </article> The following are two live codepens that you can tab through using a keyboard to see the difference between the typical default experience and the experience with the skipped links: See the Pen Demo for blog post: Optimizing keyboard navigation using tabindex and ARIA by Sara Soueidan (@SaraSoueidan) on CodePen. See the Pen Demo for blog post: Optimizing keyboard navigation using tabindex and ARIA by Sara Soueidan (@SaraSoueidan) on CodePen. One size does not fit all. Not all article listings are equal. In the examples above, there weren’t many links between each of the consecutive full article page links. In each of the examples, the post’s excerpt is short and does not contain any links, and there are no lists of tags following the post title and separating the title from the Read More link. Depending on how you set up your CMS or SSG to generate excerpts, they could be generated as plain text or full markup. For example, on this blog, the excerpts are generated as plain text, so they don’t contain any links. On codrops, the excerpts aren’t really excerpts — they are custom descriptions of an article, so, by design, they also don’t contain any links. But not all post excerpts or descriptions come without links. When there are several links between the title and the Read More link, it becomes important for the user to be able to use the Read More link. To demonstrate, I recorded the process of tabbing through Lea Verou’s Web site, where she shows a longer post excerpt per entry and containing quite a few links in some cases. Sorry, your browser doesn't support embedded videos. Tabbing through a post entry on Lea Verou’s Web site. If the Continue Reading link were not there on Lea’s post, a keyboard user would need to tab all the way back to the title to visit the full article page. In such a case, a Read More link does provide value and should not be deactivated. Because there are quite a few links after the post title in each entry, the Continue Reading link in Lea’s posts is essential for the keyboard experience. The link is a shortcut to the full article’s page now; had it not been there, or had it been skipped, the user would need to tab all the way back up to the post title to visit the full article, which would have been nonsensical. This is an example of when you do not want to use tabindex and ARIA to skip over a link because it would worsen the user experience. A few years back, I took a different approach to implementing post entries when I built Smashing Magazine’s front-end foundation. The posts were designed to be “cards”, and cards come with their own implementation considerations that I documented in my previous post about nested links. Each design comes with its own usability considerations that need to be taken into account. In order to improve an experience, you need test the design using a keyboard, and with real users if possible — they can usually provide a lot of insight that we designers/developers might miss. To sum up: Not all your users use a mouse to navigate your pages. The way you mark up your elements has a direct effect on how people interact with them. Links are focusable by default, but it might make sense to skip certain links if the design and user experience allows it. A good rule of thumb for similar cases is that if you have multiple consecutive links to the same page, there is probably a chance to improve keyboard navigation by skipping some of those links to reduce the number of tab stops to one. The less tab stops, the better, as long as it does not worsen or compromise on other aspects of usability. There is no one rule fits all. One approach might work for a design but not for another. And, once again: each design comes with its own challenges and considerations. Take those into account, weigh your options, test with real users, use a keyboard, and make optimizations when and where appropriate. At the end of the day, it should always be about the user experience.

Global and Component Style Settings with CSS Variables

Ever since I learned about CSS Variables a few years back, my absolute favorite feature has been the ability to scope variables to components. But to be honest, I haven't been putting this feature to much use over the years, until I created my own pattern library last year to speed up prototyping and client work. That’s where scoped CSS variables really shined for me. So I want to share my favorite two ways to use CSS Variables to organize and maintain styles in my projects today. Over the last few months, I’ve started approaching the way I organize and manage my CSS differently… Global Project Settings Today, at the beginning of each project, I create a _settings.scss stylesheet. This stylesheet contains the global settings for the project. These settings are usually derived from the design style guide provided by the design team I’d be working with. An example of visual settings defined in a style guide for my current client project. The style guide contains color swatches, brand colors, interaction and UI colors, font styles, type scales, spacing scales, icons, etc. I used the style guide as a starting point in my CSS, as I created and defined the global project styles by deriving their values from their visual equivalents in the style guide. Just like the style guide contains settings for visual styles like colors, box shadow styles, font styles, type scales, etc., the _settings stylesheet contains variables that serve as the code equivalent of those settings, and that are used across the CSS to maintain visual consistency across the project. :root { /* UI Colors */ --primary-hue: 12; --color--primary: hsl(var(--primary-hue), 100%, 44%); --color--primary--hover: hsl(var(--primary-hue), 100%, 39%); --color--primary--active: hsl(var(--primary-hue), 84%, 30%); /* ... */ --border-color: #ebebeb; /* Box Shadows */ --shadow-01: 0px 2px 4px rgba(37, 37, 37, 0.1); --shadow-02: 0px 4px 8px rgba(37, 37, 37, 0.1); --shadow-03: 0px 8px 16px rgba(37, 37, 37, 0.1); --shadow-04: 0px 16px 24px rgba(37, 37, 37, 0.1); --shadow-05: 0px 24px 32px rgba(37, 37, 37, 0.1); /* ... */ } An example of global style settings defined in a _settings.scss style sheet in my current client project. .card { /* ... */ box-shadow: var(--shadow-01); border: 1px solid var(--border-color); transition: box-shadow .2s linear; &:hover, &:focus { box-shadow: var(--shadow-03); } } If at any point during the project any of those settings need to change, I know exactly where to go make that change, and I know it will propagate consistently throughout my entire system. In addition to these settings, I’ve been finding the most value and convenience in using CSS variables to define local, component-scoped styles… Quicker Prototyping with “Skeleton” Components Over the years, and in the interest of saving myself time and speeding up prototyping ideas and client work, I’ve created a library of UI and design patterns that I find myself needing to recreate on most of my projects. The library now contains a growing collection of easily reusable UI patterns that I can reliably copy-paste into my projects when I need them. Each pattern is progressively enhanced using modern CSS and JavaScript, and is cross-browser and cross-platform accessible from the ground up. Since I created the library as an ‘internal’ project, it currently lives in a private Github repository, and behind a password on the .dev domain of my site. I named the library ‘Skeleton’, and I built it with Fractal. I’ve been using Fractal for a couple of years now. I chose it over other pattern library tools because it fit my needs perfectly — I wanted a tool that was unopinionated and flexible enough to allow me to set up and structure my project the way I wanted to. Fractal fit the description perfectly because it is agnostic as to the way I develop or the tools I use. And I was further sold on it after reading about how Rachel Andrew uses it to manage CSS using a pattern-first approach, which was exactly what I was going for. I particularly love that components can be nested into folders to make it easier to locate particular components, and how you structure the folders is completely up to you. I organize my patterns so that each pattern lives in its own directory, containing the component’s HTML template, CSS, and vanilla JavaScript files, along with any additional Fractal-specific assets (such as config files). Using this structure, each of my patterns is self-contained. And I can include and concatenate the pattern’s styles and scripts in my projects as I need. /* styles.scss */ @import "accordion"; @import "modal"; To quote Tyler Sticka in “Tips for Portable Patterns”: Patterns, like songs, are easier to remix when each master track is separated. My goal from creating this library is to create a tool that allows me to prototype faster, and that’s flexible and efficient enough to use across different projects. And since patterns are usually styled differently across my projects, I wanted a way to simplify the process of customizing or “configuring” them for each project. Enter CSS Variables. Scoped Component Settings Because I don’t want to spend a lot of time overriding and undoing styles when I use a pattern in a new project, I created this library with the components having little to no styling by default — mostly white (no colors), minimal spacing, and only borders where visually appropriate. So the patterns literally look like skeletons of sort, hence the name. Now when I need to use one of these components, I have little CSS to override before they’re ready to be plugged into the new project. For each pattern, I’ve found myself modifying the same properties whenever I needed to use it — like the font, colors (text, background, border), box shadow, spacing, etc. So I figured it would be useful and time-saving if I created variables for those properties, define those variables in the ‘root’ of the component, and ‘pass in’ the values for these variables when I use the pattern as I need. This way I can customize or theme the component by changing the property values in one rule set, instead of having to jump between multiple ones to do so. I use variables to abstract all styles that I usually need to override. So every property that changes across projects is usually “promoted” into a variable. Then, if, at any point during the project, I need to tweak a pattern’s style(s), I know exactly where to do it. This makes the styles for each pattern more readable and more maintainable, which is even more important for when someone else needs to modify the CSS. This approach works quite well with my approach to organizing my CSS files. I like to organize my CSS into separate style sheets per patterns, that includes all the pattern’s styles and responsive behavior. There will be exceptions to this rule... for example, styles for “atoms” (like buttons, input fields, etc.) that are re-used across patterns are defined in one style sheet. And even then, when an atom’s styling gets a little complex (e.g. styling a custom file upload input), I may create a separate style sheet for that. I’ll go into a little more detail about the way I organize my CSS in another article. Example Like most of you, I find myself creating a <select> element in almost all of my projects. As of last year, I use Scott Jehl’s cross-browser styling technique. I find that I mostly need to change the icon, border color, border radius, and background color the most. In every project, I also set a focus outline for interactive elements. The outline color also varies across projects. So, I promoted these properties into variables. For each property, I set a default or empty value and change that value when I use the component in a new project as I need. .c-custom-select { --icon: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2232%22%20height%3D%2232%22%20viewBox%3D%220%200%2032%2032%22%3E%0A%3Cpath%20fill%3D%22%23777%22%20d%3D%22M9.914%2011.086l-2.829%202.829%208.914%208.914%208.914-8.914-2.828-2.828-6.086%206.086z%22%3E%3C%2Fpath%3E%0A%3C%2Fsvg%3E%0A"); --icon--disabled: ; --border-color: currentColor; --border-color--disabled: ; --color--disabled: ; --border-radius: 0; --background-color: #fff; --gradient-background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%); --outline-color: hsl(265, 50%, 50%); --padding: .5em; } I like to think of this rule set as a settings object for the component. It makes theming the component faster by passing in the values you want. The rest of the rule sets for the select component contain fixed rules or styles that most likely won’t change across projects: .c-custom-select { -moz-appearance: none; -webkit-appearance: none; appearance: none; box-sizing: border-box; display: block; width: 100%; max-width: 100%; padding: var(--padding); padding-right: calc(var(--padding) * 3); font: inherit; color: inherit; line-height: 1.3; border: 1px solid var(--border-color); border-radius: var(--border-radius); background-color: var(--background-color); background-image: var(--icon), var(--gradient-background); background-repeat: no-repeat, repeat; background-position: right calc(var(--padding) * 1.5) top 50%, 0 0; background-size: 1em auto, 100%; } .c-custom-select::-ms-expand { display: none; } .c-custom-select:focus { outline: none; box-shadow: 0 0 0 3px var(--outline-color); box-shadow: 0 0 0 3px -moz-mac-focusring; } .c-custom-select:focus:not(:focus-visible) { box-shadow: none; } .c-custom-select:disabled, .c-custom-select[aria-disabled=true] { color: var(--color--disabled); background-image: var(--icon--disabled), linear-gradient(to bottom, #ffffff 0%,#e5e5e5 100%); } .c-custom-select:disabled:hover, .c-custom-select[aria-disabled=true] { border-color: var(--border-color--disabled); } Moving Forward As much as I’d love to do this in all of my projects, unfortunately I can only use this approach to styling and managing component CSS in my own projects at the time being. The reason for that is that most of my clients still need to support at least one or two versions of IE, which have no support for CSS Variables. And while there is a polyfill for CSS Variables, the polyfill only provides support for variables defined on the root HTML element. Depending on the level of support and optimization we need for the IEs, I currently reach for the polyfill and use CSS Variables at least for defining global project styles. I see myself using this approach to style management in the future in combination with Web Components to create overall more portable patterns. And hopefully, some time in the future we’ll have container queries to make these components truly self-contained. As for Skeleton, it still has a long way to go. My goal is to create a custom Fractal theme to go with it. I haven’t yet found a good and complete guide on how to do this, especially since I’m looking to create a theme from scratch so I have full control over its styles. If you know me, you know I’ll probably write that guide once I figure out how to create a theme from scratch. I’m also constantly working on adding more patterns and variations of patterns. And I plan on including a Snippets section which includes code snippets I also frequently use in projects, such as JavaScript patterns and functions. And of course, I want to go heavy on documentation, including adding posts about best practices such as perf optimization techniques, icon and images best practices, etc., and I’ve already started drafting most of these ideas. I may or may not turn the library into a shareable product at some point in the future. But this is not something on its roadmap at the moment. For now, I like the idea of this being a small personal project with no strings attached. That said, I would love to publish the library as an npm package (for private use to start). I’m not familiar with how to do this yet. But I found an article on CloudFour that dives into doing this exact thing, so that will probably be my starting point. And I will definitely document my process as I figure my way around doing it. Update: June 8th 2020 Heads up: using scoped CSS variables also has performance benefits because setting & modifying variables defined on a global scope can be expensive & have performance pitfalls due to large amounts of style recalculations. Lisi Linhart has an excellent writeup about the performance of CSS variables as well recommendations to avoid any performance hits.

What a Year of Learning and Teaching Accessibility Taught Me

(This article was originally published on 24accessibility). because I didn't know better. Fast forward to today, I know enough to be able to write, speak and run workshops on accessibility, helping others build more a accessible and inclusive Web. Much like everyone else in our field, I am still learning. But since I started, I learned a lot of valuable lessons and core values that drive my work today. Here are a few of them. Semantic HTML is the foundation of a truly accessible Web. Semantic HTML is the universal language that all devices accessing the internet understand. It is the language you use to communicate your content to these various devices, including but not limited to browsers, reading apps, screen readers, smart watches, and more. HTML is semantic, or in other words, it is descriptive and provides meaning — each HTML element describes the type of content it presents. So if you have a heading, you use a heading element. If you have a paragraph, you use a <p> tag. In other words, it means using the correct HTML elements for their correct purpose. By using correct elements, your document content will have conveyable structure and meaning. Structure is important because it helps interoperability. Interoperability is the ability of different systems, devices, applications or products to connect and communicate in a coordinated way, without effort from the end user. In other words, it allows more devices to interpret and access your content, including devices that will show up in the future. Structure helps applications like reading apps and reader modes (such as Safari’s reader mode) as well as environments like Windows High Contrast Mode understand your content and style it in ways that improve the user experience. This is only possible when the proper HTML semantic elements are used, such as <article>, <h1>, <ul>, <aside>, <nav>, among many others available in HTML5. These elements describe the type of content they contain. Without them, these applications wouldn’t be able to tell what that content is, and therefore won’t be able to style it properly. This increases the risk of making the content less accessible, if not completely inaccessible. A Web page by Mandy Michael demonstrating how an article is styled in the app Instapaper when that article is marked up using semanticless divs (left) and semantic HTML elements (right). (Source) Structure is also important because it allows your users to navigate your content more efficiently. Screen reader users rely on proper document structure to jump to areas of the page they need more quickly. They do that using various quick/hot keys — power commands but for screen reader users. If you don’t use proper landmarks (exposed to screen readers via semantic HTML elements like <nav> and <main> and <header>), screen reader users may not be able to efficiently navigate the page and would have to search for their areas of interest more tediously. VoiceOver’s rotor menu exposes all landmarks available on a Web page, allowing the user to easily jump to the part of the page they need. Headings also provide an outline or “skeleton” of the page that users can navigate using hot keys, and which is similar to the visual hierarchy sighted users get from viewing your page. We This is why using appropriate heading levels, regardless of what the heading size looks like. (Note that while we can style headings to look differently where needed, visual consistency is just as important.) VoiceOver’s rotor menu exposes all headings available on a Web page, allowing the user to navigate the page more efficiently. Semantics also convey purpose. HTML elements, as Jeremy Keith puts it in his Web book “Resilient Web Design” are a vocabulary of meaning. When you use the proper HTML elements everywhere, it allows different apps and devices to convey your content’s meaning to the user so that they know what to expect of it and how to interact with it. For example, when you use <button> to create a button, a screen reader exposes that button as what it is, and the user knows that they can do a specific action using that button (usually specified using the button’s accessible name) by either pressing the SPACE key or the ENTER key. The native <button> element comes with all the functionality and accessibility built into it by default. But if you don’t use a <button> to create a button, and you choose to use a <div>, for example, instead, you lose all the built-in semantics and keyboard interactivity, making the button completely inaccessible to screen readers. “But you can use ARIA attributes to turn a div into a button! Right?” Well, yes and no… ARIA is a polyfill for HTML semantics. ARIA attributes are possibly the most powerful tool in our accessibility arsenal. Many ARIA attributes mirror native HTML semantics, while others provide semantics that do not natively exist in HTML. They don’t change behavior or add functionality. They don’t make an element focusable or add keyboard behavior, for example. So if you do choose to go the route of making a button out of a div, you’re gonna have to add that functionality yourself using JavaScript. But why create a brittle implementation of something that is already provided to you by default? The first rule of ARIA states: already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so. So while we should defer to using native HTML elements whenever possible, there are certain widgets that we can only build with the help of ARIA. For instance, there are no native HTML equivalents for Tab widgets (e.g. markup consisting of role=tab, tablist and tabpanel) — with all the interactivity built into them by default, so we can create tabs by repurposing other elements with ARIA and exposing them combined as a tabbed UI to screen reader users (e.g. role=“tab”, role=“tablist”, etc.) Because ARIA fundamentally changes the exposed semantics and accessibility mappings of elements, if incorrectly used, it can have negative impacts on the way content is exposed to people using assistive technologies. Scott O’Hara, referencing the ARIA Practicing Guidelines notes: ARIA practices first principlal states "A role is a promise". <p>When using ARIA, or even HTML for that matter, think about what you're promising the people who use your interface or consume your documents.</p> <p>Are you fulfilling the promises you are making?</p> Before using ARIA attributes, think about what you’re promising your users. ARIA attributes directly affect how elements are exposed in the accessibility tree, and therefore how they are communicated to your users. Use them wisely and sparingly, and make sure that what you’ve built meets the expectations you’ve created for your users. If you need pointers as to how to use and not use them, the Using ARIA document is a great place to start. @LeonieWatson - there are about 147 HTML elements and only two of them have no built in accessibility features - <div> and <span>. Use the right semantic elements as much as possible! — Beth Fraser Simplest #a11y advice I've ever received: the div is your last resort. Is this your main content? There's a tag for that. Is it your header? That's got a tag, too. The div isn't bad; it just doesn't mean anything. That means you certainly don't need it for something clickable! Assume your content has a specific meaning and try to find the tag for that meaning. If it doesn't, then the div (or span) is what you want! The div does have a place. That place is not what many tutorials would have you believe. — E.J. Mason JavaScript is imperative for creating truly accessible custom interactive components. Even though you can get away with creating “functional” interactive components such as a CSS-only modal overlay or a disclosure widget using the infamous checkbox hack, it is almost always guaranteed that those CSS-only components are not truly accessible. When you create an interactive widget, that widget is most likely to have a state. A disclosure widget is either “open” or “closed” (or “expanded/collapsed”). That state is exposed to screen reader users using ARIA attributes (e.g. aria-expanded= "true/false), and when a user interacts with the widget, the state changes, and that change needs to be conveyed to the user. JavaScript is needed to do that. I made peace with this fact two years ago when I needed to create an accessible tooltip for one of my clients. JavaScript is also needed to add keyboard functionality to custom components (e.g. tabs in a tabbed interface need to be nagivatable by arrow keys, and a disclosure widget needs to be operable using SPACE and ENTER keys). Side note: Even though JavaScript is a requirement for creating interactive custom components, in order to make sure that your content is inclusive of all users regardless of their context, you can, and probably should — whenever possible — make sure that they can consume that content when JavaScript is not available. In fact, you should never assume that your users will have JavaScript, as there are plenty of reasons why they might not. This is why progressive enhancement is the most accessible strategy for building for the Web. I would even go as far as saying that it is a requirement, in some cases, for creating inclusive documents and components. Progressive enhancement is an inclusive strategy for building for the Web. There seems to be a misconception among many developers that just because JavaScript is required to make an interactive component accessible then you cannot possibly build it with progressive enhancement as an approach. The reason for that is that those developers think that Progressive Enhancement is anti-JavaScript. That is a fallacy. Progressive enhancement is about layering — starting with the most resilient base — semantic HTML! — and then layering styles (CSS) and functionality (JavaScript!) on top as appropriate. But what progressive enhancement achieves is having a resilient layer of content that will always be accessible, even when the CSS and/or JavaScript are absent. From the first day that I learned about progressive enhancement, it’s become my go-to strategy for building Web interfaces. I can’t imagine creating for the Web another way. And when I started building with accessibility in mind, I was convinced that it is the most sensible approach to developing for the Web. Let’s take a Tabs component again as an example. In a tabbed component, you have a series of tabs that control their respective content panels. The user can navigate between these panels by clicking on the tab they want. Tabs require JavaScript to be operable and accessible. But what if JavaScript does not work? If the Tabs were not progressively enhanced — if they were built with the assumption that JavaScript would always be there, then the component will fail to function and the content in all the hidden panels will be completely inaccessible. But if think about Tabs from a progressive enhancement point of view, you’ll want to consider what the content inside of it would look like had it been only created using HTML — without the CSS that adds the Tabbed UI affordances, and without the JavaScript that makes it behave like typical tabs. In this case, you may think of the tabs and panels as a series of sections, each with a title and content. These sections may or may not have a table of contents at the top. This would be the default “view”, and is what the user gets by default when the JavaScript doesn’t work. A tabs component may be enhanced from a series of sections, each with a title and some related content. A tabs component may also be enhanced from a series of sections, each with a title and some related content, with a table of contents preceding these sections. Then, when the JavaScript runs, you can enhance those sections by changing their layout and display, and adding the required interactivity. The way I would do it is I would probably add a style hook I want in the markup, and then I’d use that to change the layout of my sections knowing that the JavaScript has run and the Tabs will be operable and interactive. When you shift accessibility to the left of your process, using progressive enhancement as a development strategy makes even more sense. Pretty much every single non-native interactive component I have built over the past year has been enhanced from a basic non-interactive component. Start with HTMl first. Utilize everything it has to offer to provide an accessible basic experience. Then enhance with CSS and JavaScript when they are available. Progressive enhancement. Because sometimes your JavaScript just won’t work. Be prepared. — @sil Design does not always dictate implementation. One of the most common ways I see semantics broken is when they are derived from the visual design. Because the visual design does not always describe the type of content it is representing. Headings are a perfect example here. In a recent talk I gave, I showed an example from one of my latest client projects, where the page was designed in a way that a main heading for the page was seemingly non-existent, when in fact it wasn’t. It was just not styled like a large level one heading normally would. Thinking about the document structure and screen reader user expectations, I knew the page needed to have a main heading. While I had to provide a heading for screen reader users only for some other pages where one was visually absent, in this particular case the heading was already there, it was just styled to look different. So it looked like the page didn’t have a main heading, but in reality it did. Looking at the page through the lens of accessibility and keeping the HTML layer — semantics and structure — in mind, changed the way I saw the page, and fundamentally changed how I ended up coding it. So just because a component or element looks a certain way doesn’t mean that it is. And just because it doesn’t look a certain way, doesn’t mean that it isn’t. The same is true for interactive UI patterns. The same pattern may create a different experience depending on the context it is in. And often times the context defines how a pattern should behave, what the user experience should be like, and that, in turn, determines what the underlying semantics should be, and that drives implementation. In the same project I just mentioned, there was a seemingly simple UI pattern that turned out to be quite an interesting UX and accessibility challenge. The following image is a screenshot of that component: The featured videos component in my recent client project shows a video on the left with a playlist of videos on the right. Clicking on any of the video titles on the right would load the video on the left; but it would not autoplay it. (Note that the content in this screenshot is dummy.) In order to implement this video player, I needed to know how it worked, so I can mark it up in a way that conveys its semantics and functionality to screen readers properly. Even though the list of video titles on the right looks like a list of links, it is not really a list of links, because a link is supposed to take you somewhere, but these “links” don’t. Clicking on a video title would load that title in the player on the left. So it is an interactive element that performs an action and that is not a link. Therefore, and even though their appearance doesn’t show it, these titles are actually buttons. Then there was the question of what happens when a title is clicked? does the video autoplay? If it does, then the button should probably also pause the video, making it a type of a toggle button. But if you play/pause a video from the title button, you’d want to associate that button to the play/pause buttons inside the video itself, which can be a challenge given that the video could be a Youtube video, or a Vimeo video, or self-hosted. And if you don’t autoplay the video, should you move focus to the iframe after the button is clicked? After reviewing the intended UX and testing with screen readers, I ended up implementing it as a tabs component, with all tabs controlling the one panel containing the video. I had never thought about a tabbed interface with multiple tabs controlling the same one panel before. But the context of this component and the UX of it triggered a train of thought and UX considerations that drove the final implementation. So one of the things that I learned from this component was that the UX drives the implementation. ARIA comes with a lot of attributes that enable us to create different UI patterns in different contexts, and sometimes all we need to do is modify the pattern a little bit to work in the context it is in. It’s weird that we still derive the semantics from a visual design instead of the other way around. The visual design is different per context while the core semantics are not. — Rik Schennink Just because it is technically accessible, doesn’t mean it is inclusive. You can build something that is technically accessible but isn’t inclusive. That element or component may have all the buttons you want and you may be able to navigate it using a keyboard and use it with a screen reader, but did you really take your user’s needs and expectations into consideration when you made the decisions about how and what of that element should be exposed and interacted with? In his talk “Inclusive by Design”, Derek Featherstone, accessibility advocate and designer, talks about how he and his team built an accessible video player for an organization that they were contracted by. The video player had lots of buttons and was tested for technical accessibility over many phases. But then when the time came and the component needed to be used by users with different disabilities, they realized that, even though they had built the perfect accessible video player, that video player was not truly inclusive — it was missing certain functionality that made using the player easier for a group of users, such as a Rewind or Fast Forward button. Derek and his team had also made assumptions about how all users would be using the video player, and forgot about the users that were using an older version of a screen reader and who were therefore missing important announcements that were supposed to help them operate the video player. So after several iterations and tests with various users, they ended up adding features to the video player that would take many more disabilities into account, and expectations that those users would have of the player, and that made it far more inclusive and tremendously improved its user experience. Derek’s talk is full of such good examples that emphasize the importance of including your users early in the design process, and making sure that you embrace diversity by default. The idea is that if you’re designing something for me, I should have a reasonably meaningful way of participating in that thing. I should be represented in that somehow. - Michael Masutha At the end of the day, it is always about the user. As you develop with real user experiences and inclusivity in mind, you’ll soon realize that a design pattern can be built in more than just one way. And there are quite a few things in accessible design that are opinionated. Modal overlays are a great example. Regardless of being an annoying UI pattern, there are quite a few discussions around how they should be implemented and how they should behave once they are opened: Should you focus the first focusable element inside the modal? What if there is no focusable element? What if the first focusable element is the close button? Would you want the modal overlay to prompt a closing action as soon as it’s opened? (Of course not.) What if the first focusable element is an input field asking the user for their email address? Is it appropriate to prompt the user for their personal information without context first? (Also of course not.) At the end of the day, no matter what decision you end up making, it should always be about the user. So getting the user and/or a more diverse team involved in the design and development process is crucial in building truly inclusive Web interfaces. But what if you can’t? What if you don’t have access to such an environment or team? What if, like me, you’re a solo developer who often joins teams that usually don’t have users or disabled people involved? When in doubt, ask for help. If you can’t do it yourself, you can seek the experience and advice of other people who can. And it is very important for you to be open to constructive feedback. There are quite a bunch of wonderful (and sometimes understandably grumpy) accessibility experts in our field who want the Web to be and become more accessible. Most of them have been doing free work like giving free advice and sharing their valuable knowledge in various forms — writing articles and books, making video courses, giving talks and workshops, etc. And there is a lot that we can learn from them. And most of them welcome questions and inquiries (paid and free). Some of my go-to experts are (in no particular order): Leonie Watson Derek Featherstone Scott O’Hara Marcy Sutton Rob Dodson Alice Boxhall Marco Zehe Eric Bailey Steve Faulkner The Paciello Group You’d do well to spend some time reading the ARIA specifications and guidelines, and trying to get acquainted with as much about accessibility as you can, before asking for help. After all, these kind people may be able to help us, but they shouldn’t have to do our work for us — at least not for free. Final Words Accessibility isn’t easy. And often times it is downright hard. But that comes with the territory. Designing for humans is hard. And accessibility is, at the end of the day, all about and all for humans. We may not get it completely right, and there may always be room for improvement — especially as more users use our products and consume our content, but one thing I know is that that should never discourage us. Almost everything can be improved in one way or another. The most important thing is to be open to feedback and to be empathetic enough to care about our users and try our best to make their lives easier with the (powerful) tools we have at our disposal. Use HTML. Enhance with CSS. Leverage the power of JavaScript. And include your users in your design process as early as possible. And always look at your work through the lens of inclusion. This will take you far ahead. Then learn more, iterate, and improve. And don’t forget, we’re all just temporarily abled. –>

Case Study: Implementing Accessible Data Charts for the Khan Academy 2018 Annual Report

A few months ago I teamed up with SuperFriendly to create an accessible micro-site for the Khan Academy 2018 Annual Report. The site is a very beautiful visual representation of Khan’s real-life impact on world education, their end-of-year financial reports, and more. By nature, the annual report contains a lot of data and visualizations and charts to represent it. My mission was to make sure that the way this data is presented and implemented is as accessible to site’s visitors as possible, regardless of how they explore the site. Data visualizations are a great way to make information stand out and sometimes a lot easier to parse and understand. But they also come with their own accessibility challenges that you need to be aware of. The Khan Academy annual report represented all of the main data showcasing the impact they had on world education using different kinds of charts — simple and complex. When it comes to visualizing data on the Web, SVG is the most used format. It is perfect for creating data visualizations because it comes with all the elements needed to create the shapes used to represent information. Because SVG is an XML format, similar to HTML, it comes with a lot of tags to represent different kinds of elements, mostly shapes. We have elements for creating basic shapes such as circle s, ellipse s, rect angles, polygon s, polyline s, line s, and more complex path s, all of which are used to draw all kinds of data charts and visualizations. And often times, these charts and visualizations are also animated and interactive; and SVG provides us with the ability to animate and interact with the images we create with it — using CSS and JavaScript. But SVG data visualizations are, at the end of the day, SVG images. This means that when a screen reader comes across one, it is likely going to announce it the same way it would announce any image: as an image, with an accessible name (because I’m assuming that the image does have an accessible name provided in the alt attribute). This, in turn, means that the screen reader is not going to announce the content presented inside the chart to the user by default. It is only going to announce whatever accessible name we provide it with. Making sure it announces the content inside the image is something that requires a little more work on our side. How accessible are SVG data visualizations & charts? Albeit being a perfect candidate for visually representing information, SVG is not equipped with the semantics needed to convey the content of that information to the user. In her article about creating accessible line graphs with SVG, Léonie Watson says: Léonie wrote a few articles about making content inside SVG accessible that I will link to at the bottom of this article. The concept in all of them is the same: use some of the available ARIA roles to modify the semantics of SVG elements to be announced to screen readers as something other than what they are. — Léonie Watson, Accessible SVG Tables For example, in her article, she uses the ARIA table attributes to announce a visual line graph as a table to screen reader users, which makes it possible for them to announce the data inside those tables to their users as well. This is possible because a table is often times an appropriate alternative way to represent the information in a line graph. But Léonie finally notes (and emphasis is mine here) that: “The state of SVG accessibility support in browsers and screen readers is still highly inconsistent, even when ARIA is used to polyfill semantic information. The upshot is that this technique is enough to make the primary SVG content more screen reader accessible […] but it isn’t enough to make it completely so. For this (and many other good reasons), it’s a good idea to provide an alternative view of the information, for example by providing both a graphical and a tabular view of the content” Personally, I’d avoid hacking my way around making an SVG chart accessible using ARIA roles. Most of the charts in the Khan Academy annual report were more complex, so using ARIA roles to change their semantics would not only prove to be counter-productive, but also risky, especially given how inconsistent screen reader and browser support is, and how important those charts are for the site’s visitors. So, I chose the alternative view of the information route. And with all the different SVG embedding techniques available to use, SVG makes all kinds of fallbacks easy to implement. Choosing the most appropriate SVG embedding technique There are 6 ways to embed an SVG on a Web page. Choosing the most appropriate one highly depends on your requirements and what you need the SVG to be capable of and the kind of fallback that you need. For data visualizations and infographics, it’s usually best to provide the plain text (or table) version of the content of the image as fallback. Since that text fallback is likely to be more than one or two sentences long, we need to embed the SVG using an embedding technique that caters for that. We were also planning on animating the charts had the project timeframe allowed it. This means that the embedding technique also needs to allow that. And I know that we will need JavaScript for the animation, which also narrows down my embedding options further. <iframe> , <object> and inline <svg> all tick all of the above boxes. I’m not a big fan of <iframe> s, and <object> already gives me everything I need that <iframe> does, so, out of these two, I always choose <object> . In addition to the above requirements, I had a couple of other considerations in mind: we have a lot of charts, especially on the leveling the playing field page, and some of those charts are quite larger than the others. So I’ll want to keep page load and performance in mind. If I were to embed the charts inline, they would “pollute” my HTML, and would not be cached unless the whole page is. That’s not ideal. Whereas an <object> would reference an external SVG image which, after the first request, would then be cached, making subsequent visits faster. Also, on a more design-related note: I was working with SVG images exported from Adobe Illustrator, which tends to repeatedly create and use the same IDs and CSS class names for the images it exports. If I were to embed all of the images inline, the IDs and class names would clash and I would need to spend time I didn’t have to go over each SVG and provide it with unique class names to avoid the style inheritance nightmare, because, by default: Styles within an inline <svg> are not scoped to it. This means that if you have two inline svg s on the page, the styles from the second SVG in the DOM order will override the styles in the first one for elements with shared class names. And last but not least, I love the clean and uncluttered way that <object> enables me to provide text fallback for my SVG images: simply place the text fallback in between the opening and closing object tags, and that text will be displayed wherever SVG is not supported and/or whenever the SVG fails to load. So, <object> it is. Embedding the charts The initial base code for one of the simple charts would then look like this: < object type="image/svg+xml" data="/images/long_beach.svg"> <p>Khan Academy math usage for 30 minutes per week proved to improve more than 5,000 Long Beach students scores by 2 times in the Smarter Balanced Assessment.</p> < /object> This was just the base markup, but I was curious enough to check how it would be announced by a screen reader. I’m on macOS so I usually test my work with VoiceOver (VO) on Safari. VO announced the chart as a frame, and used the file name of the SVG (in this case long_beach.svg ) as the accessible name for it. Ouch. I was expecting the random name situation since my markup doesn’t yet include a label for the image, but I didn’t know how an object is usually announced. I was also curious if VO would somehow recognize or find the fallback text and announce it. It didn’t. Now, it was time to start “fixing” the situation. I want my chart to be announced as an image to start, so I needed to modify its semantics using ARIA role . To give it an accessible name, I used aria-label : < object role="img" aria-label=“Khan Academy Math usage level in Long Beach. Chart." type="image/svg+xml" data="/images/long_beach.svg"> <p>Khan Academy math usage for 30 minutes per week proved to improve more than 5,000 Long Beach students scores by 2 times in the Smarter Balanced Assessment.</p> < /object> With these two attributes added, VO communicated my chart as an image, and used the label I gave it as its accessible name. Great. But a visitor using VO would now know that there is a chart showing Math usage levels in Long Beach, but they would not be able to access the data inside that chart. Since I already have a text fallback clearly describing the data in the chart right there in my markup, I thought I could use that instead of try to communicate the same content in a second way. That text fallback was not being exposed to my screen reader. In other words, it was hidden from screen readers. But I already know that I can expose hidden content to my screen reader to announce if I reference that content inside of aria-labelledby . I’ve used this in my previous article to provide a visually-hidden accessible label to an icon-only button. So it makes sense that I’d be able to do the same using aria-describedby . There are several reasons why I’d want the image’s text content exposed using aria-describedby not aria-labelledby : aria-labelledby is used to provide an accessible label to an element. My image already has one that I have provided in aria-label . The text content is used to describe the (content of) the image. An accessible name (label) should be short and succinct. A description is usually longer, especially (and particularly) in the case of text (or table!) provided for charts and visualizations. And, last but not least, I want the text content to be announced after the image and its accessible name are. That’s exactly what aria-describedby does. aria-labelledby is announced versus that referenced in aria-describedby. The accessible name is announced before the image’s role is announced (in VO, at least); the description is announced after the image’s role, with a short pause preceding it. That’s exactly how I want my text to be announced. So, with all that taken into account, the final code for my chart looks like this: < object role="img" aria-label=“Khan Academy Math usage level in Long Beach. Chart." aria-describedby="long_beach_desc" type="image/svg+xml" data="/images/long_beach.svg"> <p id="long_beach_desc">Khan Academy math usage for 30 minutes per week proved to improve more than 5,000 Long Beach students scores by 2 times in the Smarter Balanced Assessment.</p> < /object> This works very well, including for images that have longer descriptions. Of course, we made sure (thanks, Jessi) that the descriptions were as concise and succinct as possible, so the user is not overwhelmed with long announcements but would still get a very clear and accurate text version of the information provided in each chart. “Can’t you just use <figure> for the charts?” I got this question a couple of times after speaking about my implementation choice above — once during a workshop, and once after a talk. I’m guessing that the idea here is that you would implement the SVG chart in an img inside a figure and use the figure ’s figcaption to provide the text alternative of the chart’s content to screen reader users. I assume the suggestion would be to hide the figcaption in this case visually (because we don’t show it visually, of course) and make it available to screen readers only, using a utility class such as sr-only . < !-- This is what you should NOT do.--> < figure> <img src="https://sarasoueidan.com/path/to/chart.svg" alt="ACCESSIBLE_CHART_TITLE" /> <figcaption class="sr-only"> Here goes the text that describes the information inside the chart. Note that this text could be a couple of a few paragprahs long. It might even be appropriate to represent the data using a table! /* * Utility class to hide content visually while keeping it screen reader-accessible. * Source: https://www.scottohara.me/blog/2017/04/14/inclusively-hidden.html */ .sr-only:not(:focus):not(:active) { clip: rect(0 0 0 0); clip-path: inset(100%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; } This approach has more than one issue. I didn’t choose <figure> because I excluded all SVG embedding options that don’t allow the SVG charts to be animated. <figure> is static — meaning that it won’t allow the would-be SVG img inside of it to be animated. I also didn’t consider <figure> as an option because a figure is, by definition, meant to be a meaningful wrapper for a piece of content that is relevant to the current document, but not vital to its understanding. [The figure element] can thus be used to annotate illustrations, diagrams, photos, code listings, etc, that are referred to from the main content of the document, but that could, without affecting the flow of the document, be moved away from that primary content, ... — HTML5: Edition for Web Authors Khan Academy’s annual report charts are vital to the understanding of the page they’re in, and cannot be removed from the primary document without affecting it. The data inside these charts is the meat of the annual report. So, as far as semantics are concerned, figure is not an element suitable to represent these charts. The figure ’s figcaption is used by screen readers as the accessible name of the _ figure _. As I mentioned earlier, the text fallback for the charts is not meant to be used as a name (label), and it should be announced as a description, not a name. Furthermore, the markup for the figure would have to be very dirty even if using it were possible, because the text that goes in the figcaption needs to be provided inside an aria-label on the figure alongside a role attribute for certain browser-screen-reader combinations to even announce figure as it is intended to be announced; and this brings us again to the “but the text inside figcaption is not even a label for the figure element” argument.. My friend Scott O’Hara has a wonderful article about figure and figcaption detailing how to use and not use them, and how to ensure the best cross-browser and screen reader compatibility. I highly recommend checking it out. When it comes to accessibility, semantics matter a lot. Learning about an element’s semantics and proper usage helps us make better informed decisions as to which element to use when. Final Words I had great fun working on the Khan Academy annual report, and I learned quite a bit in the process. Khan Academy’s mission is to provide free education for everyone everywhere. In other words, they are working to make world-class education accessible by everyone. The least I could do is to make sure the product I helped build for them was just as accessible by everyone, regardless of their context and abilities. I’m quite proud of the work we did. And if you could use my help building better, more accessible products, get in touch. And if you want to be the first to know when the next article comes out (hint: there will be more like this one), you can subscribe to my blog’s RSS feed. Thank you for reading. Further Reading Inclusively Hidden How do you figure? Accessible SVG Tables Accessible SVG Line Graphs Accessible SVG Flowcharts

Accessible Icon Buttons

An icon button is an icon that triggers some sort of action on the page. More accurately, technically speaking, an icon button is a button that contains an icon and no (visible) accompanying text. These buttons can be found in the majority of app and user interfaces today. The infamous hamburger menu button is a great example of such buttons when not visually labelled “Menu”. Twitter’s Compose Tweet icons are an example of icon-only buttons in the wild. Putting aside the UX side of the coin and whether or not an icon alone is enough to convey meaning and functionality to users, many implementations of these buttons today lack the proper accessibility that makes them meaningful to users of assistive technologies. While the seemingly popular aria-label is a perfectly valid way to add an accessible name to a button (and/or other components), it is certainly not the only way, let alone the best. You could always just put text in it, for example. But what if the designer or the UI enforces the absence of visual text next to an icon? There is a handful of ways that an icon button can be implemented accessibly. This article is an overview of them all. Accessible Button Names A button is announced to screen readers as a button when the proper element — the almighty <button> is used, or when an element has a role = "button" on it. Either way, when a button is announced as one, users expect to be able to interact with it in a certain way, which includes being able to activate the button using either the ENTER or SPACE keys. This means that if you choose not to use the native <button> element, you’ll need to reimplement that native behavior and functionality yourself using JavaScript. But who would want to create a brittle implementation of features that are provided to them by default by the browser when they can save both time and effort using a simple <button> , right? ; ) Inspecting the Button Name in Chrome Devtools To inspect what the accessible name of a button is and, therefore, how it will be announced by a screen reader, you can use the Chrome devtools. Next to the Style tab, you’ll find an “Accessibility“ tab, inside which you will find something that looks like this: The accessible name for the button can be defined in several ways, as you can see in the image above. When you put plain text inside the button, that text content can then be used as a name for the button, which is then announced: Send Message, Button by VoiceOver. The popup shows what VoiceOver on Mac announces a button that has “Send Message” text in it.The button is announced by its name first and then its role (button). You can inspect the button below yourself and check the accessible name in the devtools, and fire up your screen reader of choice to see how it is announced. Send Message Now, what happens when we have an icon inside the button? Icon Sitting Next to Text This post is about icon-only buttons. But it’s worth starting with buttons that contain an icon sitting next to some text. When a button contains text, that text is going to be used to create an accessible name for the button. That text should usually be enough to convey what the button does to screen readers. As such, the icon itself (an svg image) could become irrelevant to screen reader users, as it does not clarify or add to the accessible name of the button. As such, the common practice is to hide it from screen readers using aria-hidden : <button aria-expanded="false" id="menu-trigger"> <svg viewBox="0 0 32 32" width="32px" height="32px" aria-hidden="true" focusable="false"> <!-- svg content --> </svg> Menu </button> The aria-hidden attribute is used to indicate whether an element is exposed to screen readers or not. When set to “true”, the element and its contents are hidden from the accessibility API, regardless of whether or not it is visually displayed. The svg also has a focusable attribute set to false which prevents the icon itself from receiving focus in IE, because otherwise the button will have two Tab stops, which is not the expected or desired behavior. Further Reading: HTML5 Accessibility Chops: hidden and aria-hidden Hiding elements from screen readers using aria-hidden Know your ARIA: ‘Hidden’ vs ‘None’ Now, if the button does not have any visible text, you’ll still need to provide an accessible name for it somehow. There are a few different ways to do that. Technique #1: Accessible Visually Hidden Text If your button isn’t supposed to visually contain any text, you can still provide the text inside the <button> so that it’s picked up and used by screen readers, while hiding it visually using CSS. There are a few ways to hide content visually. You’ll want to make sure you hide the text but also keep it accessible to screen readers. My friend Scott O’Hara has written a fantastic article that covers how to hide content accessibly that is definitely worth bookmarking and checking out to learn more about the topic. Our icon button markup might now look like this: <button> <svg viewBox="0 0 32 32" width="32px" height="32px" aria-hidden="true" focusable="false"> <!-- svg content --> </svg> <span class="visually-hidden">Menu</span> </button> Note that we’ll still want to always prevent the svg from receiving focus in IE using the focusable attribute. Using a utility CSS class that I usually call visually-hidden (short for “screen reader only”), we hide the text visually while making sure it can still be picked up and used by screen readers: /* * Utility class to hide content visually while keeping it screen reader-accessible. * Source: https://www.scottohara.me/blog/2017/04/14/inclusively-hidden.html */ .visually-hidden:not(:focus):not(:active) { clip: rect(0 0 0 0); clip-path: inset(100%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; } I borrowed this class from Scott’s article: The above “sr-only” class is utilizing various declarations to shrink an element into a 1px square, hiding any overflow, and absolutely positioning the element to remove any trace of it from the normal document flow. The :not portions of the selector are allowing a means for any focusable element to become visible when focused/active by a user. So elements that normally can’t receive focus, like paragraphs, will not become visible if a user navigates through content via screen reader controls or the Tab key, but natively focusable elements, or elements with a non-negative tabindex will have these elements appear in the DOM on focus. VoiceOver will announce Menu, Button, and the devtools will confirm that the text inside the button is used to provide an accessible name to it: You can try it yourself by inspecting the following button: Menu Further Reading: Inclusively Hidden ARIA14: Using aria-label to provide an invisible label where a visible label cannot be used Technique #2: Accessible Visually Hidden Text with hidden and aria-labelledby This technique is similar to Technique #1 with one advantage over it: you don’t need to use a CSS utility class to hide the text visually. This technique uses the hidden attribute to hide the button text: <button class="menu-trigger" aria-labelledby="button-label"> <span id="button-label" hidden>Menu</span> <svg aria-hidden="true" focusable="false" width="24" height="28" viewBox="0 0 24 28"> <!-- svg content --> </svg> </button> The hidden attribute is a boolean attribute. When specified on an element, it hides that element both visually and from assistive tech. It is the HTML5 markup equivalent of the CSS display: none and visibility: hidden declarations, both of which also hide elements inaccessibly. That said, the ARIA specification allows the aria-describedby and aria-labelledby attributes to reference hidden elements. This means that those hidden elements can and will then be discoverable and used by screen readers. Great! Using aria-labelledby , we can use our hidden piece of text as a label for our button. The aria-labelledby attribute establishes relationships between an element and its label(s). It takes one (or more) ID as a value, which refers to the element that will be used as a label to the element it is used on. This idea is similar to how the for attribute is used to link a <label> to an <input> . Using this markup, VoiceOver will announce Menu, Button, and the devtools will now indicate that the accessible name of the button was provided by a <span> containing a piece of text that is referenced via an aria-labelled attribute: You can try it yourself by inspecting the following button: Menu One final note: the hidden attrubute has very, very good cross-broswer support. But if you still need to support older IEs (I am so, so sorry!), you’ll want to “polyfill” it in the CSS by explicitly hiding any and all elements that have a hidden attribute set on them: [hidden] { display: none; } Further Reading: HTML5 Accessibility Chops: hidden and aria-hidden Using the aria-labelledby attribute Technique #3: Using aria-label aria-label is another attribute which can be used to provide an accessible label to an element. Unlike aria-labelledby which references another element to use as a label, aria-label takes a string of text as a value, and that string will be used as the accessible name for the element it is used on. <button class="menu-trigger" aria-label="Menu"> <svg focusable="false" width="24" height="28" viewBox="0 0 24 28"> <!-- svg content --> </svg> </button> When aria-label is used on a button, the contents of the attribute will override the contents inside the button as the accessible name. This means that, if you have an icon or even other text content inside your <button> , that content will no longer be announced as part of the button’s name. VoiceOver will announce Menu, Button, and the devtools will now indicate that the accessible name of the button was provided by the aria-label attribute: The devtools will also show when the inner text content of the button was overridden by another accessible name: You can try it yourself by inspecting the following button: Bananas It is important to note here that you do not want to have an accessible label in aria-label that is different from the visual text label. I’ve used different labels here for demonstration purposes only. Always make sure the visual text matches what screen reader users will hear; this is a WCAG 2.1 requirement. Also worth noting here is that not all screen reader users are blind, so you’ll want to make sure that what they see matches what the screen reader is announcing to them. Further Reading ARIA14: Using aria-label to provide an invisible label where a visible label cannot be used Technique #4: aria-label on the <svg> Icon In all of the previous technqiues, we avoided using the icon to provide an accessible name to the button. But we don’t have to do that. The icon itself can be used to create a label to the button, but making sure that the button itself has an accessible label. The quickest way to add a label to an <svg> icon is by, once again, using aria-label . <button class="menu-trigger" > <svg focusable="false" width="24" height="28" viewBox="0 0 24 28" aria-label="Menu"> <!-- svg content --> </svg> </button> Since the button doesn’t have any text content in it, nor does it have a label defined using any ARIA attributes, the icon itself will now be used as a name. Since the icon has a clear label, that label will be used as the accessible name for the button. This is why it’s important to keep in mind that the name you provide to the icon should describe what the button does, not what the icon is. For example, you wouldn’t want to label it ”hamburger icon”. Note that since we are making use of the icon in this technique, we are no longer hiding it using aria-hidden , but we do want to prevent it from receiving undesired focus with focusable = "false" . VoiceOver will announce Menu, Button, and the devtools will now indicate that the accessible name of the button was provided by its content (the icon’s label): You can try it yourself by inspecting the following button: Please note that I do not recommend using this technique as it fails in some browser / screen reader combinations. Consult the “There is No One Way to Rule Them All” section below for details. Technique #5: aria-labelledby on the <svg> Icon This technique is conceptually similar to Techniqur #4 above. But instead of using aria-label to provide a label to our svg icon, we will use aria-labelledby . It is worth noting that this is also is one of the best ways to make an inline svg image(s) accessible. In this technique, aria-labelledby will reference the <title> of the SVG as the accessible label: <button class="menu-trigger" > <svg focusable="false" width="24" height="28" viewBox="0 0 24 28" role="img" aria-labelledby="svg-title"> <title id="svg-title"> Menu </title> <!-- svg content --> </svg> </button> VoiceOver will announce Menu, Button, and the devtools will once again indicate that the accessible name of the button was provided by its content (the icon’s label inside the <title> element): You can try it yourself by inspecting the following button: Menu Further Reading: Tips for Creating Accessible SVG Using ARIA to enhance SVG accessibility Please note that I do not recommend using this technique as it fails in some browser / screen reader combinations. Consult the “There is No One Way to Rule Them All” section below for details. Use SVG You’ve already noticed that I used SVG to embed the icon in the buttons in this article. It is my personal belief that using SVG should be the first requirement to making icons accessible. There are there a myriad of reasons why SVG is better suited for icons than icon fonts. If you’re using icon fonts and are not sure what it takes or how to make the switch, I have an article that covers that, and that will help you make the switch in no time. Making an element accessible does not only mean making it accessible to screen readers. It means making is universally accessible, regardless of what the user is using to interact with that element or what environment they’re in. In addition to the many benefits you get from using SVG, doing so makes it easier to make your icons accessible in user-controlled environments, such as Windows High Contrast Mode. I’ll be sharing more about that in a separate article. There is no One Way to Rule Them All Scott O’Hara and I synced together to publish two complementary articles today that hopefully provide you with everything you need to know about this topic. In his article, Scott dives into the technical intricacies of the markup patterns used to implement accessible images and svgs, and (generously) shares his extensive tests and findings on how those patterns work in different browser / screen reader pairings, or if they’re used within a button or a link. If you’ve made it this far, Scott’s article is the next logical stop. Scott’s test findings are extremely important as you will learn that treating the icon as decorative and providing an accessible name to the button using one of the first three techniques is often the better way to go. Either that or you will need to pick the svg pattern that has the test with the least amount of failures, and use that. In other words, both Technique #4 and Technique #5 come with their failures in some browser / screen reader combinations. Personally, I’d not use the SVG icon itself to provide a label for the button when I can provide one on the button itself directly. As Scott states, there’s just no good way to use an SVG as the sole means to provide an accessible name to a link or button. Every test had failures. Thankfully, Scott has saved us hours of testing, so if you need to provide a label to the button using the svg itsef, you can choose the pattern you need based on his findings. Final Words I hope this article has given you a clear overview of many possible ways to provide an accessible label to an icon button. It is important to note, though, that we only covered providing an accessible label to the buttons. There are many more things to take into consideration when combining labels with additional descriptions (using aria-describedby , for example), so please beware of those, and make sure you properly test your buttons before pushing them to production. If you’d like to learn more about creating accessible UI patterns, I’ve got a full-day workshop that you can sign up for. I’m running this workshop: at the Frozen Rockets academy in The Hague, The Netherlands, on June 10th, and at SmashingConf in Freiburg, Germany, next September. You can register for the Frozen Rockets workshop in The Hague today. Tickets are also on sale for the SmashingConf workshop in September.I would love for you to come join me! Many thanks to my friend Scott O’Hara for proofreading this article, his feedback, and for following up with his own findings and test results.

The SVG Filters Series

SVG Filters 101 SVG Filter Effects – Outline Text with <feMorphology> feMorphology filter, how it works and how you can use it to create paint-like image effects and proper text outlines. SVG Filter Effects – Poster Image Effect with <feComponentTransfer> feComponentTransfer operation and how it can be used to control the individual R/G/B/A components on a pixel level independently. As a practical example, we will be creating a poster image effect by using this primitive to limit the number of colors in an image. SVG Filter Effects – Duotone Images with <feComponentTransfer> feComponentTransfer to recreate Photoshop’s duotone image effect and control an image's luminance and color contrast. SVG Filter Effects – Conforming Text to Surface Texture with <feDisplacementMap> SVG Filter Effects — Moving Forward In this last article of the SVG Filter Effects series, I’ll share a list of useful resources and experiments to learn more about SVG Filters to start creating your own effects.

The Refactoring UI Book

I’ve never taken or had any design classes in school or university. Most of my (humble) design knowledge I’ve picked up online from random articles here and there, and from breaking down and building designs that I liked. So, when I found Steve on Twitter and saw how he was sharing design tips targeted at developers with no design background, I followed him in the blink of an eye. I'm not exaggerating when I say that he was one of my best follows in 2018. I remember the day I asked him to make a book out of all the tips he’d been sharing. I told him I’d give him my money in a heart beat. A book that contained all the useful tips he was sharing, the way he was sharing them, would have been a box full of gems. Fast forward a few months, Steve and Adam have published their Refactoring UI book, based on all the tips Steve was sharing, plus many more. And I’m not surprised to say that the book is just as good as I expected it would be. Just like his tweets, the book is chock full of design tips — brief, short tips written very well, straight to the point, and accompanied with visual respresentations of how to apply them and how not to. One tip is followed by another, without any extra talk or gibberish in between. Just my kind of content. Just my kind of book. As I was reading it, I couldn’t help but think that this is how I would write my own book, which is why I enjoyed reading it so much. And I read it fast because, again, there was no long or unnecessary talk — just the tips distilled down and lots of pretty visual eye candy. I learned a lot reading the book. And my favorite part is that now I understand design decisions made when I see them. I look at Dribbble shots and I think “Ah yeah I see what the designer did there!” and why they did it. If you’re a developer looking to improve your design skills to build more professionally-looking projects, or if you’re looking to understand more about design decisions made by designers on your team, then this book is a great piece to add to your library. I got the full bundle (thanks, Steve 💜), which also comes with PDF files containing color swatches (I love these!), UI component design samples, icons, and font recommendations. There are also a couple of videos where Steve shows you how to design or refactor a UI and make it look better using the tips from the book. A choice of either the full package or the essentials (book + videos only) is available to purchase on the site. So, this is what I think of the book. Would I recommend it? Of course! So if you do purchase it, I hope you find it just as useful as I did. Thank you for reading.

Nested Links Without Nesting Links

Chris Coyier started a thought exercise thread last week asking the community how they would approach building nested links. I had the same requirement a couple of years ago when I was building the front-end foundation for Smashing Magazine. So I thought I’d write my response to Chris’s thread out in the form of a blog post. The Challenge The following video shows what an article on the home page’s list of Latest Articles behaves like. Take note of how the URL of the links change at the bottom left of the video recording as I hover over different areas of the clickable blog post. You’ll notice that each of the internal links in the post links to a different page than that of the post itself, while clicking anywhere else on the post item links to the full article. Sorry, your browser doesn’t support embedded videos. Each article is clickable as a whole entity and would link to the article page. But we still wanted the links within the article item, such as the author name and any links inside the excerpt, to also work as regular links. Native Markup Limitations According to the specification, an <a> element’s content model specifically states that an <a> cannot contain any interactive descendants. An <a> element is interactive, and so therefore you cannot nest an <a> inside another <a>. This means that this markup is invalid: <a href="#1"> Link content that references <a href="#2"> another link </a> within the main one. </a> In fact, if you do use that markup, your main link is going to break into two separate links, with some of its text content being left out in the process. The following image shows what the DOM looks like after the browser parses my nested links from the above example: The browser “breaks” when it finds an <a> before it finds the closing tag for the preceding <a>, to it takes it up on itself to close the previous <a> The <object> Hack Upon searching for ways to nest links — if any existed, I came across this article by Roman Komarov, in which he explains his workaround for nesting links that he found when he was trying to nest links in one of his own projects. Roman came up with a brilliant way to make nesting links possible by working around the browser’s restrictions, taking advantage of how it parses HTML, and fooling it into allowing the nested link inside the first one using the <object> element: the inner link is wrapped in an <object> and this object is given a random, invalid mime type. Because of the way browsers handle object elements, the object element is going to be completely ignored, allowing the content inside of it to be displayed in its stead. In fact, the contents of the object are only there to be displayed as a fallback for when the object itself fails to display. So we make it fail, by providing an invalid type, and the browser then displays the content inside of it — our nested <a> — in its place, thus rendering the inner link inside the outer one. Note that this is only possible because: <object> we would get just a wrapper element for this content. But a wrapper with an unusual trait: any content inside of it would be treated by browser’s parser without looking at the object’s context. So, using this trait we can, finally, nest one link into another, separating them for a parser. Albeit being a very clever hack, this is still a hack. It comes with its own limitations, including browser support that you’d have to work around. (Check Roman’s article out for more details.) This hack also wasn’t very practical for the Smashing Magazine use case. We shouldn’t have to set up a script to wrap every single inner link with an object. Aside from being a hassle, in my very lazy developer opinion, this — I assume — might also have performance implications. So I continued looking for other — hopefully less hacky — options. The CSS-only Layered Links There’s a reason I say “layered” link, not “nested” link here. This technique fakes the behavior of nested links by overlaying one link on top of the whole item (article post in our case), and then elevating the remaining links on top of it. This results in the whole item area linking to the URL of that link overlay. The remaining links are elevated so their pointer events are not blocked by the overlay, thus allowing them to be independently clickable. Harry Roberts has a JSFiddle demo of this technique. For the following markup: <div class="post-link"> <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, <a href="https://www.google.com">feugiat vitae</a>, ultricies eget, tempor sit amet, ante. <a href="http://www.apple.com/">Aenean fermentum</a>, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Ut felis. Praesent dapibus, neque <a href="https://www.facebook.com/">id cursus faucibus</a>, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat.</p> <a href="http://csswizardry.com/2013/02/introducing-csswizardry-grids/" class="post-link__read-more">Read more…</a> </div> The styles (SCSS) look like this: .post-link { position: relative; /* Position any links in the post excerpt at the top of the `z-index` stack. */ a { position: relative; z-index: 1; } } /* Stretch the ‘read more’ link over the whole of the post. * Hide the ‘read more’ link’s text. */ .post-link__read-more { top: 0; right: 0; bottom: 0; left: 0; overflow: hidden; text-indent: 100%; white-space: nowrap; /* Needs a heightened specificity to trump `.post-link a`. * Stack it under all other links in the post text. */ a& { position: absolute; z-index: 0; } } The following image shows a very rough visual representation of this technique: Albeit brilliant, this technique had another issue that I wasn’t okay with: the keyboard tabbing order was, well, out of order. Here is a video showing what tabbing through the links Harry’s demo looks like: Sorry, your browser doesn’t support embedded videos. Because we have a Read More link that overlays the whole post, the tabbing order goes like this: Tab to child link Tab to child link Tab to child link Tab (whole) post [tab to move to next post:] Tab next post’s child link Tab next post’s links Tab next post’s link Tab (whole) next post This tabbing order felt very unnatural to me, so I knew I would have to adjust this technique to fix that. My Implementation Harry’s technique provides everything I need for the Smashing use case, except for my expected tab order, especially given the markup on the magazine differed slightly from the markup Harry was working with: <div class=""> <article class=""> <header> <time datetime="" class="">7 days ago</time> <h2 class=""> <!-- our first link 👇🏻 -->> <a href="https://sarasoueidan.com/2018/08/desktop-wallpaper-calendars-september-2018/">This is our post title</a> </h2> <span class="">by <a href="https://sarasoueidan.com/author/cosima-mielke">Author Name</a></span> </header> <p class=""> This is the post excerpt which very well contains <a href="#">links to places. </p> </article> <a href="#"> <span class="visually-hidden">Read More</span></a> The first link in the post markup is the title of the post which, naturally, links to the post itself. So I thought: what if, instead of overlaying the last link in the post — the Read More link — over the post, I would overlay the first link instead? Getting the title of the post to expand and cover the entire post area would mean that that area would also link to the post, which is exactly what we want to do in the first place! And since we’re not overlaying the last link on top of the links prior to it, this fixes the tab order and we end up with tabbing that works like this: Sorry, your browser doesn’t support embedded videos. The user tabs through the posts by going through the title, its following “child” links, then the Read More link, then moves on to the title of the following post, its child links, its Read More link, and so on. We’ve surpassed the backwards jump where the entire post was re-focused after focusing its contents. (Usually, tabbing would happen the other way around: focus the container, then tab through its content.) Technically, the post title will be expanded to cover the post by expanding a ::before pseudo-element inside of, which practically expand the entire title’s box with it: .the-post { /* elevate the links up */ a { position: relative; z-index: 1; } } .the-post-title { /* ... */ a { position: static; /* expand the pseudo-element to cover the post area */ &::before { content: ""; position: absolute; z-index: 0; top: ...; left: ...; width: ...; height: ...; /* ... */ } } } UX & Usability Considerations You may have already noticed the major limitation to this technique: the post excerpt’s text is covered by the pseudo-element, which makes that text unselectable. If you try to select the text to copy it, you won’t be able to. This was a compromise the Smashing team were okay with after testing the design with their users. The inability to select the text wasn’t an issue, as not many users attempted to make that selection. Final Words Calling these links “layered links” is a lot more appropriate and descriptive than “nested links”, given how they are implemented/styled. I would consider this technique “hacky” for sure, but if it works, and as long as it does not compromise the overall accessibility of the design, then I see no reason not to use it. The most important takeaway from this is to remember to always test the usability and accessibility of your design, especially if you use unconventional CSS tricks to create it. If you’re interested in some of the other tricks I used during the Smashing magazine development, check out the video of my talk, or read the case study which includes a link to the talk slides. I hope you found this article useful. Cheers, Sara

How do you mark up an accordion?

I made a poll on Twitter the other day asking the #lazyweb how they would mark up an FAQ section — or a list of questions and their corresponding answers. I specifically asked for markup suggestions. Turns out, people mark questions and answers up differently. I got some interesting insight from the responses I got that partly changed the way I would approach building an FAQ section, and some validation for the way I always have built them. The discussion was too interesting to not summarize in an article. The different possible markup approaches as well as useful resources are discussed below. No JavaScript The requirement for answering this question was to think of the answer in a no-JavaScript case. Hey #lazyweb, I got a small Friday poll for you: How do you mark up a list of questions and answers? (Think: FAQ) I’m talking about semantic markup, so forget about accordions for a second and assume there is no JS for that. Would you use: — Sara Soueidan (@SaraSoueidan) August 31, 2018 Why? Usually, FAQs are eventually turned into an accordion. Accordions require JavaScript to work (with the exception of the native <details> element which I’ll talk about shortly), and that JavaScript, if designed well, can be applied to almost any kind of proper markup — regardless of what elements are used to mark the questions and answers up. That’s why I specifically asked people to think about HTML semantics, not interactive behavior; otherwise, the one answer I would have probably gotten would have been “accordion”. I believe that it is imperative to think about how a component would render if no JavaScript behavior was available if you want that component to be truly accessible. Semantic HTML is the foundation of truly inclusive content. Start with the bare bones — the markup, and think about how it would render if no CSS or JS were enabled. Then, enhance the component by adding interactive behavior to it using JavaScript, making sure that you don’t sacrifice the accessibility of it in the process. This usually means applying and using proper ARIA roles and attributes, progressively applied, via Javascript. An FAQ can be thought of as a list of questions with answers, or a series of questions and answers. A series of questions and answers: <hx> + <div> A series of questions and answers can be marked up by using a series of headings for the questions, and paragraphs (probably wrapped in a <div>) for each answer. This is one of the most commonly used code patterns. The whole series of questions and answers would then also be wrapped in a container, or each pair of question and answer can be wrapped in an <article>, and they can easily be scripted to add accordion behavior by potentially replacing the heading text content with a toggle <button> which controls the expanded/collapsed answer “panel”. ARIA attributes would be used to establish the relationship between the question’s toggle button and the associated answer, and icons can also be added to the button inline using JavaScript as well. The way you might approach turning it into an accordion might be slightly different, but the requirements for making an accordion accessible should still be applied, so, in essence, the final result wouldn’t be too different. Advantages of this approach: The markup is simple and can be easily converted into an interactive accordion. ✔ Assistive technology users are able to navigate the FAQ using the headings. ✔ A list of questions with answers: <ul> or <dl> If you think about FAQs as a list of questions with answers, you’ll probably want to use HTML lists to mark them up. I’d probably not use an ordered list (<ol>) because the order of the questions is usually irrelevant. That leaves us with unordered lists (<ul>) and definition lists (<dl>). What both lists have in common is the semantics of a list — meaning that the questions and answers would be conveyed to assistive technologies as a list of items. An unordered list of questions with answers: <ul> <li> + <hx> <div> If you use an unordered list, each list item would contain both the question and the question’s corresponding answer. The semantics of an unordered list item <li> would not be enough to represent and distinguish the question and/from the answer. So I’d consider wrapping the question in a heading. This does feel odd, as I’ve never thought that an <li> as a container to a heading, but this code has some important benefits. I’d next wrap the content of the answer in a <div> so that I can easily toggle it when I want to add accordion functionality to the FAQ. Advantages of this approach: Assistive technologies (ATs) will announce the number of items, so their users will get an overview of how many questions there are. ✔ AT users will be able to navigate the FAQ list using the headings. ✔ It is also fairly easy to turn into an accordion using JavaScript and ARIA, similar to what we saw in the previous section. ✔ A definition list A definition list is similar to ordered and unordered lists. What distinguishes it from other lists is that it is made up of key/value pairs. I have always used definition lists (<dl>) to mark up FAQs. I like the fact that a <dl> has a series of terms (<dt>) and descriptions (<dd>). A question would be a term. The answer would be its description. This approach got the most votes in my poll. This may partially be due to the fact that the specification mentions questions and answers as an example usage for definition lists: questions and answers, categories and topics, or any other groups of term-description pairs. (Emphasis mine): Markup for a <dl>-based FAQ would look like so: Converted to an interactive accordion, and similar to what we’ve seen before, it would look like this: I’ve never hit any road blocks styling definition lists, but that’s probably because none of my projects required any styles that were not possible using the default markup. But many developers have, as the Twitter thread shows. Most styling limitations were due to the fact that it was invalid HTML to have a <div> as a child of the <dl>. This, in turn, meant that it would be difficult to group and style pairs of terms and descriptions. Today, it is perfectly valid to add a <div> as a child to a <dl>. That said, Steve Faulkner points out that “this can cause issues for screen readers as the pattern changes the way the semantics are represented in some browsers.” Check out his test cases and results for more context and details. Notes about this approach: Some assistive technologies (ATs) will announce the number of items, so users of those technologies get an overview of how many questions there are. This, however, is unfortunately not consistent across all tech. AT users will not be able to navigate the questions like they could with headings. It is fairly easy to turn into an accordion using JavaScript and ARIA. ✔ Even though I will not be using them for marking up FAQs from now on after the discussions I had as a result of this poll, I would still use definition lists for other, more proper use cases. For example, I’ve used them before within articles where I list a set of available attributes or properties and then elaborate on each one and describe what it does. SVG Coordinate Systems guide contains a perfect use case for definition lists. The native HTML accordion: <details> + <summary> The <details> element represents a disclosure widget from which the user can obtain additional information or controls. W3C HTML specification Inside <details>, we can put any sort of content we want. <details> has a friend called <summary>. When present inside <details>, the first <summary> element child represents the summary or legend of the <details>. Essentially, we can use <details> to create an accordion-like widget that the user can toggle open and closed. The <summary> element, when present, acts as the content of the toggle for the accordion. Before doing the Twitter poll, I’d never considered using <details> and <summary> to mark up FAQs. I’ve always thought of the semantics of these elements too literally: a summary is, well, a summary of the content of the details. Since the summary of an answer is derived from that answer itself then it is also an answer; and then a question could not be a <summary> because the question is not an answer. Confused yet? I had a discussion about this with my friend Scott O’Hara after tweeting the poll. We both made valid points, but the main reason we were confused and were disagreeing is that I was talking about <summary> as a “summary” whereas Scott was referring to the <summary> element as, well, a generic “toggle” element. Turns out, and I‘ve finally made my peace with the fact, that <details> and <summary> don’t literally represent content and summary of that content. The spec editors settled for these names out of a bunch of other options they had. Because naming things is hard. Because expressing perfect meaning in a single small, easy-to-spell word is hard, so we approximate. I remember there being a lot of possibilities when naming that - <spoiler> was my favorite. 😀 — 🌺Taudry Hepburn🌺 (@tabatkins) August 31, 2018 I would have preferred <toggle> and <panel> as truly generic names. But if <details> and <summary> are just meant to be generic names, then using them to mark up FAQs starts to make a tiny bit more sense. I think of it as: the "summary" is a short description of what you will see if you expand the details. A question in a FAQ is a summary of what the answer will cover. But yeah, I like toggle/panel more. Someone should have got you on the committee. But it's too late now. — Amelia Bellamy-Royds (@AmeliasBrain) August 31, 2018 So, marking an FAQ up using <details> and <summary> is pretty simple: … and it comes with some nice advantages, and some limitations: You get the accordion behavior (collapsible panels) baked in by default. ✔ The accordion is mostly fully accessible (ATs and keyboard) by default. Scott O’Hara wrote and shared the results of his tests with popular screen readers. Make sure to read his post before deciding to use <details> as an accordion, as there are some things you’ll need to be aware of: For general use within the context of a larger section of content, details and summary are well supported. However, if you want to treat them as a more complex accordion component, or need to support Internet Explorer and Edge, you’re going to need some JavaScript (and ARIA attributes for IE/Edge). The <details> element and its <summary> are fairly easily styled. (Some specific browser handling is required but nothing too complex.) ✔ You can’t currently animate the opening and closing of the details panel. But you can work around it by animating the content inside the details. Opera Mini, IE and Edge currently don’t support <details> and <summary>. But, <details> and <summary> degrade gracefully to show their content by default, without the interactive behavior, which, in my opinion, is a perfectly acceptable fallback experience. So, why does this all even matter? Because semantic HTML matters and is essential for creating truly inclusive and functional Web sites that work across the widest range of apps possible. Sure, there are different ways for doing one thing, but as long as all these different ways offer true accessibility, then we have the freedom to choose whichever technique we like. It’s always necessary, in my opinion, to consider what content would render and look like in foreign environments, or in environments that are not controlled by our own styles and scripts. Writing semantic HTML is the first step in achieving truly resilient Web sites and applications. Further Resources If you need to learn more about creating accordions that are accessible, I recommend checking these resources out: Accessible ARIA Accordions by Scott O’Hara. Collapsible Sections by Heydon Pickering. Accordion accessibility expectations by Dave RUpert. Accordion WAI-ARIA Authoring Practices Thank you for reading. —Sara

On Switching from HEX & RGB to HSL

A couple of weeks ago I tweeted about a feature that I didn’t know existed in VS Code: the visual color editor that pops up when you hover over color values in a style sheet. The VS Code color editor that pops up when you hover over a color value. The editor allows you to visually choose and edit colors, and to switch from one color format to another. In the context of the tweet I mentioned that I had converted all the colors on my site from the Hexadecimal and RGB(A) formats to the HSL format. A bunch of folks asked me why I made this switch. This article is my response. I’ve been using the Hexadecimal and RGB(A) color formats in my CSS for as long as I can remember. But I’ve never found these formats intuitive or easy to read, let alone tweak. I’ve always felt crippled whenever I needed to tweak the colors for contrast, or create colors that work well with other colors. I always resorted to GUIs, which made my workflow less than optimal. Until a while back when I came across a great article in which Marcin Wichary shows how he took advantage of the hsl() function in CSS to create different shades of colors for a dark theme for an app he was working on. That’s when I had an epic facepalm moment: how did I forget about HSL?! I knew the hsl() function existed in CSS — heck, I even wrote an entry about it in the Codrops CSS Reference, but I don’t know why I never took advantage of it before now. When I think about it, I guess it all goes back to my “Use it only when you need it” principle. I only introduce tools into my workflow when they offer great value for my projects. I’ve never given too much thought for the color scheme on my site — especially since I love black and white and have been sticking to them since forever, with one or two highlight colors for links and buttons here and there. So I never really needed a more powerful color system, despite the frustration I had whenever I tweaked the few colors I use on the site. But with more sections added to the site during the last couple of years, and a few more sections I’m going to add later, and that will have their own set of colors, it became clear to me that color management in the CSS was going to get out of hand, and that I needed a more intuitive and sensible way to choose and tweak colors, this was particularly true because I also want to offer a couple of themes to make my site’s UI friendlier. Enter HSL. HSL == Hue, Saturation, Lightness In CSS, an HSL color can be expressed using the hsl() function: The first parameter is the hue value, the second parameter is the saturation value, and the third is the lightness value. The function also has another variation: hsla(), which takes the same parameters, with an addition fourth parameter that controls the opacity of the color. The best way to understand HSL if you’re not familiar with it is to consult a color wheel. Hue The Hue determines what color of the rainbow something is. The value of the hue is the angle of that color on the color wheel. Red starts at 0 degrees, and the rest of the colors follow along the 360 degrees. (You don’t need to specify the unit of the angle in the hsl() function because it is the default.) Sorry, your browser doesn’t support embedded videos. Saturation Colors can be vivid (rich) or dull. The less of the color there is, the more is turns into a shade of grey, depending on the hue and lightness you start with. Somewhere along the line — between the 100% pure hue and the shade of grey, you can see tinted grey, or, if you look at it the other way around, you see a dull hue. Saturation controls how vivid or dull a color is. Sorry, your browser doesn’t support embedded videos. Lightness HSL works by tinting colors with white, which is also similar to how I used to deal with colors back in my days of watercolor painting. If I wanted to make a color lighter, I’d add white. If I wanted to make it darker, I’d add black. This is how the Lightness parameter works, where going below 50% means you’re starting to add black to the hue and creating a new shade of the color, and going above 50% means you’re adding white, creating a tint. Sorry, your browser doesn’t support embedded videos. — Wikipedia When you define a color in the HSL format, you pick a color in the form of an angle between 0 and 360. Setting the saturation to 100% and the lightness to 50% you get the purest form of that color. Tweaking the color from there on becomes very intuitive. HSL and Color Harmonies Using the color wheel to pick colors has many benefits. One of the main advantages of HSL is that creating color harmonies becomes a piece of cake. Complementary colors are located across from one another on the wheel. So if you start with a color and you want to get its complimentary one, all you need to do in CSS is to add 180° to the value of the Hue: The first thing you’ll probably notice in this example is that my complementary hue angle is greater than 360. Guess what? That’s okay, because HSL is smart enough to loop around the color wheel again. You could also have deducted 180 degrees from the primary hue if you didn’t want to add them. --> Color Harmonies. --> --> There are many color harmonies (or schemes) as the image above shows. Similar to what we did above with the complimentary scheme, triadic color schemes can be created by adding (or subtracting) 120°. You can also create analogous color combinations with 30° separating the hues. You can also create monochromatic harmonies easily, with one main hue and then tweaking the lightness to get different tints and shades of that hue. The sky is the limit. The Switch The switch itself was super quick. I installed a Sublime Text plugin that converts all of my colors to HSL format in a fraction of a second. That’s all it took. Yay 🙌🏻 to useful tools (and to the brilliant people who make them). HSL + CSS Custom Properties = 💜 CSS Custom Properties (a.k.a CSS Variables) are the best when it comes to creating multiple themes that can be applied on the fly. They: are live variables, available at run time. This makes it possible to change and update the values of these variables on the fly, and the changes will be reflected on the page without refreshing it. can be inlined in a style attribute, in a style tag, or updated within a style sheet — all live, just like any other CSS property. This means that you don’t need to request a separate style sheet for the different themes. You can define a set of colors for each theme and then “activate” the theme by updating the value of a data attribute on the root element. Or you could use class names, if you prefer. The value of the theme data attribute is updated upon user’s interaction with a set of inputs specifically created for changing the theme. You can use a CSS Variables as a value inside another variable. And you can use CSS Variables in combination with the calc() function. This, combined with hsl(), wields a lot of power when it comes to creating, maintaining and tweaking site-wide color themes. Marcin already showed a great example in his article that I recommend checking out if you haven’t already. I imagine creating different themes leveraging CSS Variables and HSL could look something like this: You can organize the code in any and many different ways, all depending on your own project and needs. This is just a simple example showing how HSL can be used to create more maintainable and readable color swatches and relationships, especially when combined with CSS Variables. I’ll come back with another article and a real life example another time. 😌 Useful Resources hsl() Codrops CSS Entry Understanding and Using HSL in your CSS Marcin Wichary’s Dark Theme in a Day Final Words I’ve been meaning to create a living style guide for my site for over a year now. But most of us know that our own Web sites usually sit on the shelf with a lower priority compared to client projects, and this is particularly true for freelancers. We’d rather be spending the time working on client projects and making a living. But what we tend to neglect is the fact that our sites are our online home, the place clients visit to enquire about work, and it’s important that they reflect the kind of quality and organization that we promise to offer our clients. I’m currently working on cleaning up the code and styles of my site, organizing the CSS files by creating componentized styles, and, eventually, working my way into creating a living style guide. With HSL, I now feel like I have real control over color management — every aspect of it, from choosing colors to controlling how they relate to and work with each other. Creating color relationships and swatches for theming has never been more intuitive or as easy for me. I’ve recently learned that Github also uses HSL as their color format. I really like the tip of how they moved from a dull, grey-grey into a more blue-tinted grey, which is made possible by choosing the blue hue you want and then desaturating it enough to get to the level of grey you want out of it, and decreasing its lightness to darken it as needed. HSL is a very powerful color format, especially when combined with other CSS features like CSS Variables. And I intend to take full advantage of it from now on. I’ll share any special tips or tricks that I learn or come up with in my process as I go. Cheers, Sara

SVG Filters: The Crash Course

I always try to customize in-house client workshops to my client’s needs. That sometimes also means that if my client’s design and dev team is interested in learning something that is not covered in my workshop, I will tweak the content of the workshop to make sure they learn what they need to make their work better. One such example is when I ran my SVG Workshop for the design and engineering team at Netflix last year. Elijah told me he’d be interested in learning more about SVG Filters. I hadn’t dug into SVG filters before that, so I took his request as an opportunity to finally do it, so that I could customize the workshop for them. I learned all the basics of SVG filters in time for the workshop, and then spent the following two months learning more. The material I gathered, learned and created turned out to be useful enough to share with others, so I thought I’d write a series of articles on the topic, maybe even give them their own URL somewhere. I also thought they’d be good material for an interesting talk, so I created a talk and gave that talk twice this year: the debut was at Beyond Tellerrand Munich in January, and the second one was at CSS Day in Amsterdam last month. If you know me, you know that my talks tend to be fast, packed with practical and technical goodies and tips. This talk was no exception. And the feedback to both talks was mind-blowing. I had not shared the slides for the talk before today. The main reason was that I wanted to create that series of articles that I’d been meaning to write on the topic. But that plan never saw the day of light, and, to be quite frank, I don’t think that it will any time soon because I don’t feel as excited to write long, deep dives about SVG as I used to. My interest and excitement is shifting to other aspects of the front-end. I’m still very much into SVG but only as one of the many tools in our front-end arsenal, and my future articles are going to reflect that. So I decided to write this article to share the video(s) of the talk(s), the slides, and some links for if you’re interested in learning more about SVG Filters from further resources. The Video Recording The following is the video recording of my talk at btconf: SVG Filters: The Crash Course - Sara Soueidan - btconfMUC2018 from beyond tellerrand on Vimeo. I don’t want to slow this page down too much by embedding two videos, so here’s a link to the CSS Day talk recording. You may want to watch the videos at a slower pace than the default. 🙈 drop me a line and request it. The Talk Slides You can find the slides online here. Further Resources I Googled a lot while learning about filters. I jumped between the official specification and a bunch of articles that were not specifically about SVG filters, but more about the concepts that you need to know about in order to understand SVG filters. So I learned about noise generation, turbulence, random math functions, color matrices, color functions, Gaussian and other blur operations, and so, so much more. But there were a few resources that I found myself coming back to, and those include: The Web Platform SVG Filter docs were an indispensable resource. I learned so much from Michael Mullany’s work. He wrote some of the content of the Web Platform docs, and has written a wonderful introduction to SVG filters for net magazine that I learned a tonne from. Michael also has a bunch of SVG filter experiments on Codepen that I highy recommend checking out. I also broke down most of his pens and one of the demos in my talk was inspired by / borrowed from his examples. Dirk Weber’s wonderful experiments on Smashing Magazine. The article doesn’t dive into the concepts needed or used in SVG filter primitives, but I broke down some of his demos as a way of learning more about the filters used. I learned everything else by picking up small tips and pieces of information from here and there and sewing them together. So Many Possibilities I only scratched the surface of what is possible with SVG Filters. You can do so much with SVG Filters. As I showed in my talk, you can recreate many graphic editor capabilities using almost exactly the same steps in SVG using filter primitives. But there are also limitations. I was particularly interested in recreating one particular Photoshop color glitch effect when I was working on the demos for the talk, but I don’t think there’s a way to do that using SVG’s filter primitives. I could be wrong, though. After all, I only scratched the surface and stopped halfway through my research because I had to focus on client work. So if you know a way to do this, please feel free to share and tweet at me. After my talk, many people expressed their interest in experimenting with SVG filters, and many of them already started sharing great demos on Codepen. Yoksel has been tweeting about her SVG filter experiments lately that I highly recommend checking out. Others have requested more resources after my talk, which prompted me to write this article today. So, I hope you too find it useful and are excited enough to experiment with SVG filters today. Cheers, Sara

Interview: net Magazine September 2018 Issue #310

The September 2018 issue of net Magazine came out today, featuring a six-page interview with yours truly, discussing all things front-end development and UX ahead of my upcoming workshop at Generate Conference in London. The interview features photos taken by me, in and outside of my home office. This isn’t my first interview feature in net magazine. My first feature was in 2015, a short while after I was awarded the Developer of the Year award in the 2015 net awards. But this interview is different, and I prefer it over the previous one for a a couple of reasons: The previous interview didn’t focus much on my work as a front-end developer, even though I would have liked it to. This interview, on the other hand, is all about my work at the intersection of front-end development and UX. I enjoyed talking about what I do, including ways I stay productive and healthy during my work. This interview features photos that I took myself, as opposed to having a professional photographer take them. With the exception of a photo of me speaking at CSS Day last June — which was taken by Drew McLellan — all the photos were taken by me, using my camera, with the help of my faithful tripod and remote control combination. It was fun doing these self portrait photoshoots over the last few months. The issue is now out, and you can buy a physical copy of the magazine or a digital copy if you use the net magazine mobile app. —Sara

On Designing and Building Toggle Switches

Yesterday I was working on creating the slides and accompanying demos for my upcoming Web Directions Code talk next week. One of the demos I’m creating is a basic proof of concept for a simple switch that is used to switch the theme of a UI from light to dark and vice versa. I liked, and was inspired, by the theme switch in the Medium app, shown below. The only difference is that I wanted my switch to explicitly state which theme is currently enabled, so instead of just enabling and disabling a dark theme like the Medium switch, I wanted the user to explicitly switch between Light and Dark options. There’s no particular reason for that other than personal preference. There are other ways to do this as well. How you design it is a personal preference, as long as it works and is easily understandable by users. As always, I started thinking about how to mark this simple element up, ensuring accessibility is baked right into it from the start. So I started doing my homework and reading and learning all I can about this topic. It was important for me to make sure this demo is accessible even if it’s just a quick proof of concept for a talk. First of all, because the code for the demo will be public, so I have a bigger responsibility for making sure it’s accessible, because I wouldn’t want to spread any inaccessible code around, especially if there’s a chance people might be using it somewhere else. Another reason I wanted this to be good is that I’ll probably want to reuse it for other components for my upcoming front-end components workshop. Start with the markup As I mentioned above, I started thinking about how to mark this element up ensuring it is accessible to screen readers. That’s when I realized (and it was a “D’oh!” kinda moment) that function and markup depend on how I want the toggle to behave, and on how I want it to look. It was pretty clear to me: the switch would allow a user to choose between a light theme and a dark theme, with the light theme being the default. It was at this moment that radio buttons came to my mind: two options with one of them checked, and only one option can be checked at a time; that makes a great use case for good old radio buttons. I knew I would have to choose something different if I wanted the UI to look and behave differently. For example, if I wanted the UI to say “Enable/Disable Dark Mode”, then I wouldn’t need or want to use radio buttons, because I’d only have one option to deal with that could be switched on and off — that would be a great use case for a checkbox or a good old toggle <button>. Takeaways: Style and function are interrelated; so it helps to think about these two simultaneously when designing for accessibility (and designing anything in general, really). Always, always start thinking about the markup and accessibility when building components, regardless of how small or simple they seem. Research As always, I needed to back my theory and practice up with good research. So I started reading. My first go-to references are Heydon Pickering’s Inclusive Components and The A11y Project. As it turns out, Heydon had a fantastic article just about Toggle Buttons which I learned a lot from, and my friend Scott O’Hara had an ARIA switch button included in the Patterns section of the A11y Project. So, naturally, I inspected the code for that button and read Heydon’s article to confirm if I’m on the right path. Thankfully, it turns out I was. Before I move on it’s worth mentioning that this is not an article about how to create accessible toggle switches. Heydon’s article does a fantastic job covering that. The main points I personally concluded from the above research are: There are different types of switches that seem to do similar things but are fundamentally different when it comes to markup and accessibility. Just because they are styled to look the same, doesn’t mean they are necessarily the same. I need to think about how I want the UI to behave, look and sound when marking the switch up. Design and UX first, then code. A toggle switch can be used to switch between two separate options, or it can be used to switch one option on and off (or like enabling/disabling an option). This is where the implementation differences start to manifest. If you’re switching between two separate options, using standard radio buttons makes sense. Radio buttons are used when you need your users to choose one of two or more options, so this is a perfect use case for them. They also have basic accessibility and keyboard tabbing baked right in. Just make sure you don’t break the accessibility of either of these in the HTML or using CSS. If the purpose of the switch is to enable/disable a feature (or turn it on/off), there are other approaches for it: Using a checkbox to check/uncheck (enable/disable) that option. Using a <button> that can have two states: pressed and not pressed. This approach requires the use of ARIA which in turn will require JavaScript to function properly for assistive technologies (the ARIA attribute values are updated on click with JavaScript). Read Heydon’t article for more details on this approach. This approach means that you have only one option, which in turn means that the switch button has only one associated label, and would probably not look like a “double-switch” button anymore, unless: The double-switch button (indicating on/off) states would have clear text indicating what the current active state is; so it would look like this example from Scott’s demo mentioned in the A11y project : For my use theme switcher, it was a clear choice: since the user has two options (dark and light), I was going to use radio buttons. I didn’t want it to say “turn dark mode on/off” — I wanted it to say “Enable light mode or enable dark mode”. The solution will be CSS and HTML only, require no JavaScript, and accessibility would be baked right in by default. Takeaway: Have a clear vision of what the design of the component is supposed to do and not do. Base your markup and styles on that. Learn More Inspecting Code Now, after reading and inspecting in the above resources, I decided to see how other people are marking such a switch up. After all, I knew I’d find tonnes of examples of toggle switches that look and behave like this visually on Codepen, and it’s always great to see how others are doing it — maybe I’m missing on some cool techniques for styling that I can learn, or maybe I’m missing some important piece of information when it comes to the markup and accessibility. Since I was working in Codepen on my own version of this switch (demo shared below), I thought I’d inspect Codepen’s own toggle switch: the switch that you use to choose whether you want the pen to be public or private. Quick takeaway: It is always helpful and interesting to learn from other people’s work by inspecting their code (be that via the devtools or on Codepen). The Codepen Privacy Switch The Codepen switch exhibited some weird behavior that I had also noticed before but never felt curious enough to “debug”. The following video shows this behavior: First, it’s worth mentioning that I was always confused by this switch. The red color vs green always gave out a weird feedback loop. If I make the pen private, the color turns green, and making it public makes it red. In my head, green meant more like “this pen is accessible by people, it’s open” and red was more like “this pen is closed, people are NOT allowed access”. But in Codepen terms, the colors symbolized other things. More specifically, the red stands for “PUBLIC ZONE = DANGER ZONE” or “BEWARE this pen is now PUBLIC which is NOT GOOD”. (Sorry, I’m being too dramatic, but purposefully.) Then there was the buggy behavior demonstrated in the video above (where clicking on the same label changes the value of the switch to the other label’s value). I was curious to see what was causing it so, again, I fired up devtools and inspected the code. I found that the Codepen switch is one checkbox that appears to have two labels. That’s why clicking on both “Public” and “Private” multiple times would cause the switch to be turned on and off. In other words, this is why the visual feedback/behavior of the switch did not match the purpose of the switch or what it seemed to do. I tweeted about this bug, its possible cause, and suggested an alternative solution that could fix it. I started getting responses and opinions from other developers, which led to a very good and enlightening discussion that I thoroughly enjoyed (one of the few positive aspects of Twitter!). The general consensus was that the switch needed fixing, of course. But how it would be fixed depends largely on what the Codepen team wants it to do: If the switch toggle is supposed to be an enable/disable button for the “Private” option Then: That would mean that the ON/OFF switch pattern mentioned in the previous section above would be the ideal solution. This means that the “Public” label would be discarded, and only the “Private” label would be preserved, with a clear indication that the switch next to it turns this option on or off. Which brings me to another point: The visual representation of the switch would either have to change completely or it should be tweaked: If the switch button were to remain visually the same (i.e. preserve the double-swicth “move this toggle left and right” behavior), I’d suggest adding “On/Off” labels to it akin to what Scott did in his A11y project demo, because according to WCAG, you should not use color alone to convery information. The colors also need to have enough contrast if you were to use them. And, again, I’d reconsider the red and green colors as they may confuse someone else like they confused me for a while. (Someone suggested grey and green, because “The addition of color would more closely connotate the enabled state (no color vs has color as opposed to two separate colors)”.) The underlying structure and markup for this case (one label only) could be: checkbox, that can be checked or unchecked. I would suggest just using simple (fancy, maybe) checkbox styles for this behavior and ditching the whole double-switch style altogether. <button> with aria-pressed (and aria-checked if needed), where the pressed state would indicate the pen is private, and the unpressed state indicates it’s not private; i.e. it’s public. The style of the button would also change in this case, and the behavior would requir JavaScript to modify the value of the ARIA attributes on click. If the switch toggle is supposed to explicitly offer and enable two separate options: Public and Private Then using a couple of radio buttons would make much sense, in my opinion. Two radio buttons, each with its own label, announced to assisitive technologies as a couple of separate options of which the user should choose one, and perfectly accessible via keyboards, and has no additional ARIA or JS requirements to function. And sprinkle some CSS on it to create the “double-switch” button style if you want (seriously I don’t know what else to call it) and you’re all done. The markup and styles for such a solution might differ slightly between developers, but the essence of the code would be the same. Which brings me to the live demo… Live Example This is my implementation of a two-options toggle switch. I created this not as a solution to the Codepen switch, but simply as a switch for my light/dark theme switcher that I’m using in my talk: See the Pen Accessible Option(/Toggle) Switch by Sara Soueidan (@SaraSoueidan) on CodePen. My switch is going to live in the context of a larger set of form elements, that’s why I don’t have any fieldset or legend in the demo. And yes I know, I know.. you could also tweak the code to not need the extra spans in the markup and use pseudo-elements instead, but I chose this approach anyway, just because I wanted to. Try to play with the code and uncomment some of the styles (especially try removing the spans to see how my switch looks like without them) to dissect the code and have a better idea of my choices and what I was trying to achieve. I also added focus styles to ensure keyboard users can see where the focus is since I’ve covered my default radio buttons with the spans, and labels don’t get highlighted on focus by default. I used :focus-visible only at first (with polyfill) but it didn’t work as expected in Firefox and Safari, so I ended up adding :focus back again and using that instead. Also, the focus styles aren’t very pretty, I know, but this demo is just a proof of concept so it doesn’t need to be strikingly beautiful. If you’d like to see another demo that also uses radio buttons but implements them differently, without spans and using pseudo-elements, check this Codepen by my friend Scott O’hara out: See the Pen Radio Toggle Switch by Scott (@scottohara) on CodePen. Final Words. OK let me start by saying that I could be wrong. I know that the Codepen folks may want something completely different, or think of something completely different. So this article is not meant to redesign the Codepen switch button, but rather serve as a documentation of my research and train of thought while working on creating my own switch button for my talk. I’ll need to do even more research when it’s time to continue working on my new workshop, and things may change, and I know I’ll learn and know more by the time I create my next switch. But, until then, I know I’ve got this blog post to reference for some of the thoughts and ideas that crossed my mind when I took the first step into this. I hope you find something useful reading this article. An if you’ve made it this far already: thank you for reading. Cheers.

A new Smashing talk. A smashing new experience.

I’m currently in Toronto, Canada, where I ran a workshop two days ago and gave a talk today at yet another SmashingConf event. Like all previous SmashingConfs, it was.. well.. smashing! But this one stood out for me so much that, for the first time ever, I found myself firing my code editor up to write this short and sweet conference review. I felt like I needed to save a part of this experience in written format. I’ve never written conference reviews before, so this goes to say a lot about how much I’ve enjoyed this event. No Slides! This was the first SmashingConf event with a new twist: all talks are performed live, with no slides allowed. All speakers (myself included, of course) shared a small part of their everyday workflow in what I would consider the most engaging talk format so far. From an attendance point of view: I think this was the best conference learning experience. I have a very, very short attention span when it comes to conference talks. I usually lose my focus and get distracted about 5 to 10 minutes sitting and listening through a talk. It’s something I’ve tried to “fix” about my brain, but never could. Sitting there and watching people just talk and move through tonnes of slides with images and text on them has never been appealing enough for my brain. But seeing people do things is a whole other thing. It’s like getting a glimpse into their real everyday work lives, and learning from them first-hand, without any barriers. I personally learn more from watching people than I do from listening to them. And this is why I absolutely loved this conference experience. From a speaking point of view: this was the most fun, least stressful of all my talks so far. I’ve done a bit of live-coding in my talks before, and I’ve felt more “at home” during those live coding sessions than all the rest of my speaking. There’s something about getting my hands busy on stage that distracts my brain enough to not even have a chance to wreck my nerves like it usually does. I usually get very, very nervous before my talks. And no, it never got easier over time. If anything, it felt more like it was getting worse every time. Actually, ”nervous” is a very understated way to describe my situation before I speak. I get heart palpitations; I feel extremely dehydrated; and I feel very dizzy (sometimes I worry I might actually faint). Maybe it’s because expectations start building up the more you speak, and you find yourself competing with your past self to do better every time. This is generally good for self growth, but expectations are very nerve-wrecking. But this time… this time it was different! I think it may be because this talk format was, in essence, very similar to a workshop format. And having given many workshops in the last few years, it’s become kind of a second nature for me to do things live in front of people. Maybe? I don’t know. I felt almost zero nervousness. I was too busy getting things done to feel nervous. For me, showing people how to do things is so much easier than talking about it. Even though I sound like I got it all together, speaking in English is not as effortless as it may sound to me, and translating ideas that are runnig through your brain at the speed of light live is not easy. So working through concepts and techniques instead of talking about them was much more liberating for me. I love the fact that this talk format also kind of rid me of the expectation that it needed to be flawless. Every speaker knows that doing things live on stage comes with a risk of failure. But since all speakers were in this together, it kind of helped relieve some of the pressure, and so instead of fretting over moments were they get stuck on stage, I saw speakers like Harry Roberts embrace these moments as a natural part of this talk format and even make fun of those moments, again adding more humor to an already interesting and engaging talk. But it isn’t for everyone.. I believe some attendees and some speakers were not very fond of this format. And that’s okay. Everyone learns and teaches in different ways, and I think it’s good to try new things out and learn more about what works for us and what doesn’t. There were great people. And I had enlightening conversations. I met some friends I’d only known over the internet for the last few years. I’ve re-met and had formidable conversations with wonderful friends and acquaintances, many of which were truly, truly life-changingly inspiring! (Believe me, this is not something I would say lightly.) I saw some of my previous workshop attendees, who shared updates on how what they learnt in the workshop is currently helping them in their everyday work. It was very rewarding to hear this. And then there’s the humbling fact that I shared the stage with some of my favorite people in the industry. It was truly great. Toronto is beautiful! Toronto is like a downsized, saner and more liveable version of NYC. And I love NYC. Toronto is kind of like the better version of it. I’m very much enjoying the city so far, and I look forward to a few more days here and more updates I’m going to share in another post next week. While I’m here, I’m sharing my view of the city on my Instagram, where I’ve already posted quite a bunch of photos, if you’re into that kinda thing. I would definitely do it again. I do want to give slideless talks again. It could be at another SmashingConf, and it could be anywhere else. I think that, for my kind of talks, there’s much more value in demonstrating things live than there is in theoretical talks that don’t include practice. So I see this format as an improvement to the “normal” format for my talks. Of course, the live format wouldn’t be ideal for all my upcoming talks, and that’s also okay. Smashing is smashing. SmashingConf is one my favorite events, and the SmashingConf team and crew have become more like family over the years. I’m really happy I got to be a part of this particular event. Kudos and many thanks to Vitaly, Markus, Amanda and everybody else in the team that made this event possible, and for pushing the boundaries once again and challenging us to get out of our comfort zones. If you ever get a chance to attend a SmashingConf, I would recommend not missing it.

Going Offline

Earlier this month I rolled out a new and long overdue feature on this Web site: offline viewing. In other words, from now on, after your first visit, you can re-visit my Web site even when you’re not connected to the Internet. Furthermore, depending on the device and application you’re using to visit this site, you may also be able to add the site to your mobile homescreen, similar to other native applications. Offline with Service Workers Most of the main pages of the site (those linked in the menu in the header and links in the footer) will be saved for offline viewing by default on your first visit. Posts published in the Articles section (like this one) or in the Desk section will be available for offline reading on demand. All this is possible thanks to the power of Service Workers. Progressively Enhanced Experience If you visit my site using a modern browser that supports Service Workers, you will get an enhanced experience, with a colorful “Save this page for offline reading” button at the top of each post, that does exactly what it says: it caches the page offline so that you can view and read it again when you’re offline. Using a Service Worker to save pages offline also enhances the overall experience of the site by making it load even faster than it already did before. If a browser does not support Service workers, it will miss on these new features, but the general experience of the site will remain unchanged from what is was before — nothing will break. This is because all the features that Service Worker offers are only enabled when support for Service Workers is detected and the Worker is registered and installed. “Going Offline” I wrote my first Service Worker script about 3 or 4 years ago — the year Workers were announced and started getting implemented. But my Worker never saw the day of light. I remember getting caught up with client work and adding the script to my todo list for this Web site. I never got to finish it. This month, A Book Apart announced (and released early previews of) a new book titled “Going Offline”, written by none other than Jeremy Keith (“adactio”) himself. Like any book written by one of my favorite people in the industry, I leaped on the chance to read the early preview. Over the course of two days, I read the book and followed along with it as I rewrote my old Service Worker script for the site. By the time I reached the end of the book, I had a Service Worker installed and working on the site, and I had added a Web App Manifest file — the file that enables your Web site or Web application to behave and look similar to a native application on your mobile device(s). Jeremy covers literally everything you need to know to write and install your first Service Worker, tweak it to your site’s needs, and then write the Web App Manifest file to complete the offline experience, all in a ridiculously easy to follow style. It doesn’t matter if you’re a designer, a junior developer or an experienced engineer — this book is perfect for anyone who wants to learn about Service Workers and take their Web application to a whole new level. If you care about the user experience of your site / application, making sure it loads blazing fast and works offline might be one of the best steps you could take to improve that experience for your users. And this book is a vital one if you’re not sure where to start doing that. I highly recommend it. I read the book over the course of two days, but it can easily be read in half a day. And as someone who rarely ever reads a book cover to cover (I tend to quit halfway through most books), this says a lot about how good it is. The book is now available for (pre)order here. Final Words If you’re interested, you can take a look at my script here. It is a basic script, and you can write an exact same script if you follow along Jeremy’s book. But of course it’s important, in my opinion, that you know, understand and customize what the script does to your own needs. Jeremy’s book helps tremendously with that. The book also contains a list of extra resources for further learning about Service Workers. So have a look at those if you need more information. I have more work to be done on this site, and I’ll be writing about new features as they roll out. I’m quite excited about what’s coming next! Thank you for reading!

Case Study: Optimizing SVG Text & Image Delivery with Inline SVG

I love when I’m pushed to think of creative techniques when tackling design and dev challenges on my client projects. And it so happens that the new Smashing Magazine design released this year was one of the more (fun and) challenging projects I’ve worked on. And one of the challenges I had to tackle was delivering three fairly complex SVG images in a performant, accessible way. I was the front-end developer (and, at times, the designer) on the project. I’ve written a case study about the project earlier this year. But the case study was more about the design aspect of the project than it was about the development of it. I’ve talked about the development part at a few conferences during the last year. This is the first in a series of articles going over some of the tips and tricks I mentioned in those talks. The Challenge The new Smashing Magazine offers, as a replacement to ads on the site, three new types of memberships. The Membership signup page shows these three membership options, with a fairly complex SVG illustration for each one. The following image shows the three illustrations I worked on. Even though the content of these illustrations has changed since I worked on the project, the complexity of the images as well as the technique used to embed them remained unchanged. Each of these illustrations contains the title/name of a membership. There are no actual titles in the HTML to represent these memberships otherwise, which means that the text in each image is the title of that particular membership. This, in turn, means that this text needs to be as searchable, selectable and accessible as real (HTML) text. In other words, the text inside the images needs to remain real text and not be converted to outlines, for starters. SVG text — wrapped in <text> elements within an <svg> — is searchable, selectable and accessible by default. So we have a great start there. And since the text inside each image is real text, it needed to be styled like the rest of the text — more specifically, the headlines — on the site. Using font-family, you can apply a font face to SVG text the same way you would apply a font face to text in HTML. And I wanted the font styles to be applied in the main style sheet, not in a seperate style sheet referenced within each SVG image. So, ideally, these three images would be embedded inline in the page. This would give us both the styling from the main style sheet as well as flexibility to do pretty much anything else we may want to do with the text otherwise. But inlining the illustrations was not as simple as it sounded. Each illustration was complex enough to make the size of it so large that adding it inline to the HTML was simply not an option. The following recording shows the size of one of these illustrations. Inlining three times the amount of code shown in the above image was definitely not an option. But I still wanted the text inside those images to be inlined. So, what’s the best way to get the best out of SVG: searchable, selectable and accessible text, a cacheable illustration (hence better performance), and clean code? The Solution There are seven different ways to embed an SVG on a Web page. Choosing which one to use depends largely on the case at hand and what your project requirements are. But something that I frequently mention when talking about embedding techniques is that you may not have to choose one technique. In other words, you can choose to embed an SVG using more than one embedding technique at the same time! SVG is a document format, not just an image format. Thus, referencing external images inside an svg document is possible just like it is in HTML. So, why not take this a step further and reference an SVG image from within an SVG document? Since I wanted the text to be inlined and the rest of the image to be external and cacheable, and since the nature of SVG allows me to do pretty much anything with its contents, I thought “Why not split each of these images into separate parts: text and illustration?”, and then use an inline <svg> to wrap and stitch these two parts together? In other words, an inline <svg> in the page would contain the <text> of the illustration, and then I’d reference the rest of the the illustration using an <image> element, within the same inline svg. So, in essence, I’d be working with SVG content in a similar way to HTML text and images. We use an <svg> document to embed an SVG image plus its accompanying text. Then, using some tweaking, I’d position the inline text on top of the illustration so that the end result would look like the original image. So, I took each of the three images and removed the text content from them. That left me with three illustrations with no titles. Then, for each illustration, I embedded that illustration within an inline <svg> that also contained the text for that illustration. The code looked something like this: Using this solution, I achieved all three main goals I needed: The complex illustration is no longer embedded in the HTML. This means the HTML code remains clean and uncluttered. The illustration is cached upon subsequent requests, which is a win for performance. The title for each plan is real, inline text, and is therefore searchable, selectable and accessible. Then, to finish this off, the text inside the SVG representing the title for the respective plan was styled further in CSS: And… that’s pretty much it. Final Words Replacing the old illustrations with new ones was easy and fast. I got three new illustrations without text in them, and referenced those by simply changing the path to the images in the inline <svg>s, and then tweaked the x and y for the <text> of each one to position it correctly in the new images. The styles for the text and everything else was left untouched. Sometimes you don’t have to choose just one embedding technique to embed an SVG. Keeping the document nature of SVG in mind opens doors to creative solutions that might otherwise not come to mind at first glance. SVG is, after all, both a document and an image, and that’s where most of its power really comes from. I hope you found this tip useful. Don’t forget to subscribe to the RSS (link in footer below) to receive the latest and new articles in your RSS reader as soon as they’re out. Thank you for reading. Footnotes a video recording of me going over ths particular trick if you're more into listening than reading. ↵

Cropping & Scaling Images Using SVG Documents

I’m always interested in and thinking about ways to use SVG in my client projects to solve common UI challenges — uses that go beyond simple icon display and animated illustrations. I’m also always researching and looking for practical uses of SVG to add to my talk and workshop material that go beyond SVG the image format, and more into the document nature of it. After all, SVG on the Web isn’t just about displaying pretty and animated illustrations. I’m also particularly interested in CSS and SVG as a combination (that I like to call “The Power Combo”) to solve common real-world challenges. These two work really well together. And it so happens than some of what’s possible in CSS is also possible in SVG, either because the CSS functionlity was imported from SVG to begin with, or simply because SVG documents also happen to offer tools that achieve the same functionality. And since SVG goes way back and has much better support than newer CSS features, it is possible to use SVG either as a fallback or as a replacement to some CSS functionalities. It all depends on the browser support you’re after. SVG comes with a pair of attributes — namely viewBox and preserveAspectRatio — that allow us to manipulate the contents of an SVG (whether vector content or raster images) in a myriad of ways to achieve a myriad of things. One thing we can do with these attributes is control the scaling and position of the contents of the SVG. In this article, we’ll use these attributes to crop, scale and position images, as a fallback or alternative to the CSS object-fit and object-position properties. viewBox, viewport and preserveAspectRatio, I highly recommend reading my extensive guide on the subject. Although this article does not require a deep understanding of these attributes, I highly recommend you get comfortable using these attributes. Cropping, Scaling and Positioning in CSS with object-fit and object-position Say you’re using a CMS, and you’re allowing your users or authors to upload photos of themselves to use as an avatar next to their biography on the site. And you want to make it possible for them to upload any image of any size and aspect ratio, and then you’d handle the cropping of that image before you display it on the page in a box that might very well have a different aspect ratio than the image the author uploaded. There are many ways you could handle this. For example, you can handle the image cropping on the server-side using PHP or some JavaScript script, and then serve the cropped image on the site. You may even be in a different scenario, where you just want to be able to quickly crop and display the images on a page, without using a CMS and back-end script. Fortunately, today, CSS has two properties that make cropping and scaling images within a fitted box a breeze. These properties are object-fit and object-position. The object-fit property specifies how the contents of a replaced element should be fitted to the box established by its used height and width. Even though a bitmap image has its own intrinsic dimensions and aspect ratio, you can size it to fit into any box of any size as defined in your CSS. And you can choose whether you want to preserve the aspect ratio of the image or not, all using one property (object-fit) and one line of CSS. The following image shows the effect of each of the possible values for object-fit: object-fit values to an image to be fitted in a box with a different aspect ratio. By default, the image is centered within its containing box (the square, in our example). You can change that default position using object-position, which takes values similar to the values of background-position. For example, object-position: top left will align the top edge of the image to the top border of the box, and the left edge of the image to the left border of the box. Here’s a live Codepen for you to try the effect of changing object-position on the images: See the Pen CSS `object-fit` Values by Sara Soueidan (@SaraSoueidan) on CodePen. Browser support for object-fit and object-position is very good: it is supported in all the latest browsers, including MS Edge 16+ and Opera Mini, though it requires the -o- prefix in the latter. You can see the latest updated browser support on CanIUse.com. If you, like me, want to be able to provide a similar experience to Internet Explorer, you’re going to need an alternative solution, or at least a fallback. And, ideally, the alternative solution needs to provide support at least back to IE9, maybe? This is where SVG can fill in. Cropping & Scaling Images with SVG If you’ve ever played with the SVG viewBox, then you know that the coordinate system defined by the viewBox does not necessarily need to have the same aspect ratio as that of the <svg> viewport. And when the aspect ratio of the viewBox is not the same as that of the viewport, the browser needs to position the former in the latter similar to the way the photo was being positioned inside the box in the previous section. By default, just like with object-fit, the browser will fit the viewBox inside of the SVG viewport (or “box”) by containing it inside of it, such that the entire viewBox — and, thus, all the contents of the SVG — are visible inside the viewport. Using the preserveAspectRatio attribute, you can change the position and scale of the viewBox — and, thus, all the contents of the SVG — similar to the way object-position changes the position and scale of the image inside the box when using object-fit. love my CSS and SVG front-end workshops. You can sign up for one of my upcoming workshops or request an in-house workshop for your team, at your company, in your city. Learn more about the workshops I offer in the Training & Workshops page. For example, suppose we have a square svg (aspect ratio 1:1) and a viewBox that has a different aspect ratio (2:1). The easiest and fastest way to visualize the viewBox coordinate system in the svg is to create a <rect> that starts at the coordinate system’s origin and has a width and height value of 100%. The result of the above code is shown in the image below. The yellow rectangle represent the size and position of the viewBox within the svg viewport. object-fit values to an image to be fitted in a box with a different aspect ratio. Now, using preserveAspectRatio, you can change the position of the viewBox as well as its size (or scale) within the viewport similar to the same way we could change the position and scale of our image in the previous section using object-fit and object-position. A preserveAspectRatio value is made up of two keywords, one of them represents the scale viewBox and has one of two values: meet or slice. meet has the same effect as object-fit: contain; (or background-size: contain;) and slice has the same effect as object-fit: cover; (or background-size: cover;). The former will preserve the aspect ratio of the viewBox and fit it inside the viewport so that it’s entirely visible. This is the default behavior. Whereas slice will scale the viewBox up, while preserving its aspect ratio, so that it covers the entire viewport area, even if it means cutting some of the content off (hence the “slicing” effect). The other keyword in preserveAspectRatio represents and controls the position of the viewBox within the viewport. It has 19 values, including none which tells the browser to scale the viewBox to fill the viewport area without preserving its aspect ratio, and is similar in effect to object-fit: fill;. The default value for the preserveAspectRatio is xMidYMid meet, which is the value the browser uses even if you completely omit the attribute from the <svg>. The following snippet using preserveAspectRatio="xMinYMin meet will change the position of the viewBox in the previous example such that the yellow rectangle’s top edge is aligned with the viewport’s top edge, and its left edge is aligned with the left edge of the viewport, while keeping the whole rectangle contained within the viewport and preserving its aspect ratio. xMinYMin is equivalent to 0% 0% or left top values in background-position. an interactive demo that includes a cheatsheet that maps each of the preserveAspectRatio values to one of background-position values. I highly recommend checking it out. Now, to get back to the objective of this article. If you replace the <rect> element with an image (such as a photograph) and you match the aspect ratio of that image with that of the viewBox, the browser’s default behavior will be to position the viewBox (and consequently also the image) so that it is fully contained and centered within the viewport (assuming again that the viewport’s aspect ratio is different from that of the viewBox and the image). The following Codepen shows that in action. We have a 1:1 aspect ratio SVG, and an image with dimensions 579px by 375px. I’m using the same as the one I used in the CSS demo in the previous section again, and I’m keeping the default preserveAspectRatio. Try changing the value of preserveAspectRatio to see how the changes affect the position and scale of the image within the SVG. To get the effect of object-fit: cover;, for example, you need only change meet into slice — the image will remain centered by default with xMidYMid. See the Pen b47336d56a318d056218aa57e8889f3a by Sara Soueidan (@SaraSoueidan) on CodePen. Pretty much any combination of values of object-fit and object-position can be replicated using preserveAspectRatio on viewBox. And what’s best is that this technique will work in any and all browsers that support SVG, which means that it will work in Internet Explorer all the way back to IE9. IE8 does not support SVG so you’d have to provide a different solution for it if you need to support it. One more thing: making the SVG solution more accessible. One thing that the SVG solution is missing at this point is an alternative to the alt attribute, because an image should always have that. If the image is just decoration, the alt attribute can be left empty, but it should never be omitted. To make the SVG snippet accessible, you can add the SVG alternative to alt: the <title> element, first thing in the SVG, before your <image> declaration. So, doing that in the example above, the code would look like this: Last but not least, to enhance the accessibility of SVG further, add a couple of attributes on the <svg> element to describe the role of the <svg> as well as re-enforce the relationship between the <svg> and the <title> element, so that the latter is recognised by screen readers as the accessible name for the SVG content (—our image, in this case). And just like that, you now have a perfectly accessible SVG alternative to a CSS object-fit declaration. Summary & Recap You can crop and scale any image using CSS object-fit and object-position. However, these properties are only supported in the latest version of ME Edge as well as all other modern browsers. If you need to crop and scale an image in Internet Explorer and provide support back to IE9, you can do that by wrapping the image in an <svg>, and using the viewBox and preserveAspectRatio attributes to do what object-fit and object-position do. The snippet can replace an object-fit declaration: where imgX and imgY are the dimensions of the image you want to crop and scale, and <align> and <meetOrslice> are the two keywords that determine the scale and position of the image within the SVG wrapper. And that’s it. A simple SVG tip to provide better cross-browser support for a less-supported CSS feature. I hope you like this tip and find it useful. Thank you for reading! Footnotes <img> and <video> are obvious examples’. ↵ ↵ viewBox is changed, the origin of the rect should be changed to match that, otherwise the rectangle can no longer be used as a visualization of the current user coordinate system in use. ↵

Auto-Sizing Columns in CSS Grid: auto-fill vs auto-fit

In this article I explain the subtle but important difference between auto-fill and auto-fit for sizing columns in CSS Grid. Each of them exhibits a responsive behavior once compbined with repeat() that you may or may not want for your responsive layout.

Migrating from Jekyll+Github Pages to Hugo+Netlify

During the last 18 months, working on my Web site became a daunting task—be that for developing, redesigning it, writing a blog post, or making updates to my speaking and workshop pages. My then static site generator, Jekyll, is why. And a change has long been overdue... Jekyll became unbearably slow at compiling my Web site after every change I made. Until, at one point, waiting for the site to compile became a torturous, life-sucking process that I wanted to avoid at all costs. This may sound exaggerated, but I promise you it’s not. Jekyll became way, way too slow. “Too slow” is actually an understatement. Recently, every time I changed a CSS property or made any change in the HTML I had to wait up to five minutes for that change to be picked up and compiled by Jekyll. I am, once more, not exaggerating. Jekyll used to literally just… freeze. I’d have to ctrl+C my way out of the freeze and then run it again for it to pick up the changes and finally compile. And if I made many changes in a row, my Macbook would heat up so much and the fan would go so crazy that it sounded like an airplane about to take off. My site is relatively small, I’d say. I have less than 100 blog posts. Less than 60 at the time of writing of this article, actually. And only a few static pages. I don’t use heavy JavaScript. In fact, I barely need to use any JavaScript. And yet, Jekyll still choked every time it had to compile it. Yes, I did use Jekyll flags such as --incremental and every single other flag and setting that I found or that someone recommended to speed up the compiling process. But no, it did not help. I can’t even emphasize how bad it got during the last year. I would literally feel the stress hormones increase in my blood stream every time I so much as thought about making a change to my Web site. I knew I would be about to give myself one hell of a bad time doing so. But I knew that this couldn’t go on forever. I knew I’d have to ditch Jekyll and migrate to a new generator at some point. I just never found the time to do so. Actually, to be more honest here, I never made the time for it because every time I had time off a project I wanted to make the most out of that time by staying away from my computer. My site was just not a priority, especially since I’d been very much still undecided about what to use as an alternative. So I kept stalling. But recently, knowing I had a couple of weeks off to do practically anything, and since I’ve been having a lot of ideas for my blog that started piling up and that I really want to get out there, such as a setting up a newsletter, tweaking the design, improving the code (which is still WIP), adding a new type of content section (coming soon) and a few more ideas, I finally managed to put my head into it and do it, because I want to get my ideas out, and write a few blog posts. But I needed to start enjoying working on my Web site again, first. So I finally thought to myself: “That’s it. I’m just gonna have to put my head down for a few days this week and dedicate my time to moving to the new static generator”. I knew this was a necessary and extremely useful time investment that I just had to finally make. I put my mind to it, and just did it. (This is the most effective way to be productive, really: Just do it.) Choosing a static site generator As I mentioned earlier, one of the reasons I didn’t make the switch earlier to another generator was because I didn’t know which one I wanted to use. Several Twitter friends suggested a few of the many available options. But I never felt comfortable with any of them. You see, everyone has some way that their brains work, and some way they like to organize their files, directories, and work, that works for them. None of the static generators I saw gave me everything I wanted and needed for my site. Until someone once suggested having a look at Hugo. I took a few minutes to read the docs, just to get an idea of what to expect and what Hugo had to offer—to get a first impression of it, so to speak. After reading a little into the content structure and organization section and learning how Hugo offers the ability to create many different content categories and sections, plus all the general flexibility it provides, I thought that this was the static site generator I’d always wanted and needed. The organization and structure looked exactly like what I had imagined my own site to have. But what made me settle for Hugo out of all other options was seeing how incredibly fast it is compared to Jekyll. Not only has every single blog post I read online made a comparison and proved this, but I also got to experience this speed first hand while working on the Smashing Magazine redesign. The new Smashing Magazine (currently at next.smashingmagazine.com) uses Hugo as a static site generator. The setup that I got to use while building the front-end of the magazine was so blazingly fast that I had absolutely no doubt that the results I was reading about were true. And since my site is much smaller than Smashing Magazine, I knew I had nothing more to worry about. I mean, if Smashing Magazine can be compiled so ridiculously fast, how could my blog not be? Setting Hugo up Setting up Hugo isn’t complicated. The docs include two guides: one for installing Hugo on a Mac, and one for installing it on Windows. From here on forwards I’ll be referring to a Mac setup since a Mac is my main work machine. I used brew to install Hugo: I followed the instructions in the installation page and updated brew and ran a few other commands to ensure everything was installed and working as expected. That’s all you need to get Hugo to work and run on your machine. It can’t get any simpler than that. With Jekyll, installation didn’t go as smoothly as I remember spending quite a lot of time to get it set up and running back then. I tend to be a lazy developer sometimes. But that can be good because it pushes me to find the fastest and simplest way to accomplish a task. So the first thing I wanted to do in making the switch to Hugo was a way to automatically migrate all my blog posts without me having to go over each and every one of them to change the front matter in each one. (Seriously, I would have aborted this whole operation if I had to do that. 😅) Fortunately, as of version 0.15, Hugo provides a one-liner to migrate from Jekyll. You type the following line into the terminal—replacing jekyll_root_path and target_path with the paths to your current Jekyll directory and the directory you want to set up your new site in, and Hugo will import your current Jekyll site’s files into a new Hugo site directory for you: If you’re not importing a Jekyll site, you may want to check the corresponding docs out, detailing what you need to know about folder structure in Hugo, such as where static assets go, where content and layout templates go, and more. The next step is to convert your Jekyll templates into Hugo templates, and this is where the bulk of the work is, and where I ended up bumping my head into the walls quite a few times. (But believe me, the end result I have now is very much worth it. Plus, I’ve learned a lot. I’ll be sharing some of what I learned in the next section.) Victor Hugo boilerplate, which comes equipped with everything you need to even get Webpack and Gulp up and running in your site’s Workflow as well. The structure the boilerplate provides is slightly different from what I have below, but not too much. Diving into Hugo: Technical details Let me start by saying this: at some point during the migration, I was just tweaking stuff, changing values, names, file names, structure, etc. in the hopes of something magically working and when it does I would go like: “I have no idea how or why this worked.” And as someone else mentioned on Twitter, apparently I’m not the only one who’s had such moments with Hugo. So I’m hoping this (fairly long) post will help some of you thinking about making the switch to Hugo, hopefully saving you some headaches along the way. Disclaimer: There’s a lot about Hugo that I still don’t know how to do and find myself Googling sometimes. But I’ve got all the basics and everything I need for now all up and running, and yes, I do know how and why everything I have working now is working the way it is. So, let me share some of that stuff with you. I’ll also share some of the extremely useful articles I found that helped me as well. So think of this article as an idea dump, and a set of reminders for my future self to get back to if I ever get confused again about the basics. Hugo Folder Structure My site’s local directory structure currently looks like this: The folders you see in the image above, apart from node_modules, are the ones that Hugo generates for you when you import your site from Jekyll, and these are also the ones you would normally create and set up for a Hugo site. The files at the bottom are the files needed or used by Github and Gulp. The only file that is also used by Hugo is the config.toml file. config.toml contains the site’s configuration variables such as baseURL among many other variables that you may or may not decide to use. It is similar to Jekyll’s yaml configuration file. The Hugo docs provide a long list of available variables and everything you need to know to set up a config file that works for you in this page. My config file contains very few variables for now. /public/ is the directory your compiled site will live in. This directory is similar to the the dist directory used in most apps’ directory structure. The rest of the directories are where the dev process happens. The static directory is where static content such as images, css and js files, audio, video, talk slides, etc. live. It is where I find I spend most of my time working. After working on the Smashing Magazine redesign I also learned that your structure can be different from the above. The basics are the same, but if you use something like Netlify’s Victor Hugo boilerplate, your setup would be a little different, but the main concepts of what is compiled to where remains almost the same. Also note that the Victor Hugo boilerplate is a fantastic place to start if you want to move to Hugo and use Webpack and Gulp in your workflow. I found Webpack to be overkill for my site given how little JS I have here, but if you do need it, I highly recommend using the boilerplate. I also prefer building from scratch so I can learn the ins and outs of how things work. Whatever works for you, go for it. Creating and laying out content For any kind of content you want, be that a static page, a blog post, an index page (for articles, case studies, etc.), you need to create an .md (markdown) file in the /content/ directory. This is where all the content is “defined”. After creating the content in its specified directory, you then create (or re-use) a layout template from the /layouts/ directory to lay that content out. Every .md file in the /content/ directory corresponds to a page and starts with the page’s front matter, which can be written in either yaml or toml format. Since I wanted to get the feel of a whole new environment, and since most Hugo docs and resources use it too, I decided to use toml. Jekyll uses yaml. I won’t go into the details of the difference between the syntax used by Hugo versus that used by Jekyll. The Hugo docs as well as, well, Google, do a great job at explaining the differences, so feel free to research further and get back to this article once the differences are clear. I personally did have to spend quite some time learning the new syntaxes (toml, Go templating, etc.) before I felt comfortable using them. But they don’t have a steep learning curve, so don’t let the new syntax intimidate you if you’re not already familiar with it. Defining Content Types (or Declaring types of content) Every page’s front matter defines the type of the page/content, which in turn defines what template will be used to lay it out. The type of the page is defined using the type variable. For example, the front matter of an article in the blog section on my site looks like this: The type value an be practically anything, and this is where one of Hugo’s powers truly shines. You can define as many content types as you want. For example, I currently have five types of content on my site: static (pages such as About and Hire), blog (articles like the one you’re reading now), workshops, case studies, and desk (which is a new kind of posts that will be coming soon). I can create as many more content types as I want in the future. is being rolled into Hugo now that allows you to create subsections of content, too! This would allow you to, say, create design and development subsections in the articles section, and much, much more. It’s an exciting new addition to the CMS. The following screenshot shows what the /content/ directory of my site currently looks like: The content of the content directory on my Web site. Static pages are created as individual .md files in the root of the /content/ directory. Other kinds of content that would need an index page (such as articles, workshops, case studies, etc.) are created inside directories that are named after the content type. For example, workshops are created inside a /content/workshops/ directory. My articles live inside the /content/blog/ directory. Directories like these are also referred to as sections. For every piece of content, you need to define the type of that content. And that can be done in two ways. The type of the static pages is defined using the type variable, which is in the page’s front matter. The type for the four sections (blog, workshops, case studies and desk), however, is defined using directory structure. When you use directory structure to define a type, you don’t have to define the type in the front matter anymore. For example, a blog post lives inside the blog directory, so its type is automatically set to blog. You don’t need to redefine that type in the front matter of each post. You can use either the type variable in the front matter or the directory structure way to define content type. Generally, you would use the type variable to define and create static pages; and use the directory structure to define content that requires an index page, such as blog posts. An important and useful thing to know here is that when you define the type of the page using the type variable, the page can be placed anywhere inside /content/ directory and the directory structure will be irrelevant. Meaning that you could define a page of type static and place it inside the blog directory, and Hugo will still see it as a static page, and consider its location in the blog folder irrelevant. But.. irrelevant for what? The answer is: to choosing which layout template to use. You see, each content type will be “mapped” to a certain layout template. You can have different types use the same template, too. I’ll talk more about layout in the next section. But first, let’s create a couple of content pages: two static pages (Homepage and About, for example) and an index page for the blog posts. But before we do that, I want to point out a note about creating index pages for different sections or types. The blog section needs to contain an _index.md file inside the /content/blog/ directory. This file is the index page for this section (where we will display a list of all the posts). The /content/blog/ directory will also host the individual blog posts as well. Check the following screenshot out for a more visual example: section) includes an index page (starts with an underscore), in addition to the individual posts in that section. Similarly, any and every other content type (or section) will have an index page as well as the individual posts in that section. So, let’s start creating some pages. The homepage The homepage is created by creating an _index.md file inside /content/. You can see it at the top of all static pages in the folder structure of the screenshot above. The homepage is the only exception to the other pages when it comes to layout in that it will require its own layout in the /layouts/ folder (we’ll talk more about layout in an upcoming section) and that layout template has the same name: index.html. In the front matter of the /content/_index.md you define the type of the page as well as give it a title and description. The front matter of my homepage looks like this: The description is used in the header partial of the site as a <title> value like so: The reason I’m not using the title value as the <title> in the HTML is that, in other pages, the title of the page is used as the name the page will get in the main menu. More on this later. An .md file in the /content/ directory can contain both markdown and HTML. So for the homepage, and since I have no dynamic content such as post listings, I only have the HTML of the page in there. But how does this markdown/HTML content get laid out, and how do we include the header and footer of the page? That all happens in the layout template. The /layouts/index.html file is the layout used for the homepage. And this is what it looks like: {{ .Content }} pulls the content from the corresponding page in the /content/ folder. So, for the homepage here, it pulls the content of the homepage from the /contents/_index.md file. Additionally, I’m calling the homepage header as well as the site footer in here using partials. By default, when you require partial "footer.html" ., Hugo will look for the partials—any partial—inside a partials directory which in turn is located inside the layouts directory. the Hugo docs on partials for details on what the dot at the end of the statemenet refers to and what it does, and how you can customize partial calls. And that is how you create the homepage for your site: a /content/_index.md file that contains the homepage content, which is then called and laid out using /layouts/index.html. Adding a static page After I got the homepage set up, I wanted to set the rest of the static pages up before moving on to the more dynamic content. So I set out to build the About page. I had to do a lot of Googling and reading help threads in the Hugo forums and elsewhere to figure this one out. So I hope this post will be most beneficial when it comes to creating static pages—which, surprisingly, turned out to be quite simple. Static pages are created in the root of the /content/ folder, just like the homepage. However, unlike the homepage, the file names will not start with an underscore. Also unlike the homepage is the fact that you will need to specify the type of the page as well as tell Hugo to include it in the site’s main menu, give it a title and a description. For the About page of my site, I created a /content/about.md file. The front matter of the page looks like the following: Notice the type value. As I mentioned before, you can specify any type in there. I used static because it literally describes the type of this page. (You’ll also find a lot of online resources using this type for static pages, too.) The page variable is telling Hugo which template in the /layouts/ directory to use. It is worth noting here that Hugo will automatically use this template even if I don't tell it to. But I remember banging my head against the wall a lot at first when I was trying to figure out how to use the layouts for the pages. I didn't know which layout was going to be used. Despite reading the docs, I still found myself doing and undoing a lot of things and then seeing things work and not work like some sort of magic. Hugo felt like a black box at first that took me a few days to figure out enough to feel comfortable writing about it. When it finally worked, I decided not to touch the front matter anymore because I was afraid I may end up breaking the layouts again. But now that I know better, it's useful to note that you don’t really need the page variable in there. The title will be used as the title of the link in the menu. (If you look at the menu at the top of this page, you’ll see it as “About & Interviews”). The description is used in the header partial as mentioned before as a <title> for the page (which you can see in your browser‘s tab description.) The menu variable tells Hugo that this page should have its own link in the main menu. The weight variable is very useful because it allows you to control the order in which your items appear in the menu. If you don’t use it, Hugo will use its own default order, which is not the order I wanted on my site. You can set weights in negative values as well. All other static pages are created similarly. The only thing that’s different for each of them is the title and description as well as the order in the menu. The layout used is the same for all of them. I’d like to note something here that we will get back to later: Hugo has a specific order in which it chooses which layout to use for every page you create in /content/. We will talk about this more in the layouts section below. So had we not specified a /layouts/static/single.html as a layout template, it would have used a different template from a default folder inside /layouts/. More on this later. Last but not least, and just like the homepage, the HTML content of the about page is placed in the about.md file, and then pulled into the /layouts/static/single.html template using {{ .Content }}, with a call to the header and footer partials as well. Note how the static type has a corresponding static folder in the /layouts/ directory that contains its layout template. Content Archetypes You may have noticed in the screenshot above that I also have a folder called /archetypes/ at the root of my site. This directory is also related to the content types you create. But it has a specific and very useful purpose. To explain the purpose of this directory, I’m going to first quote the corresponding page in the Hugo docs: In Hugo v0.11, we introduced the concept of a content builder. Using the CLI command hugo new [path/to/my/content], an author could create an empty content file, with the date and title automatically defined in the front matter of the post. While this was a welcome feature, active writers need more flexibility. When defining a custom content type, you can use an archetype as a way to define the default metadata for a new post of that type. Archetypes are quite literally archetypal content files with pre-configured front matter. An archetype will populate each new content file of a given type with any default metadata you’ve defined whenever you run the hugo new command. In other words, defining an archetype allows you to speed up your content creation process, because it will populate the front matter of your new page with all the variables you want it to. For example, suppose I want to create a new case study (which would go in /content/case-studies/). Instead of going into the directory and creating a new .md file for the new page, I can type this one-liner into the terminal and Hugo will create the new file for me: And the new case study (my-new-case-study.md) will automatically be populated with variables for: client name, client logo (path to the image), client description, project description, project date, … and many more. The values for these variables will be empty by default, ready for me to fill them up with their values. The following image shows the variables I have defined in front matter of the case-studies archetype: archetypes directory that correspond to the other four type sections I have on my site. That’s pretty much all there is to know about archetypes. You can read more about them in the Hugo docs page. They’re pretty handy. You don’t absolutely need to define them, but I reckon you’ll want to. Laying content out with page layouts and creating an index page for posts This is the part that got me the most confused at first. How do I know which layout will be used for this section? How do I know how many templates needs to be in each one or whether I need any at all? I did a lot of fiddling around, Googling, and, mostly, just trial and error until I managed to make the layouts work. Then I started breaking them so I could understand how and why they worked. I can now finally confidently say that I’ve got the hang of them. Generally speaking, if you’re creating a very simple blog, you will only need two default templates: list.html and single.html. The list.html would be used for the pages whose role is to display a list of items, such as the blog’s index page where you see the list of all blog posts you have. The single.html, as you may have already guessed, is used to lay out the single pages such as the individual blog posts. These two templates would go in a /_defaults/ directory inside /layouts/. So, if you create a blog with a few posts and don’t give Hugo any special instructions about how to lay their content out, it will go looking in /layouts/_defaults/ for templates to use. I have these layouts in place as a fallback. But I override them. You can override the default templates by providing templates that fall under the same section name or content type as your content. In other words, you can create a similar directory structure in the /layouts/ directory to the one you have in the /content/ directory, and Hugo will follow that structure to determine which template to use. Or, you can create a directory that has the same name as a type you’ve defined in the content directory, such as the static type we defined for the static images. Hugo will then use the template inside /layouts/static/ as a template for all the pages that have type = static, instead of using the default templates. For example, I created a /layouts/static/ directory, and inside that directory I created a single.html file, which Hugo will use to override /layouts/_default/single.html to lay out the static pages. Once again, the /layouts/static/single.html page is just a template containing the following: where the content of the template is pulled from the respective markdown. So, the generated about.html page is in fact the above /layouts/static/single.html page, with the {{ .Content }} pulled from /content/about.md. Now, to create an index page for a list of posts as well as the posts I want to list, such as the blog page and the articles it lists, or the workshops page and the workshop details pages, we do something very similar. Just like we created a directory for the content type defined using type that has the same name as the type itself, we create a directory for each of the other content types that were initially defined using directory structure, and we give that directory the same name as the directory name it has in the content folder. Or: just like we created a folder in /layouts/ named after the content type, we create a folder for each of the content sections (blog, workshops, etc.) and name the folder after the section, so we end up with the same directory structure inside /layouts/ as the one we have in /content/. Confused yet? Don’t be. Here is what it looks like for my site: Let’s take a look at the blog section again. The /content/blog/ directory has a corresponding /layouts/blog/ directory. Inside the /content/blog/ directory I have an index page: _index.md and the blog posts. Inside /layouts/blog/ I have a list.html template as well as a single.html page. Hugo will use the list.html template for the _index.md page and the single.html template for each of the individual blog posts. Similarly, each of the other sections also gets its own layout directory containing a list.html and single.html template. As I mentioned before, you don’t really need all these layouts. And you may have noticed that a few layout pages I have are exactly the same except for their names. The reason I’m doing this is for future flexibility. If I ever want to change the layout for one type or section, I’ll just have to modify its corresponding layout template. If your site is simpler than mine and does not have as many content types, you’ll probably not need to do as much as I did here. The only exception to the layouts directory structure rule is the homepage, whose layout template is placed in the root of the /layouts/ template, named index.html. Please note that it is important that you check out the default order in which Hugo chooses the template for each page. I highly recommend you do so. To quote the docs: Hugo uses a set of rules to figure out which template to use when rendering a specific page. Hugo will use the following prioritized list. If a file isn’t present, then the next one in the list will be used. This enables you to craft specific layouts when you want to without creating more templates than necessary. For most sites, only the _default file at the end of the list will be needed. Users can specify the type and layout in the front-matter. Section is determined based on the content file’s location. If type is provided, it will be used instead of section. You can learn more about this order prioritization in the corresponding page in the docs. Looping through section lists The last point I want to talk about in the technical Hugo section is listing the posts of a section in that section’s index page. Again, let’s take the blog in /content/blog/ as an example. Markdown files will, of course, not include any templating logic. So, to list all the posts of the blog, we’ll need to do that in the layout template corresponding for that index page, which is located in /layouts/blog/list.html. The loop and all other templating logic is written in Go. Now, the loop itself can and will probably be different for a lot of you. After Googling around a lot, I managed to end up with the following loop, which shows the latest five posts and then calls the pagination partial after the loop: The {{ range .Paginator.Pages }} part is the key here. Each .Paginator you use in any section’s index page will loop through and display the posts in that section. The (.Paginator 5).Pages tells Hugo to only list five posts. The loop in the code above will go over the posts in the blog section, listing only the most recent five. A similar loop in the layouts/workshops/index.html file would loop over the workshops inside /content/workshops/ and display a list of the posts in there. As for the pagination.html partial, mine currently looks like this: Feel free to dig into the variables more and learn more about them. I find that the code above is understandable as it is, but, again, if you need more functionality, the docs and forums would probably be able to help more. Creating an Archive page In addition to the default blog page, I wanted to add an archive page that lists all of my articles in one pagination-less page. This was not as straightforward as I’d hoped it would be. The docs didn‘t help me much and I again found myself Googling. I came across this extremely useful article, and pretty much used the same technique the author is using. For the archive page, I created a static page inside /content/ and gave it a new type: archive. The page will use the layout inside /layouts/archive/single.html. Inside the layout template, I loop through the articles using a loop similar to the blog’s loop, but with an important modification: {{ .Title }} {{ .Date.Format "January 2, 2006" }} {{ if .Params.External }} — for {{ .Params.External.Host }} {{ end }} Read more ›› Heads up: .Site.Pages will loop through all pages you have on your site. In other words, it will list every single .md file you have inside /content/. In order to tell Hugo to only display posts inside the /content/blog/ section, you “filter” the pages using "Type" "blog". Similarly, if you want to create an archive page for a different section, use that section’s type name as a filter. And that’s it. Hosting on Netlify Github pages was my choice for hosting this Web site over the last couple of years. At some point, it started coming short. There also seemed to be some weird caching issue happening all the time where I found myself having to push changes to the repository twice in order for the latest change to show up (I guess the cache may not have been invalidated whenever it needed to). So I’d start creating “dummy commits” only to clear the cache and be able to see the changes I’d made live. Now, I’m not sure if this was indeed a cache problem, although that’s exactly what it seemed like it was. I also don’t know if anyone can replicate this issue. No, I haven’t asked Github support about it. I’ve hated my Web site so much that I kinda thought “I’ve got a lot worse happening locally to even worry about this online issue”, so I just ignored it all along. I also saw how blazing fast Netlify was when I worked on Smashing Magazine. Netlify also offers to “make your site or web-app many times faster by bringing it closer to your users. Instead of a single server, push to a global network of intelligent CDN nodes that also handle asset fingerprinting, automatic caching headers, and smart redirect & rewrite rules.” And to top that off, if you’re a developer and/or you’re doing open-source work, Netlify offers you a free Pro subscription for life. All they ask for in return is a mention of Netlify on your site or application. For me, this was no issue at all as I always mention where my site is hosted in the footer. So, I signed up for the free Pro subscription. Free, fast hosting! Woohoo! It only takes a few clicks to get your site up. Create an account on netlify.com Link your Netlify account to your code repository. Mine is hosted on Github so I just connected it (you do all this from the Netlify dashboard). Specify the build destination folder as well as a build command. hugo is the build command I used, and public is the build directory. (See screenshot below.) Set up a custom domain. This also includes making some DNS changes. It took literally only 3 clicks to get an SSL certificate and HTTPS running for the site. And.. well.. you’re done. I should probably mention that I did face a couple of annoyances while I was making the switch but it was not Netlify’s fault. And the Netlify team was super helpful and swiftly debugging the issues I was having. After making some DNS changes in my domain registrar’s dashbard, it took a few hours for my site to be online on my custom domain. A couple of tips worth mentioning: Add your local /public/ folder to your .gitignore file. Netlify will build your site for you on their servers. In order to avoid any possible conflicts, don’t push your public directory to the repo. I keep mine local now. I had an issue with some templates rendering when I was committing it before. Check the Hugo version you’re using (hugo version) against the version that Netlify uses. I had some build errors preventing the deploy at first which were a result of my version being ahead of that of Netlify’s. Let the team know if you face any similar issues so they can add a build environment variable to your site to match your local version. Here’s what a part of my Netlify dashboard looks like: I also love that Netlify provides options to optimize and bundle assets for you, improving your site’s overall performance sometimes as well. I saw quite a few performance improvements and more green A’s in the webpagetest.org results that used to be red before. I still have a few more improvements to make. Summary of current set up This Web site’s source code is hosted on Github. I use Hugo as a static site generator. Pushing to repo automatically deploys using Netlify. Hosting with Netlify for free with the developer’s Pro plan. It’s worth mentioning at this point that compiling my entire site now after every change, without having to filter out old articles or anything like that, takes Hugo no more than 40 seconds every time. To be more accurate, it takes Hugo around 39ms to compile my entire site now, compared to the minutes needed by Jekyll before, even after using flags like --incremental. Future Plans These include some but not all of the things that have been on my to-do list for the last couple of years that I have been postponing, partially because of the previous Jekyll situation: Starting a mailing list. This will be coming later this month. A new section on the site for articles that don’t fit into the technical articles section. Improving the site code enough to not be embarrassed by it anymore and make the repo public on Github. Make the site available offline. And make it even faster. There will be an AMA but not the traditional Github-hosted AMA. There are aspects of the Github-based format that I don’t like. More info and details will also be out as soon as the newsletter is. Write more frequently. I’m letting way too many ideas slip that I should honestly be turning into blog posts. I promised myself to write more even if the article ideas are not as deep-dive as my usual articles are. And this post is a start. Final Words? I’ll let Agnes express how I feel about my current setup, even though I know I can and will be improving some details more in the future: An animated image of Agnes from Despicable Me grabbing her friend and most excitedly saying “I’m so happy”. via GIPHY At least for now I know I have a setup that won’t give me any headaches whenever I want to make any new changes to my Web site. I’m also enjoying writing articles for the blog again, which means that you can expect more to come in the next few weeks. Thank you for reading.

Building a fully-accessible help tooltip

Today is one of those days that started out with a Google search for yet another accessibility question/concern. I’m working on a new project for my client Provata and part of that project is to build a sweet and seemingly simple help tooltip which explains to the reader/user what the Framingham calculator is. The tooltip is triggered by a small help icon like the one shown in the top right corner of this screenshot: As with every project, starting out by thinking about what HTML element to use to mark up a component was the first thing I did. But it turned out there is no HTML element to mark up a tooltip like this. And when we have no semantic elements to mark up our components, we are faced with the challenge to make sure that assistive technologies (ATs)—which are usually capable of understanding and conveying meaning via semantics—are able to understand what our elements really are and what they do. ARIA attributes to the rescue? Making elements more readable by ATs when HTML isn’t enough is possible using ARIA attributes. For example, you can get by creating a progress bar without actually using the not-too-well-supported HTML <progess> element. Making that bar look and behave like a bar is straightforward using some CSS, but if you’re using divs and spans to build it, you need to give ATs something more to make something of those non-semantic elements. This is where ARIA attributes like role="progressbar" and its companions, the helpful aria-valuenow, aria-valuemin and aria-valuemax (among others), come in handy. Sprinkling in some simple JavaScript, you upate the value inside aria-valuenow as the user progresses through whatever steps you provided them with and you’re generally good to go. You can read more about this on MDN if you’re curious or unfamilir with this. Great. We have an ARIA attribute value to help us indicate that a certain element is a tooltip: tooltip. Using role="tooltip" ATs know that this element is indeed a tooltip. But tooltips are usually triggered by an action performed on another element. Let’s first get back to the basics. According to Wikipedia: The tooltip or infotip or a hint is a common graphical user interface element. It is used in conjunction with a cursor, usually a pointer. The user hovers the pointer over an item, without clicking it, and a tooltip may appear—a small “hover box” with information about the item being hovered over. Tooltips do not usually appear on mobile operating systems, because there is no cursor (though tooltips may be displayed when using a mouse). I have a problem with the “Tooltips do not usually appear on mobile operating systems, because there is no cursor” part because mobile users have just as much right to get information on a page as non-mobile users. Whether you’re using a mouse or your finger, you should be able to understand what the Framingham score is, so this tooltip should be accessible in all contexts. And this is exactly where the fun starts. Triggering the opening/closing of the tooltip I knew I couldn’t rely on hover alone (even though my client only requested hover) because, unless you have a touch screen with a fancy digital pen which allows for hover to be triggered, you won’t be able to see the hint inside the tooltip, and that is unacceptable. I set out to make the tooltip show when the help icon is both hovered and clicked. It is worth noting at this point that sometimes tooltips work on both touch and pointer screens without having to do any extra work, such as those that are shown as help labels on input fields, like this example by Heydon Pickering. In scenarios like this one, role="tooltip" in combination with aria-describedby are enough to indicate to ATs that this piece of text is indeed a tooltip which describes the content or functionality of the input field. Marking the tooltip up in this case is very easy because it’s already clear enough what it is. All that remains is for you to show/hide the text when the input field is focused, and this can be done using a couple of lines of CSS alone. The experience is great on mouse and touch screens, and everyone gets to experience it the same way. However, things aren’t so straightforward when you have an example like the one in my project. And apparently I’m not the only one who’s been here and has been just as confused as to how to approach this. Here are a few of the ideas that crossed my mind as I was thinking about the implementation of this: Use a <button> to trigger the opening and closing of the tooltip. Tooltip would initially be hidden so that ATs won’t read it out loud as the user moves down the page. The tooltip interrupts the flow of the content in our project’s case and so should only be shown on demand. “on demand” means when the user hovers/clicks/taps/focuses the trigger. The tooltip would initially be hidden using display: none and only shown on demand. Since semantics and “how machines would read this” is how I start all of my HTML code, I thought: if I use <button> I’ll have to use aria-controls to indicate what that button controls and that it will show/hide some element when it is clicked. All good. Speaking of semantics, I could also use a link (<a>) that links to a specific section on the page, which in my case is the element containing the hint. When using a link, the user will jump to the section on the page to which they’re being taken. I hate page jumps. I avoid them like the plague unless the decision to jump is intentional. (For example, a “Back to top” link on a very long page.) In order to avoid the jump when using <a>, and in order to make the <button> open and close the tooltip, I need JavaScript. For some holistic reason, I wanna avoid JavaScript and use it only when necessary. What if the user is a senior using some very old machine that has JS disabled? Usually, when I’m torn between two solutions and when the JS-no-JS thoughts start floating in my mind, I look for second opinions. My first source of a second opinion is Google. I thought: “someone else must have built one of these before, and so must have somebody else too, so let’s see how they approached it and solved these issues”. At this point I was still on the “I want to do this without JS if possible” boat, but believe it or not I love JS and was completely open to using it if the JS-based solution is better than all of the others. Googling got me to land on a question that was exactly the same as mine. I found a lot of similar questions but all of them were more like the tooltip-on-input example. I found a very old thread started by Zoe Gillenwater who had the same question back in 2011 that I had today. I am aware that some technical details in there would/could be invalid today but the general principles are still valid. I highly recommend you read through that thread before continuing to read this article because everything else in here is based on some of the insights I got from that thread. Main points mentioned in the thread included: Avoid using <button> and stick to <a> because links can be used to practically anything whereas buttons should be left for using in forms. I have to say I disagree here. If you know a very good reason to avoid using <button>, please let me know. Using <a> you have to consider/remember: If you use <a> and have the hint be included inside of it: The code looks like this: <a href="#" aria-describedby="#tip"> <!-- your icon here, img or svg --> <span id="tip"> Your hint text here </span> </a> The text will be readable with the flow (which is not favorable in my case) because the content of the hint interrupts the flow of the information and data displayed in the main content. Using CSS only, you can hide and show the text with display: none and display: block respectively when the link is hovered. This is good for sighted users using a mouse. However,… If you hide the text using display: none inside the <a> and show it on focus, ATs won’t be able to read the shown text because the contents of the link are announced on initial focus only and won’t be re-announced when the text is displayed inside the link with display: block. Testing this out I noticed that since the link doesn’t really link to anywhere, the user will jump to the top of the page when they tap the link on a touch screen. This is particularly horrible in our case because we have a long page and jumping up will only confuse the users. This can be solved using JavaScript to preventDefault on click. (My opinion: I really dislike the fact that the link doesn’t really link anywhere. It’s a self-containing link, if that makes any sense, which negates the role of the link to begin with, in my opinion. So even though I tested it out of curiosity, I knew I didn’t want to use this.) If you use <a> and have it link to a separate piece of text (not a descendant of the link itself): The code would be along the lines of: <a href="#tip"><!-- icon here --></a><div id="tip"> <!-- tooltip text here --> </div> The link still causes a page jump unless using JavaScript. On touch screens, tapping the link focuses it which in turn opens the tooltip, but the link image remains the same and there is no way to close the tooltip unless the user clicks anywhere outside it to remove its focus, which is not intuitive because there’s a lot of cognitive effort and guesswork and “how do I close this” guesswork and frustration involved, especially since the tooltip covers the content when open. Every single no-JS solution came with a very bad downside that negatively affected the user experience. JavaScript is the way to make this work properly for every user in every context. It solves every one of those problems mentioned, except for the “this link doesn’t link anywhere” problem which can only be solved by, well, not using a link that links nowhere. :D (Some may disagree that a link not linking anywhere is not particularly wrong or invalid, but it’s not something I’d personally do.) I ended up choosing a solution that works, using JavaScript, and has a not-too-bad fallback as well. This pretty much covers the main thoughts and considerations I had throughout this. Conclusion(s)? JavaScript is imperative to make fully-accessible interactive components. Sure, you can get away without using it in some cases, but a lot of accessibility requires JavaScript. Some ARIA roles and attributes are absolutely necessary to make components accessible, and many of those will simply not behave as they need to unless you make them work with JavaScript. Since my client is a health company, it is more likely that their users have one form of disability or the other than it is that they have JS disabled, so it’s safe to worry about not implementing JavaScript than about it not running. If you’re interested in learning more about which attributes require what, I highly recommend checking out the ARIA Role Matrices from WhatSock. It provides and easy-to-scan and read overview. Paul J Adam has also created a demo to show the different ways to show tooltips on hover. His examples still use JavaScript to make the components more accessible by toggling ARIA attributes as the tooltips open/close. This one is also definitely worth checking out. Did I miss something? Let me know on in a tweet.

Mimic Relative Positioning Inside an SVG with Nested SVGs

Positioning elements inside an SVG image is very similar—if not identical—to positioning elements absolutely in HTML. Every element in SVG is positioned "absolutely" relative to the SVG viewport, and the position inside the viewport is governed by the current coordinate system in use. But this similarity in positioning elements should not conceal the fact that there is a fundamental difference between SVG elements and HTML elements: SVG elements do not have a box model like HTML elements do in CSS. Before we move on, let’s quickly review what a box model is in CSS and how it affects positioning things. Quick Review of The Box Model in CSS Every HTML element has a box model in CSS that is composed of four boxes: the content box, the padding box, the border box, and the margin box. box-sizing entry in the Codrops CSS Reference. Normally, when an element’s size is set, the width and height properties determine the width and height of the element’s content box. Any padding added to the element will increase the total computed width and/or height of the element—this is how the default box model works in regards to sizing the element. The box-sizing property allows you to control how the sizing of an element’s dimensions works. More specifically, using the box-sizing property, you can tell the browser to include the padding width and/or border width in the width of the element, without increasing that width. This is useful for many use cases, but mostly so for when you’re building grid systems in CSS, for example. You can learn all about this property and its values in this entry over on Codrops. An element’s box model is also used to create a positioning context for the contents of the element, where applicable, or for the element itself. When the value of an element’s position changes from the default static value, it either creates a positioning context for its descendants or for itself. Whenever the default position changes, a positioning context is needed to specify where and how an element is going to be positioned outside the default page’s content flow. (You can learn more about this subject here.) If you want to remove an element from the page’s content flow, you can do that by positioning it absolutely. Positioning an element absolutely means it will be positioned relative to one of its ascendants, using that ascendant’s box as a positioning context. Each positioning context, however, requires a coordinate system. The cooridnate system is established by the dimensions (width and height) of the element’s box model. Any descendant of the element will then be positioned inside and relative to the element using this coordinate system. In SVG, however, there is only one coordinate system by default used to position elements inside the viewport: the current coordinate system in use, established by the SVG viewBox. And so when an element needs to be positioned inside an SVG, it is positioned relative to the entire SVG viewport. Technically, there are two default coordinate systems in an SVG. But only one of those is relevant when dealing with positioning SVGs unless you explicitly change the values of both. If you're not familiar with SVG coordinate systems and how they're established and used, I highly recommend reading this article before continuing through this one. In this article, we'll be dealing with the ‘normal’ case where we only need to deal with one. Individual elements don’t have a box model and therefore don’t have their own coordinate systems that can be used as positioning contexts for other elements. So, what if you do want to position an SVG element relative to another SVG element or group of elements? The answer is: nested <svg>s. Nesting SVGs One of my favourite things about SVG is that it’s an image defined by markup. And that markup is what gives us a lot of power over the contents of that image and how they are displayed. You can nest <svg>s. That is, you can put an <svg> inside another <svg>. And then you can put another <svg> inside that <svg>. And then you can put yet another svg inside that svg. And you can go on and on. You can nest SVGs as deeply as you want. How many levels deep you want to go depends on what you want to do and whether or not you need to, of course. I’ve personally never needed to nest SVGs more than two levels deep. Some notes about nested <svg>s The inner <svg> element does not require specifying a namespace (xmlns) on it because it is assumed to be the same namespace as the outer <svg>’s namespace. Even the outer (root) <svg> does not require a namespace if it is embedded inline in an HTML5 document. You can use a nested SVG to group elements together and then position them inside the parent SVG. Of course, you can group elements inside an SVG using the group tag <g>, but using an <svg> instead has a few advantages, such as being able to specify the group’s width and height, and positioning it using absolute values x and y instead of having to use transforms (for <g>). By specifying a width and height to the <svg>, you restrict the content inside it to the bounds of the viewport that is defined by the width, and height attributes. Any content that lies beyond these bounds will be clipped. Percentage values specified for elements inside an inner <svg> will be calculated relative to that svg, not relative to the root svg. Percentage values specified on the inner <svg> itself will be calculated relative to the root svg. So, Why Nest <svg>s? One use case for nesting SVGs is creating interesting responsive effects where the contents of the SVG would hide or reveal other portions of content at different viewport sizes. Such an example is the following SVG illustration of a small bird inside an egg: Normally, if the SVG is responsive, resizing the screen would make the entire SVG smaller while maintaining the positions of the content inside of it and the spatial relationships between them: Resizing the responsive SVG in the browser makes the SVG shrink in size, without affecting the position and spatial relationships of the content inside of it. By nesting svg elements, we can create separate “layers” inside the root <svg> that we can then control so that the contents of these layers would change position inside the root svg as the viewport size changes. By doing that, we can show and hide different portions of content inside the SVG as desired. svg elements, we can create separate “layers” inside the main <svg> For example, we can separate the above illustration into 3 layers that would reveal the small bird on smaller sizes: This effect is achieved by using different preserveAspectRatio values on each of the inner svgs. This ensures that the contents of each svg—i.e. the contents of each ‘layer’, ‘sticks’ to either edge of the root SVG, thus revealing the content in between. I’ve written a detailed article about how to achieve this; so, if you’re interested, do check it out. ‘Relative’ Positioning in SVG Using a Nested svg The fact that contents of an inner svg are positioned relative to that svg itself gets us one step closer to positioning elements relative to other elements as opposed to being relative to the root svg. But how exactly does a nested svg enable us to position one element relative to another non-svg element? Before we answer that question, we need to understand what an SVG element’s Bounding Box is. What is a Bounding Box? Not all SVG elements are created equal. The powerful thing about SVG is that its basic shapes allow us to create all kinds of non-rectangular shapes: from arbitrary paths, to open or closed polylines and polygons, to circles and ellipses. Because of the nature of these elements and their lack of a CSS box model, the SVG specification compensates for the lack of a box model by introducing the concept of a bounding box: In simpler words, a bounding box is the smallest rectangle that you can draw around an element, that encloses the entire element—all its points and edges. Transform panel. Three kinds of bounding boxes can be computed for an element: The object bounding box is the bounding box that contains only an element’s geometric shape. The stroke bounding box is the bounding box that contains an element’s geometric shape and its stroke shape. The decorated bounding box is the bounding box that contains an element’s geometric shape, its stroke shape and its markers. An element’s bounding box is characterized by properties that can be retrieved using the getBBox() method—the SVG equivalent of getBoundingClientRect(): x, y, width and height. Using the element’s bounding box, we can fake the presence of a coordinate system around that element, which we can then use to position other elements. More specifically, we will be creating and using an inner <svg> to establish a new cooridnate system around an element. The properties of the <svg> will be defined by the properties of the element’s bounding box: the x, y, width, and height properties. Creating a new coordinate system around an SVG element Suppose we have the following SVG image (courtesy of Vecteezy) with the bird and the nest: Let’s have some fun. The bird in the above image is trying to get back to its nest. (My idea of fun is, admittedly, not than fun.) Normally, we are able to position the bird above the nest by specifying its position inside the SVG using the entire SVG canvas’s coordinate system. We can certainly do that. But, ideally, we’d be able to position it by using percentage values that would be calculated relative to the nest’s “box”. We can mimic that by creating a coordinate system around the nest using our new <svg> element. The <svg> element has its own coordinate system established by its width and height. We will use that coordinate system to make up for the missing coordinate system on the nest. Then, we move the bird (the actual bird content) into that <svg> tag. By being contained by the <svg>, the bird‘s position will be calculated relative to the coordinate system established on that <svg>. But to create the relative connection between the bird and the nest elements, we need the positioning context of the bird—which is our <svg>—to resemble a coordinate system around the nest. In order to do that, we will position the <svg> on top of the nest, visually. It’s important to note here that the inner SVG does not actually wrap the nest—the nest elements are not contained inside the <svg> tag. We’re only positioning the <svg> on top of the nest, visually, so that it seems as though the <svg> is the visual representation of the nest’s coordinate system. In order to determine the exat position of the <svg> (its x and y position inside the root svg) and its dimensions, we will be using the nest’s bounding box properties. The position of the <svg>—the x and y values—will be equal to the x and y values of the nest’s bounding box. That is, the bounding box of the group of elements forming the nest. (Groups can have bounding boxes, just like single elements can.) The inner svg will also have explicit height and width values which are equal to the height and width of the nest’s bounding box. Here is what it looks like visually: What the above image is missing is the fact that the bird is now contained inside of it. So this is what it really looks like: The grey border is the border representing the bounding box, and also the new coordinate system around the nest established by the svg. It’s important to note here that the bird is now positioned relative to the coordinate system of the inner <svg>. Notice how it is offset by some amount of pixels from both the top and left edges of the inner svg, just like it was positioned relative to the root svg. That is fine for now. We will need to get rid of that space to get a finer control over the position of the bird. But we’ll get to that shortly. Another thing to note is that since the inner svg has an explicit height and width which are equal to the height and width of the nest’s bounding box, the bird’s feet get cut off at the bottom due to the way it is positioned. If you have other, more or different elements in your own projects, those might get cut off too. You definitely don’t want that. So to work around that, you need to explicitly set the overflow value to visible on the inner svg. This will ensure that the inner svg behaves only like a positioning context, not like a container that restricts its contents to a specific area visually. Here is what the code looks like: Just like with the root svg, the viewBox value of the inner SVG svg#coord-sys is determined by its dimensions. Next up, we need to position the bird inside the new coordinate system. I won’t refer to the inner svg as “inner svg” anymore—I’ll be referring to it as svg#coord-sys. Since we will be positioning the bird inside the svg#coord-sys, we need to be able to specify a position for the group of elements forming this bird. After all, the bird is not made up of one element only—it is a group of shapes. And so we need to position a group of elements, not just one element. The group of elements forming the bird is wrapped in a group (<g>) element. But the problem is: the <g> element does not have x and y attributes. So we can’t simply move it to a specific position like so: Usually, to move a group of elements around inside an SVG, we use SVG or CSS transform functions (translation transformation, most of the time). You can use transforms to move the group around, sure. But that would negate the whole idea we’re trying to achieve and would make the new coordinate system useless. After all, we could have used transforms to position the bird close to the nest inside the root svg without having to create a new coordinate system. What we want is to mimic the way elements are positioned in CSS, relative to each other. So to say “move this group of elements to the position (x, y) inside this particular positioning context”. Since <g> does not have x and y attributes, we’re going to substitute it with another <svg>. The svg wrapping the bird has an ID bird. This SVG, as opposed to its ancestor, will only serve as a container and, even though it does create a new coordinate system, we won’t be using that system. Using this svg, we can now move the bird around inside the new coordinate system established around (on top of) the nest. At this point, it is best to get rid of the white offset space around the bird. The innermost svg#bird has the same dimensions and viewBox as its wrapping svg#coord-sys; which means that in order to move the bird around, we need to take this white space into account. So if we want to move the bird to position it at the top left corner of the system, we won’t be able to simply say set x and y to zero—we will need to use a negative offset in both directions to achieve it. That’s not practical. We would also need to take this offset into account wherever and however we want to position the bird later. At this point, you need to be not only familiar but also comfortable with how the viewBox works. I’m going to assume you are. If you’re not, pause here and go read this article first. We will change the value of the viewBox of svg#bird to crop the white space out. (So we are going to use its coordinate system, but only a little bit.) By default, a nested svg will occupy 100% the width and height of its container, unless you tell it otherwise. So svg``#bird now has the exact same dimensions as that of the svg``#coord-sys. It’s the one with the pink border in the following image: We don’t need the dimensions to be different in this example so we will leave them as they are. The image above also shows the amount of white space by which the bird is shifted inside that svg. So in order to “unshift” it, we will change the value of the viewBox of the svg#bird to crop that white space out. That will shift the bird so that it is positioned at the top left of the coordinate system. I’m unfocusing svg#bird in the following image, so only the nest’s coordinate system is still shown, and the new position of the bird inside of it: So now that the bird is positioned at the top left of its wrapper, we can move it around and get the expected result every time. For example, if we were to move the bird by 50% in both directions: We would get the following result: With this setup, we can now move the bird around inside the nest’s coordinate system just like we would move an HTML element inside another one in CSS. Both relative and absolute position values work here too. Pretty nice, huh? This is possibly the closest we can (currently) get to relative positioning in SVG today. Granted, to get here is not the simplest process, but once you’ve got a good grasp of how SVG coordinate systems and the viewBox work, it’s hopefully not so complicated. Here is a live demo of the above bird and nest, with the position of the bird set so that it stands at the edge of its nest: See the Pen [Article Demo] Relative Positioning in SVG by Sara Soueidan (@SaraSoueidan) on CodePen. Final Words The example used in this article is a very specific example and is, admittedly, not the most practical use case of all times. Your use case(s) are likely to be entirely different. You might be working with a very different SVG where you may not even need to do any viewBox cropping at all. If you create your SVG yourself, you can position your element (e.g. the bird in our case) at the top left of the SVG canvas, so that when you wrap it in another svg, it would also be positioned at the top left, and you wouldn’t have to do any cropping at all. I left this example slightly more complex just so we can cover more scenarios. (And because I was a little lazy to edit the SVG in Illustrator after having written half of this article. But I keep wanting to deny that.) But the takeaway is how to mimic relative positioning using nested svgs. Whether you use one level, two levels, or more, the concepts are the same. You might find this technique useful for positioning SVG UI elements relative to each other. Or maybe relative positioning in dynamically created SVGs. Your imagination is the limit. I hope you found this article useful. Thank you for reading!

Making the Switch Away from Icon Fonts to SVG: Converting Font Icons to SVG

If you’re reading this article, then I can probably assume you’ve already decided to switch from using fonts for icons to an SVG icon system. Or maybe you're pondering the idea and want to get an overview of how that would be done and whether or not it's worth it. Either way, this post is here to help you with that. If you’re not already convinced as to why SVG is a better icon system, then I highly recommend reading this article—a cagematch-style comparison between icon fonts and inline SVG for icon systems. Many companies and organizations including Github have already made the switch to SVG, and have written great articles explaining why they found SVG to be a better alternative. I’ve listed some articles at the end of this post for further reading. Making the Switch 1. Grab your icon fonts files. Font icons are font glyphs. They’re part of a web font and are thus defined in web font files and formats. I don’t usually use icon fonts, so for the sake of demonstration, I headed to Fontello.com—an online icon font generator—to create an icon font that I can work with for this blog post. I picked a few icons and then generated an icon font and downloaded it. Fontello generates a folder containing a demo page showing you how to display the icons on your own page and what class names to use. The files generated by Fontello. Among the generated files is the actual font used to define the icons. The font files are available inside a font folder. The font file formats generated by Fontello. These are the files you need to proceed. We’re going to be using these files to “extract” the icons and convert them to SVG. 2. Choose your tool. To convert the icons to SVG, we can use one of the following tools: fontello-svg: “a command-line tool to generate the SVG versions of a Fontello icon set, with a corresponding CSS file.” font-blast: “You can use font-blast to extract icons from any icon font - Font Awesome, Foundation, anything from Fontello etc.” Icomoon app: a web app for generating and creating icon sets in both SVG and icon font formats. I’m sure there might be more tools to do this, but these are the ones I know about. I’m going to be using Icomoon and font-blast in this article because they’re general tools that can be used with any font and are not restricted to just one. Both fontello-svg and font-blast are used pretty much the same way, and you can find extra information about fontello-svg in the Github repository’s Readme. 3. Convert the font icons to SVG icons. 3.1. Using Icomoon To convert the font icons to SVG icons using Icomoon, we first need to upload them. Your font icons will be available as an icon set in the app. The next steps are the same steps you would take if you were choosing from the set of already-available icons on the page: Select the icons you want to download as SVG. Click the Generate SVG & More button. Like Fontello, Icomoon generates a folder containing the icons you generated, along with a demo page showing you how they can be used on your own pages. The icons you’ve converted to SVG are available in the SVG folder. There is one SVG file for every icon. The set is ready to be embedded in your page. But before embedding the icons, you might want to sprite them. That is, create one SVG sprite that contains all of the icons, and then use that sprite to display each icon at a time, wherever needed on the page. Icomoon conveniently generates an SVG sprite (symbol-defs.svg) for you along with a polyfill (svgxuse.js) for older browsers that don’t support external sprite references. 3.2. Using font-blast To convert the font icons to SVG icons using font-blast you need to first install font-blast using npm via your terminal. The -g flag (short for global) ensures that you can run the script anywhere on your computer, regardless of the installation root. As mentioned in the font-blast documentation, “You can generate icons from the command line by called the script with two parameters: the SVG file of the font, and the directory where inidivual icons should be placed”: My command looked like this: Tip: You can drag your folder into the terminal, which will sort of drop the path to that folder into the terminal, so you don’t have to manually write it or grab it and then copy-paste it. Running the above command, font-blast retrieves the icons from the font files and creates an SVG icon for each one, and saves the result to the folder you specify in the command line. My terminal then looks like this: The result of running the font-blast command in the terminal, letting us know how many icons were found and converted to SVG. The svg-icons folder I chose for the generated files looks like this: The files generated by font-blast show the source font file used to extract the icons and include a folder containing the generated SVG icons. As you have guessed, the SVG folder contains the generated SVG icons: The font-blast-generated SVG icons. The icons are then ready to be embedded on your page. 4. Sprite, Embed, Style, Animate, Have fun! There are three main ways to create and use SVG sprites. I wrote an overview of these techniques here. We will explore each of these techniques in more detail in an upcoming article (or a series of articles), show the pros and cons of each one, and how to create and use the SVG sprites, so stay tuned. You can subscribe to the RSS feed of my blog to stay up-to-date with new articles. An e-mail newsletter is in the works too! Recommended Reading: Inline SVG vs Icon Fonts [CAGEMATCH] — a must-read that clearly highlights the advantages of SVG and why it’s a superior icon system format. Seriously, Don’t Use Icon Fonts Seriously, Use Icon Fonts — I still recommend using SVG for icon systems, but it’s always good to read a different point of view. Delivering Octicons with SVG on the Github blog Ten reasons we switched from an icon font to SVG

SVG Style Inheritance and the ‘Flash Of Unstyled SVG’

There are too few things not to like about SVG, and I don’t mean the things that browsers cause by incomplete or lack of certain features or buggy implementations. Yet you might sometimes get some unpredictable results that might frustrate you when working with SVG, if you don’t know the details of how certain features should behave and what to expect from them, as per the specifications. SVG presentation attributes come with a bit of their own behavior which might sometimes surprise you. I’ve written and spoken quite a bit about styling and animating SVGs with CSS, and have included a list of resources to dive into the details at the end of the article. I’ve also touched on the subject of style inheritance and the CSS Cascade in SVG in both speaking and writing. However, the topic is worth its own blog post. I’ve been meaning to write this article for a while now but have been kept preoccupied. But what prompted me to finally write it today is this tweet I saw yesterday: Issue: Oversized SVG icons when the page’s CSS fails to load https://t.co/FwkaBAzrAT — Web Platform Daily (@openwebdaily) February 29, 2016 And I remembered that I have already mentioned the cause and solution to this issue in one of my talks as well as in the Smashing Book 5 chapter on SVG, but never in one of my articles, not even the article focused on making SVGs responsive with CSS. (See links at the bottom of the article.) So, what’s the problem again? When CSS is disabled or fails to load for any reason—such as when you’re on lo-fi, most SVG images, especially inline ones, will scale and take up the entire viewport width, thus making the unstyled page look even more ‘broken’ than it already does. I’ve come across this scaling issue quite a few times in the past when I visited Codepen on my fairly slow connection (which sometimes gets more than just ‘fairly’ slow). The responsive Codepen logo would take up the entire viewport area, thus blocking the content underneath it and forcing you to scroll down to read whatever comes after it. This—allow me to call it—Flash of Unstyled SVGs (FOUSVG) is caused by the lack of width and height attributes on the <svg> element. But the SVGs are meant to be responsive… So why would you want to set explicit dimensions on your <svg>when what you’re really trying to do is make the SVG fluid, right? Right. Ideally, we should make our SVGs responsive while also catering for any worst case scenarios where our styles are ignored or simply not applied for any reason. By taking advantage of the SVG style inheritance tree, we can make our SVGs responsive while simultaneously planning for worst case scenarios, and providing a decent, less broken, fallback. The How In order to avoid the no-CSS scaling issue, all you need to do is not remove the width and height attributes from the SVG. 1. Keep the width and height attributes This means that, if you’re creating the SVG yourself in, say, Adobe Illustrator, you should avoid checking the ‘Responsive’ option in the Export panel(s). It’s very tempting to check that option, because you do want your SVGs to be responsive, after all, but you shouldn’t check it unless what you need is for the SVG to simply occupy the entire width on the screen—like when it’s supposed to be viewport-width, for example. (I’ve embedded an SVG in my current client project and I wanted it to occupy the full page width, so I safely removed the attributes.) Unchecking the ‘Responsive’ option will ensure that Illustrator will export the SVG and preserve the dimensions it has. 2. Specify your desired width and height values in the CSS You want your SVG to scale—be fluid—and fill out its container’s width? No problem. Tell the browser you want that to happen by specifying the dimensions specified in the attributes above, using CSS properties: or maybe something like which will restrict the dimensions of an SVG icon, for example, and scale it in proportion to the text it is inline with. Specifying your desired width and height in the CSS will make sure the width and height attributes no longer restrict the dimensions of the SVG when the CSS is successfully loaded and applied. If the CSS does fail to load, the browser will use the values provided in the attributes as fallback, thus preventing the excessive scaling of the SVG. The Why: Why does the above technique work? SVG presentation attributes are special style properties—a shorthand for setting a CSS property on an SVG node. For this reason, it only makes sense that SVG presentation attributes would contribute to the style cascade. When I got started with SVG, I expected presentation attributes to be more specific than any other style declaration. It made sense to me that the “closer” a style is to a node, the more specific it is. For example, inline <style>s are more specific than external styles, an inline style attribute is more specific than <style> ‘islands’, so I thought it made sense for presentation attributes to be the most specific form of styles. But I was wrong. Just like HTML presentational attributes, SVG attributes count as low-level author style sheets and are overridden by any other style definitions: external style sheets, document style sheets and inline styles. This makes it possible to provide a fallback for when the CSS styles are not available, so the SVGs still look good in their ‘worst’ case. Tip: You can use presentation attributes to provide fallback for more than SVG scaling If you have an SVG you’re styling and animating using CSS properties, you may start by ditching the presentation attributes altogether—we do have an option to do just that in Illustrator’s Export panel, by choosing CSS Properties over Presentation Attributes. That will lead to all attributes being exported as CSS properties, if they can be set as CSS properties. You see, only a subset of all CSS properties may be set by SVG attributes, and vice versa. The SVG specification lists the SVG attributes that may be set as CSS properties. Some of these attributes are shared with CSS, such as opacity and transform, among others, while some are not, such as fill, stroke and stroke-width, among others. In SVG 2, this list will include x, y, width, height, cx, cy and a few other presentation attributes that were not possible to set via CSS in SVG 1.1. The new list of attributes can be found in the SVG 2 specification. Some of the ‘new’ CSS properties for SVG are already implemented and available in Chrome today! There is a benefit to keeping the presentation attributes inside the SVG as well, not just on the root element. These benefits are highlighted the most when you attempt to style the contents of <use>d elements in SVG. When you re-use an element, the contents of that element are copied, as is, into wherever you place the <use> in the page. But you may want to re-use an element mutliple times and style each occurance differently. You can do that by leveraging CSS Custom Properties (a.k.a. CSS Variables). When ‘theming’ multiple <use> elements with CSS custom properties, it is recommended to always keep the presentation attributes that provide the default styles for the reused SVG, so that the image is styled both when the CSS fails to load and/or when the SVG is viewed in browsers that don’t yet support custom properties. Without the presentation attributes, most styles—such as fill and stroke—will default to black, which is probably not what you want. Weird SVG scaling gotchas to be aware of Depending on how you embed your SVG, browsers will generally default to a 300px by 150px size, which is the default size for replaced elements in CSS. This is the default size you get for <iframe>s as well, for example. If the dimensions of the SVG are not specified, or if they are explicitly set to auto, the browsers will default to the 300 by 150 pixels dimension. If either dimension is set to auto (instead of 100% as mentioned earlier), the browser will cancel out the value set in the presentation attributes and will default to one of the default height and width values. Well, kind of.. Again, It Depends™. You see, the browser behavior depends on how you embed your SVG. If you embed the SVG using <iframe>, you get the 300x150 as a default. If you embed the SVG inline in the document (using <svg>), most browsers will scale it to the width of its container and will scale the height proportionally to preserve the SVG’s aspect ratio, while Internet Explorer will scale the width but not the height, so you need to explicitly tell it to scale the height as well. Fun fact: IE will scale the height of the SVG if you give it an explicit width value of 100%. Crazy, but true. I’ve written more about the rendering of different SVG embed techniques in the ‘Making SVGs Responsive with CSS’ article linked at the bottom of the article, along with ways to ensure the SVG is ‘responsified’ across all browsers. Amelia Bellamy-Royds has also gotten into more detail about the browser scaling techniques in her article ‘How to Scale SVG’ on CSS-Tricks. Scaling Tip: Never drop the viewBox Ever. This is possibly the most important thing you need to be aware of when attempting to scale SVG: you need the SVG viewBox to properly scale SVG images. need the SVG viewBox to properly scale SVG images. Do not remove it. viewBox to make sure SVG images are rendered as expected. You can check his post out here. Wrapping Up Having explicit, non-percentage width and height values set on an SVG not only helps with fixing FOUSVG issues, but it also helps with other scaling problems, especially when the SVG is used as a background image in CSS. Internet Explorer sometimes refuses to scale the image properly if it doesn’t have its aspect ratio specified with the width and height attributes. I’ve had this happen even with non-background images recently as well. Quite honestly, I don’t know the details of why or when exactly this happens, but I do know that we can avoid it by having these attributes available anyway. The viewBox is even more important than the width and height, so always make sure you keep it there. You can learn all there is to know about how the viewBox works in this article. It is a very powerful attribute that is definitely worth taking the time to master. Further Reading [Slides] Styling and Animating SVGs with CSS – my talk from 2014, given at CSSConf and CSSConf EU. [Article] Styling and Animating SVGs with CSS — sort of a talk transcript, published on Smashing Magazine Making SVGs Responsive with CSS — article published on Codrops How to Scale SVG — by Amelia Bellamy-Royds Scaling of SVG Backgrounds on MDN Styling the Contents of SVG <use> with CSS on Codrops Understanding SVG Coordinate Systems and Transformations (Part 1): The viewport, viewBox and preserveAspectRatio Attributes I hope you found this article useful. Thank you for reading!

2015 In Review

Happy new year! 🌟 OK, I felt awkward starting a blog post that way—I confess. ☺️ But this is also an unusual post—not an article about CSS or SVG, and not a lengthy tutorial about web development. It is also the quickest post I ever wrote. This is my first time writing a year in review kind of post. A lot of great stuff has happened in 2015 that I thought are worth documenting and have a look back at a few years from now. I’m grateful and thank God for every one of these things and everything else that has happened. And since a photo is worth a thousand words, I’ll start with a preview of the highlights in a few pictures, followed by sort of an alt text for each one, and then a little more: Delivering the opening keynote at CSSDevConf 2015. Photo by Chris Casciano. My 2015 speaker badges for the conferences: CSSConf AU, Smashing Conf LA, btconf Duesseldorf, Microsoft Edge Summit, Generate London, Velocity NY, CSSDevConf, View Source conf, ffconf. Me accepting the Developer of the Year award at the net awards ceremony. Photo by and copyright of net magazine. (I think I look sleep deprived in that photo, but it was already two hours past my bed time, so, there’s that.) Photo of the net award. (These things are very difficult to take proper photos of! ☝) Photo of the O’Reilly Web Platform Award I received in April. (I took like ten photos till I finally got a decent one. 😅) Photo of the first page of the “Mastering SVG for Responsive Web Design” chapter in the Smashing Book 5. Me giving a workshop at Smashing conf LA. Photo by Marc Thiele. In 2014, Manoela Ilic asked me to write a CSS Reference for Codrops. In February 2015, we finally released the 8–months worth of work & writing to the world. This year, I also got published for the first time in a real book—the Smashing Book 5, which I contributed to with a very extensive article about using SVG in a RWD workflow. Back in April, I won an O’Reilly Web Platform award. I had never heard of the award before I was informed about winning it, and so I had no clue that I was even nominated. That came as such a beautiful surprise! Back in June, I was nominated and shortlisted for two net awards: Developer of the Year and Outstanding Contribution. In September, I won the Developer of the Year net award. This was one of the most awesome things that have happened since I started doing what I do on the web, so thank you so much for each and every one of you who nominated me and voted for me. I am humbled and extremely proud! You are awesome! 💜 I published 23 articles. That’s an average of 2 articles per month, which I think is good. I like to take my time with the articles I write, as opposed to try to publish as much as possible during a specific period of time. I spoke at 9 conferences worldwide—in the US, UK, EU and AU, including the first Microsoft Edge Summit, and gave my first workshop about SVG at Smashing Conf in LA. (A lot of people ask me for videos of these talks sometimes. You can find a list of them—in chronological order— on my speaking page.) I gave two conference keynotes, one of which was the first day opening keynote—at CSSDevConf on board the Queen Mary (a boat!!) in California. These points pretty much sum up the biggest highlights of the year, and the ones like to remember it with. Of course, many things happened on a personal life level, but those don’t belong here, so I will spare you the list of them. This one is on the weirder kind of highlights side, but definitely one of the things I remember 2015 with: I finally got a British visa! Those of you who have been following me in the last couple of years are already familiar with my visa stories. I apply for visas a lot, given the passport I hold (Lebanese) and then the places I speak in. I need to apply for a visa for most conferences I want to speak at, which sucks but is unfortunately necessary. But one visa application that was particularly painful for me was the British visa, given how unfair the result was, simply because the person responsible for granting the visas was “not satisfied with my intentions in the UK”. 😒🙄 I decided to give it another shot last year for Generate London and ffconf, as well as to attend the net awards ceremony. After having showed evidence of my 10 previous speaking appearances at that time, the UK Visa & Immigration was finally convinced, and they granted me the visa. Woo. Of course, 2015 wasn’t all rainbows and unicorns. I failed to do some of the things I was hoping to do, too. Possibly the number one thing I regret to say that I didn’t do was to keep maintaining and updating the Codrops CSS Reference with new entries as I intended to. With client development projects taking priority over all other work, and then the many speaking and writing commitments I had, it was very hard to find enough time to do this. Maintaining the reference requires way more time than I could possibly devote for it. As such, I think it’s an appropriate time to officially announce that I am no longer the maintainer of the reference. (More news and updates about this will be shared on and by Codrops some time in the near future, so no elaboration is necessary at this point.) The reference is one those things I’m most proud of, and I know it will be well taken care of. In 2015, I also managed to strain my wrist which is still not healed today. I can’t exercise like I used to, I don’t have enough strength in my left hand to do things that I would normally do with ease, and, well, it’s just frustrating. The pain comes and goes but it’s just not healed yet, which means I still have to see a doctor (again) and keep away from any form of physical activity that adds to the strain of it. On the bright side: this means that I take longer breaks from work, which is something to add to the list of things I failed to do. I overworked and pushed myself to the limits, and reached the boundaries of a burnout mutliple times last year. This is one of those things I am currently working on and making sure it doesn’t happen again. Saying ‘No’ to stuff helps a lot, by the way. #protip To keep this post short, I will skip the 2016 resolutions list. Partly because it’s not finalized yet, mainly because my goals aren’t really year-specific, so I’m not sure they count as “2016 resolutions”, and additionally because I’ve got a couple more announcements and updates coming that deserve their own blog posts. So, stay tuned! I want my web site to be home for most (not all) of my articles and tutorials in the future, so make sure to subscribe to the RSS feed to stay updated with what comes next. So, that was my look back at 2015. I’m really excited to see what 2016 will bring. I don’t expect it to be all good, because I’m a realistic person, but I do always keep a positive eye on the future.. or at least I try to. What was your 2015 like? What have you accomplished and what are you most proud of? And what have you got planned for 2016?

Animated SVG vs GIF [CAGEMATCH]

SVG can do much more than display static images. Its animation capabilities are one of its most powerful features, giving it a distinctive advantage over all other image formats. They are one of many reasons that make SVG images better than raster images, including GIFs. But this, of course, only applies to images that are good candidates for SVG, such as: Logos non-complex, vector-based illustrations, user interface controls, infographics, and icons. Of course, if you have an image that is better suited for the raster format—such as a photograph or a very complex vector illustration (that would normally have a very big size as an SVG), then you should use a raster image format instead. Not only should the image be a good candidate for SVG, but SVG should also be a good candidate for the image. If the image size is much less as a PNG, for example, then you should use PNG, and serve different versions/resolutions of that image using srcset, or <picture>, depending on what you’re working on and trying to achieve. Generally speaking, the images listed above are usually perfect candidates for SVG. And if you’re going to animate any of those, creating your animations by animating the SVG code is the sensible way to go. However, last week, a link popped up in my Twitter timeline that linked to a set of icons that are animated as GIFs. The first thing that crossed my mind when I saw them was that they were perfect candidates for SVG and should be created as SVG images, not GIFs. SVGs can indeed replace GIFs in many places, just like they can replace other raster image formats for candidates like those mentioned above. The ability to animate SVG images is what gives it this advantage and ability. And this applies to more than just animated icons. So, here is why I think you should use SVG instead of GIFs whenever you can. Image Quality The first advantage to using SVG over GIFs—or any image format, for that matter—is, unsurprisingly, SVG’s number one feature: resolution-independence. An SVG image will look super crisp on any screen resolution, no matter how much you scale it up. Whereas GIFs—a raster image format—do not. Try zooming in a page that contains a GIF image and watch the GIF become pixelated and its contents blurred. For example, the following GIF recording of an SVG animation looks fine at this small size: SVG Motion Trails demo by Chris Gannon. Zooming into the page a few times will cause the image to be pixelated and the edges and curves of the elements inside to become jagged, as you can see in the image below: Whereas if you check the SVG demo out and zoom into the page, the SVG content will remain crisp and clear no matter how much you zoom in. To provide crisp images for high-resolution displays when you’re using a bitmap image format like GIF, you need to use <picture> or srcset and switch the images up for different contexts. Of course, the higher the image resolution, the bigger the file size will be. With GIFs, the file size will end up ridiculously large; but we’ll get to that in a minute. Also, using a high-resolution GIF and serving it at a smaller size for mobiles is bad for performance. Don’t do it. When you create GIF-animated icons or images, their dimensions are fixed. Change the dimensions or zoom in and out of the page, and they’ll get pixelated. With SVG, size is free, and clarity is a constant. You can create a small SVG and have it scale up as much as needed without sacrificing image clarity. Conclusion: GIF Animated SVG GIF, just like other image formats, are not resolution-independent, and will therefore look pixelated when scaled up or viewed on higher resolutions. SVG is scalable and resolution-independent, and will look crisp clear on any screen resolution. Colors and Transparency Perhaps the number one deal-breaker with GIFs is the way transparency is handled, especially when the image is displayed on a background other than a white background. This is an issue that is most likely to emerge when using GIF icons (whether animated or not), since icons are usually created with transparent backgrounds. For example, take the following circle with a stroke, created as both an SVG image (left) and a GIF with a transparent background (right). The problem is evident as soon as you look at the two images: the GIF circle has grey fringes around its stroke. If you’re not reading this in the browser, the effect might not be visible to you because the figure styles might not be applied. Here is a screenshot showing the problem (on the right): This happens because transparency in GIF images is binary. This means that each pixel is either on or off; a pixel is either transparent or fully opaque. This, in turn, means that the transition between the foreground color and the background color is not as smooth, and results in artefacts caused by inadequate sampling frequency, commonly known as aliasing. When a line is not completely straight, it causes some pixels (around the edges) to be partially transparent and partially opaque, so the software needs to figure out what color to use for those pixels. The halo effect “is caused by all the pixels which would have been > 50% opaque being fully opaque and carrying the bg color against which they were rasterized” (Chris Lilley). So this effect is usually a result of pixel contamination from the color of the background against which the image was composited against upon creation/saving in a graphics editor. Aliasing is usually countered with anti-aliasing, but that is not as simple when transparency is binary: There is a severe interaction between anti-aliasing and binary transparency. Because the background colour of the image is mixed in with the foreground colours, simply replacing a single background colour with another is not enough to simulate transparency. There will be a whole host of shades which are mixtures of background and foreground colours [...]. The effect in this case is a white halo around objects, because the original image was anti-aliased to a white background colour. — Chris Lilley (Source) The solution to this problem is variable transparency, commonly known as the alpha channel, which allows for varying degrees of transparency and hence a smoother transition between the foreground and background color, which is not what is available in GIF; thus, the halo effect problem. Images with the halo effect usually look best when used with white backgrounds; any other high-contrast background color will make the artefact visible. I’m not quite sure if there is a way to work around this issue, but I’ve not yet come across a GIF with a transparent background and curved edges that did not have this problem. I’ve even seen rectangular shapes suffer from it as well. If you want to use your image/icon on a non-white background—say, on a dark footer background, this alone could be a deal-breaker. But there are other reasons SVG is better than GIFs too, that we’ll cover in the next sections. Note: if you’re reading this article in a browser but still don’t see the fringes in the first image on a smaller screen, try zooming the page in to see the effect. Why might you not be able to see the fringes on smaller sizes? The answer is: the browser smoothes the edges as a part of the image resize process. Does this mean that you can utilize this to get rid of the fringes and still use a GIF? Yes, you can. But to do that, you have to use a GIF that is much bigger than the size you want to render it at, and then resize it. This also means that you will be serving your users images that are much bigger than they need, therefore taking up more of their bandwidth on mobile, as well as hurting the overall page size and performance. Please don’t do that. Conclusion: GIF Animated SVG GIF images are capable of only binary transparency. This causes artefacts, known as the halo effect to show up whenever the image or icon is used on a non-white background. The higher the background color contrast with the image, the more visible the halo effect, which makes the icons practically unusable. SVG images come with an alpha channel and do not suffer from any problems when they are used on different background colors. Animation Techniques & Animation Performance You can animate SVGs using CSS, javaScript or SMIL, and each of them gives you a different level of control that you can take advantage of to create all kinds of animations on SVG elements. There are no “techniques” to animate GIF images. They are animated by showing a series of images—one for each frame—sequentially, in a fixed manner, at a fixed pace. You know, the way GIFs just work. Granted, you can get creative with your icons before you turn them into GIFs and then “record” the animation and convert it into a GIF, but how good will it look? And how much control over the animation timing will you get afterwards? None. Unless you make sure you have at least 60 frames—that is, 60 images—per second to create your GIF, the animation will not look smooth. Whereas with SVG, achieving smooth animations is much easier and simpler by taking advantage of browser optimizations. A GIF has a bigger file size than PNG or JPEGs, and the longer the animation duration, the bigger the size will be. Now, what if your animation plays for at least 5 ot 6 seconds? What if it plays for much longer? You get the picture. Let’s look at a more specific yet minimal example. Below are two images: an animated SVG on the left, and an animated GIF on the right. The rectangle in both images changes color over the course of six seconds. svg {width: 48%;}path { animation: loop 6s linear infinite; } @keyframes loop { to { fill: #009966; } } The SVG image on the left and the GIF on the right. There are a couple of things to note here: The GIF animation looks smooth but if you look closely you will notice that the SVG rectangle is going through a wider range of colors as it transitions from the initial to the final color. The number of colors the GIF goes through is limited by its number of frames. In the above image, the GIF goes through 60 frames, i.e. 60 colors, whereas the SVG goes through the entire spectrum between the shade of pink used and the final green color. For looping animations like this one, it is generally best to avoid the color jump shown in the above animation, and create the animation so that it reverses once it reaches the green color; that way, it will transition smoothly back to pink and then start the second round of animation from there too, avoiding that unsightly color jump. With CSS, you can reverse the animation using the alternate animation direction value. But with GIF, you will need to work on your number of frames and probably end up doubling it to make this happen; this will, of course, also increase the size of the image as well. The sizes of the two images shown above are: GIF image size: 21.23KB SVG image size: 0.355KB This is no trivial difference. But we all know we can optimize our images. So let’s do that. Optimizing the SVG using the SVGO Drag-and-Drop GUI brings the SVG’s file size down to 0.249KB. To optimize the GIF, you can use one of the several GIF optimization tools online. I used ezgif.com to optimize the above image. (Other tools also exist; gifsicle is one of them.) The file size dropped down to 19.91KB. There are many options you can choose from when optimizing GIF images. I optimized the above image so that the number of frames remains intact, using Lossy GIF compression, which can reduce animated GIF file size by 30%—50% at a cost of some dithering/noise. You can also optimize it by removing every nth frame; that can reduce the file size even further, but at the cost of the animation not being smooth anymore. And in the case of an animation like the case at hand, removing frames will make the change in color be “jumpy” and noticeable. Other optimization options are also available such as color reduction (which wouldn’t be suitable for our color-dependent animation here) and transparency reduction. You can learn more about these options on the ezgif.com optimization page. To recap: If you want your GIF animation to be smooth, you’re going to need more frames per second, and that will consequently increase the file size by a lot. Whereas with SVG, you’re likely to maintain a much smaller file size. The above example is minimal, and I’m sure there are better ones out there, but I wanted the most minimal example to show the difference between the two formats. Even if you were animating the above rectangle using JavaScript or even a JavaScript framework—since animations on SVG don’t work in IE, for example, the file size of that framework combined with that of the SVG is still likely to be smaller or at least equal to the size of the GIF image size. For example, using GreenSock’s TweenLite, the size of the SVG with the library combined would be less than 13KB (which is still less than the size of the GIF), since TweenLite is 12KB minified. If you do end up with a size equal to that of the GIF, the other benefits of SVG will tip the scale and you will be getting more out of it. Some other JavaScript libraries exist that focus on certain animation tasks at a time, and come in impressivly small file sizes (<5KB), such as Segment which is used to animate SVG paths to create line drawing effects. Segment is 2.72KB minified. That’s not too shabby, is it? There can be exceptions, so you should always test. But given the nature of GIFs and how they work, you will likely find that SVG is a better option in most cases. Note: SVG Performance is not at its absolute best today, but this will hopefully change in the future. IE/MS Edge offer the best SVG rendering performance among all browsers today. Despite that, SVG animations will still look better than GIF animations, especially when you're tackling long animations, because the file size of the GIF—assuming it’s recorded at 60fps—will have a negative impact on the overall page performance. Libraries like GreenSock also offer impressive performance as well. Conclusion: GIF Animated SVG GIF images are generally larger than SVG images. The more complex and longer the animation, the more frames are required to create it and therefore the bigger the file size and the more the negative impact on performance. Unless GIF animation plays at 60fps, the animation is going to be jagged and not smooth. Also, the more the number of frames per second, the bigger the file size, especially for longer animations. Result: There will be a compromise that needs to be made. Either the GIF animation is smooth and the overall file and page size and performance is negatively affected, or the GIF animation will suffer with less frames. One form of performance is risked in both scenarios. SVG images take advantage of the browser optimizations when animating elements. Even though browser performance on SVG elements is still not at its best, animation will still perform better without having to make page performance compromises. Maintaining & Modifying Animations ..is a pain if you are using GIFs. You will need to use a graphics editor such as Photoshop or Illustrator or After Effects, to name a few. And if you’re like me, then graphics editors are not where your skills shine, and you feel more at home when you make modifications in code, not in graphics editors. Screenshot of the animation timeline as created in Photoshop. The lower part shows a fraction of the frames created for the animation. Fore more complex animations, more frames are required. Also notice the layers panel. Thanks to my designer friend Stephanie Walter for the PS animation tips. What happens if you want to change your animation timing? or if you want to change the timing functions for one or multiple elements inside your image? or if you want to change the direction in which an element moves? What if you want to change the entire effect and have the elements in your image do something completely different? You will need to recreate the image or icon all over again. Any change requires you to jump into the graphics editor and work with frames and a frame-based UI. That would be like torture to developers, and a Mission Impossible for those of us who don’t know our way around those editors enough to make these changes. With SVG, making any kind of change to the animation(s) is only a few lines of code away. Conclusion (developer’s perspective): GIF Animated SVG Maintaining and modifying GIF animations requires re-creating the image or resorting to a frame-based graphics editor’s UI to do so, which is a problem for design-challenged developers. SVG animations can be changed and controlled right inside the SVG code—or anywhere the animations are defined, usually using a few lines of code. File Size, Page Load Time & Performance In the previous section, we focused on the performance of the animation itself. In this one, I want to shed some light on the page performance as a whole and how it is affected by the image format choice you make. Fact: The bigger the file size, the more the negative impact on page load time and performance. With that in mind, let’s see how using SVG instead of GIFs can help improve the overall page load time by looking at a more practical, real-world example. At my first SVG talk, 18 months ago, I mentioned how SVG can be used to replace animated GIFs and result in overall better page performance. In that talk, I provided a real-world example of a real-world web page that took advantage of what SVG has to offer and reaped the benefits: the Sprout homepage. The Sprout homepage has two animated images that were initially created and displayed as GIFs. Two years ago, Mike Fortress wrote an article on the Oak blog, in which he explains how they recreated the animated GIFs, particularly the chart GIF (see image below) as an animated SVG image. (All rights reserved by their owners.) Note that the animation is created using SMIL so it will not be animating if you’re viewing it in Internet Explorer. In his article, Mike shares some interesting insights on their new page performance as a result of making the switch to SVG: This chart, and one other animation on Sprout, were initially GIFs. By using animated SVGs instead of GIFs we were able to reduce our page size from 1.6 mb to 389 kb, and reduce our page load time from 8.75 s to 412 ms. That’s a huge difference. —Mike Fortress, “Animated SVGs: Custom Easing and Timing” A huge difference indeed. The Sprout chart is a perfect candidate for SVG. There is no reason to animate it by converting the animation into a GIF recording, when SVG can bring so much more benefits. Jake Archibald realizes the power of SVG animations too, and uses them to create and animate interactive illustrations to complement his articles. His Offline Cookbook article is an excellent example (and an excellent article, by the way). Could he have used GIFs to do that? Of course. But given the number of images he used, the GIFs could have easily increased the overall page size to a couple or few megabytes, with each GIF being at least hundreds of kilobytes in size; whereas the entire web page currently weighs at 128KB only with all the SVG images embedded inline, because you can reuse elements in SVG, so any repetitive elements will not only cause the entire page to gzip much, much better, but for each page, the overall size of the SVGs becomes smaller. Now that is impressive. I will rest my case about page load and performance here. But it is still important to note that there can be exceptions. Again, in most cases, you’re likely going to find that SVG is better than a GIF, but you’ll always need to test anyway. Conclusion: GIF Animated SVG GIF images are generally bigger in size than SVG images are with animations added to them. This negatively affects the overall page size, load times and performance. SVG images can be used and reused, as well as gzipped better, making their file sizes generally smaller than those of GIFs, thus improving page load times and performance. Browser Support Probably the only absolute advantage to GIFs over SVGs is browser support. GIFs work pretty much everywhere, while SVG support is less global. Even though we have many ways to provide fallback for non-supporting browsers—and current browser support should not be hindering anyone from using SVG, the fallback images, if provided as PNG or JPG, are going to be static, animation-less. Of course, you can always provide a GIF as a fallback to SVG, but the previously-mentioned considerations and disadvantages should be kept in mind. Conclusion: GIF Animated SVG GIF images work pretty much everywhere. SVG images have less global browser support, but they come with a lot of ways to provide fallback for non-supporting browsers. Accessibility Concerns (#a11y) Move something on a page, or anywhere, for that matter, and you’ve instantly added a distraction—something that is sure to grab a user’s attention as soon as it starts moving. This is simply how the human brain works. This is also one of the reasons ad banners are so focused on—and built with—a strong focus on animation. This is also why animated ad banners are extremely annoying. They are distracting, especially when you’re trying to perform a task on a page that requires your entire attention, such as reading an article. Now imagine a page with a set of animated icons (or images) that just won’t stop animating no matter what you do. We’re no longer talking about one or two images on a homepage or within an article here; we’re talking about UI elements and controls, and smaller icons that are likely to be present in multiple places on a page, and on multiple pages. Unless your icon is supposed to be inifnitely animation—for example, if it is a spinner animating during a user-inactive waiting phase, then it is likely to introduce a problem, and become more of an annoyance, than a “nice thing”. As a matter of fact, for some people it can become more of an annoyance, as continuous motion can literally make some people feel ill. In her article “Designing Safer Web Animation For Motion Sensitivity”, designer and web animation consultant Val Head discusses the effects of overused animation on the web on people with visually-triggered vestibular disorders (emphasis mine): It’s no secret that a lot of people consider scrolljacking and parallax effects annoying and overused. But what if motion does more than just annoy you? What if it also makes you ill? That’s a reality that people with visually-triggered vestibular disorders have to deal with. As animated interfaces increasingly become the norm, more people have begun to notice that large-scale motion on screen can cause them dizziness, nausea, headaches, or worse. For some, the symptoms can last long after the animation is over. Yikes. Now imagine if the animation does not end… Double Yikes. Val’s article explains the problem in more detail, as she gathers feedback from two people who actually have these problems and share their experience with animation in different examples. One of the solutions that can help avoid these problems is to provide the user with the ability to control the animation so that they can stop it when it gets disturbing. With SVG, you can do that. You can fully control the animation and play it once or twice on page load—if you really need to have it play as soon as the user “enters” your page, and then fire it on hover for subsequent tweens, using nothing but a few lines of CSS or JavaScript. You do not need hundreds or thousands of lines of CSS or JavaScript to create an icon animation, unless your icon is a really complex scene with a lot of components that are animated inside of it. But I think that in that case, it does not count as an “icon” anymore, but more of a regular image. You can go even as far as control playback, speed for each consequent tween, and much more, assuming, of course, you are using JavaScript to gain this level of control. Or you can add a toggle to give the user the ability to stop an infinitely playing animation. You can’t do that with GIFs… unless you opt for replacing the GIF with a static image upon a certain toggle action. Some might even argue that you could display a static version of the image—as a PNG for example, and then provide the GIF version on hover. But this comes with a few problems of its own: If the images are inline, you’ll need to replace these images using JavaScript. That action does not require any JavaScript if you are using SVG. If the images are foreground images (embedded in the HTML using <img>), and you need to replace these images, you will end up with double the amount of HTTP requests for every image. And if they are background images inlined in the style sheet (which is not recommended), the images (especially the GIFs) will add to the size of the style sheet and therefore to the overall render-blocking time of the page. If/when you switch image sources on hover, there is a noticable flash between the first and the second image on slower connections. My connection is slow; sometimes 3G-slow, and I have yet to remember a time when an image was replaced with another one on hover, viewport resize, or whatever, and not have seen that flash. This situation gets even worse when the second image (GIF loaded on hover) is fairly big in size—there will be a flash, followed by a slow, janky animation of the GIF while it loads completely. That’s never attractive. So, yes, you can switch image sources to control if or when the GIF animation plays, but you’re losing the finer control over the GIF and affecting the user’s experience with the UI. You are also able to control how many times the animation plays in the GIF—which is pretty cool, but that means that the animation will play only n number of times. And then to re-fire the animation upon a user interaction, you will need to resort to the above technique with multiple images. Multiple images to maintain, multiple HTTP requests, and an overall hacky, non-optimal solution to what could have been easily achieved with one SVG image. Embed the one SVG image on the page. Create the animation any way you want/need. (Or create the animation before you embed the image.) Play, pause, control the animation; and give the user the ability to control it as well. No extra HTTP requests for every image, no complicated animation timeline maintenance in graphics editors, and no accessibility concerns or woes that cannot be avoided with a few lines of code. Conclusion: GIF Animated SVG GIF images cannot be stopped by the user without requiring extra images and extra HTTP requests. Even then, the control is not full. SVG animations can be fully customized so that they are enabled, disabled and controlled by the user without requiring any hacky approaches. Content Accessibility GIF Animated SVG GIF images are only as accessible as PNG and JPEG images are—using an appropriate alt attribue value to describe them. The content inside the image cannot be discerned or made directly accessible to screen readers beyond what the overall image description does. SVG images are accessible as well as semantic. The content inside the image that is being animated can also be described and made accessible to screen readers using SVG’s built-in accessibility elements, and enhanced using ARIA roles and attributes as well. (You can read all about making SVGs accessible here.) Interactivity There’s not much to add here but the fact that you can interact with individual elements inside an SVG, during, before or after an animation, but that is not possible with a GIF. So, if you use a GIF, you will lose the ability to do anything beyond triggering or stopping the animation, and even those are not really done inside the SVG, as we’ve seen, but are achieved by swapping the GIF out with a static replacement. Even changing the colors of elements inside the GIF would require additional images to do so. That is yet another advantage to using SVG over GIFs. Conclusion: GIF Animated SVG Animations defined in GIF images cannot be interactive. You cannot interact with individual elements inside a GIF element, nor create links out of individual elements either. SVG content is fully interactive. You can create hover and click interactions (and more) to which individual elements inside the SVG image can respond. Responsive & Adaptive Animations The ability to animate SVG directly from the code, as well as manipulate its many, many attributes, results in and adds yet another advantage over GIF-based animations: the ability to create responsive, adaptive and performant animations, without adding any extra HTTP requests, using a few lines of code, and with quite smaller file sizes. Sarah Drasner wrote an article on Smashing Magazine showing different ways to animate SVG sprites. One of these ways is having multiple “scenes” inside an SVG, animating them with CSS, and then changing the SVG “view”—by changing the value of the viewBox attribute—to show one scene at a time, depending on the current viewport size and available screen estate. If you wanted to create the same animation using GIF images, you would lose the animation control capabilities as well as require multiple images which are probably going to be bigger (in file size) than the one SVG image. But if you don’t want to go with animating SVG code, you could always create an SVG sprite and animate it the way you would animate any other image format—using steps() and a few lines of CSS. Sarah also talks about this technique in her article. Animating SVG images does not need to be complicated, and is generally performant. Conclusion: GIF Animated SVG Given that content inside a GIF cannot be controlled with code, it is not possible to make the animations adapt or respond to viewport or context changes without resorting to seperate images. Given that SVG content is directly animatable using code, the content as well as its animations can be modified so that they respond and/or adapt to different viewport sizes and contexts, without having to resort to any additional assets. Final Words GIFs have pretty good browser support, yes, but the advantages of SVGs outweigh theirs in almost every aspect. There might be exceptions, and in those cases do, by all means, use GIFs or any other image format that does a better job than SVG would. You might even use Video or HTML5 Canvas or whatever. SVG can bring a lot of performance benefits to the table when compared to other image formats, especially GIFs. Thus, given all of the above, I recommend that anywhere SVG could be used for animation, GIFs should be avoided. You’re free to ignore my recommendation, of course, but you’d be giving up on the many benefits that SVG animations offer. Unless GIFs show a lot of advantages over SVGs that go beyond browser support for IE8 and below, then I believe SVGs should be the way to go. A few resources to help you get started with SVG animations: The State of SVG Animation A Few Different Ways to Use SVG Sprites in Animation Creating Cel Animations with SVG GreenSock has a bunch of very useful articles on animating SVGs Snap.svg, also known as “The jQuery of SVG” SVG Animations Using CSS and Snap.SVG Styling and Animating SVGs with CSS Animated Line Drawing in SVG Thank you for reading. Many thanks to Jake Archibald for reviewing and giving feedback to the article, and to Chris Lilley for his feedback re transparency in GIF images. It wouldn’t have been so comprehensive (read: ridiculously long) without their feedback. ^^

Tips for Creating and Exporting Better SVGs for the Web

Working with SVG in a RWD workflow usually involves a design phase and a development phase. The design phase is usually handled by designers who may or may not know how to code. And because of the nature of SVG as both an image format and a document format, every step taken in the graphics editor in the process of creating the SVG directly affects the resulting code and hence the work of the developer in charge of embedding, scripting or animating the SVG. In my day-to-day work, I am usually the developer whom designers hand the design assets over to, and SVG images are part of those assets. Most of the assets I’ve been handed in my past projects needed a do-over and/or a second round of editing in the graphics editor before I could script them, because the resulting SVG code was not optimized enough for the kind of work—especially animation—that I was hired to do. The reason for that is that many of the designers I’ve worked with knew very little—if anything—about SVG code. They create vector graphics and UI assets all the time, but, for them, SVG is no more than an image format and they don’t know much about the code generated when their assets are exported as SVG documents. There are some steps that designers can take or avoid—a set of “dos and don’ts”—that can help make the generated code cleaner. In this article, I want to share some of these. If you know any more, please do share them in the comments at the end of the article. The tips we’re going to go over are applicable in Adobe Illustrator (Ai)—my graphics editor of choice—as well as other graphics editors. But since I personally use Ai, it is what I will be focusing on throughout this article. We’re also going to go over the current SVG export options available in Ai and which ones to choose and why. But note that these options will change in the future, and this article will then be updated to reflect those changes. So, let’s start. this article. 1. Create Simple Shapes Using Simple Shape Elements, Not <path>s. There is a reason we have different basic shapes in SVG for creating, well, basic shapes. One could create practically any shape using a <path> element, right? Simple shape elements (<line>, <circle>, <rect>, <ellipse>, <polygon> and <polyline>) are there for many reasons, and one of these reasons is that they are more readable and more maintainable and editable by hand than their <path> alternatives. Basic shapes come with a set of attributes that allow you to control the shape features, such as position (x, y, cx, cy) and dimensions (width & height), while paths don’t come with these attributes. For example, the following snippet shows the difference between a circle created and exported as a simple shape, versus one created and exported as a path: If you want to animate your shape by, say, moving the position of the circle or making it bigger, you can do that by animating the position of the center via the x and y coordinates (cx & cy) and the radius of the circle (r). Whereas if you are working with a circle generated as a path, you will have to resort to CSS/SVG transformations (translation and scaling) to do that. And then suppose you want to animate that path and the animation requires you to apply further transformations to it? It can easily become a transformation mess. Another advantage to using simple shapes is that, in the majority of cases, the code required to create a shape using simple shape elements is less than that required to create the same shape using a <path> element (see above snippet for a comparison), so using simple shapes will also result in a smaller file size, which is always better. 2. Convert Text to Outlines.. Or Don’t. To convert text to outlines: Select the text you want to convert. Choose Type → Create Outlines Pros: Text converted to outlines will preserve the font face used, without having to use a web font to display it. This means you save a few extra HTTP requests and don’t risk displaying your text with a fallback font that generally doesn't look good enough to substitute the beautiful font of your choice. Cons: Text converted to outlines is not real text: it is a set of paths that form the outline (shape) of the text. Consequently, the text becomes unreal and inaccessible, not searchable and not selectable. alt text (if the logo is embedded as an image) or SVG’s accessibility elements (<title> & &>) is a good idea for providing alternative text for screen readers. I highly recommend reading all about making SVGs accessible in these two articles by Léonie Watson: Tips for Creating Accessible SVG Using ARIA to Enhance SVG Accessibility Converting text to outlines can significantly increase your SVG file size, depending on the complexity of the font face used. The image below shows the difference in the size (and readability) of an SVG with text converted to outlines (left) and text exported as SVG <text> (right). Paths are not easily controlled and animated as <text> elements (including <tspan>s) are. The latter have a set of attributes that give you more control over your animations, while path data is limited in that sense. 3. Simplify Paths. A path is defined by a set of points which in turn are defined by a couple of coordinates each. The less the number of points, the less the path data (d attribute), and, consequently, the less the overall SVG file size. This is always a good step to take because a smaller file size is better for performance. To simplify a path: Select the path Go to Object → Path → Simplify Tweak the number of points. Make sure you have the Preview checked so can see how the path changes as you change the number of points. Tweak the number to get to the minimum number of points while preserving (or sacrificing) as much of the path’s visual appearance as you need. There is a video tutorial created by Adobe to explain the process; so if you are more into videos, you can check it out here. You can also simplify paths using the Warp Tool. I’m not a designer and I usually use Ai’s Simplify algorithm to simplify my paths, so, if you’re a seasoned designer, you probably already know much more about the Warp tool than I do. There is an article over at Smashing Magazine all about this tool, in case you want to check it out. 4. Avoid Merging Paths Unless You Don’t Need Control Over Individual Paths. Many designers tend to combine or merge paths whenever possible. To merge paths: Select the paths you want to merge. Go to Window → Pathfinder Click the Merge option among the list of options at the bottom of the panel (third icon from the left, shown in the screenshot below). Combining paths may have its benefits, but avoid it when you or the developer needs to control and/or animate paths separately. Some animations are designed so that multiple elements are animated seperately, or sometimes you just want to style the paths using different fill colors. If you combine the paths, that will no longer be possible. You need to make sure you know what the developer (or yourself, if you’ll be handling the development phase as well) needs and wants to do with the shapes you’re working on, and make the decision to merge or not to merge accordingly. This will save both of you a lot of time and friction. 5. Create Filters Using SVG Filters, Not Photoshop Effects. If you use the filters in the Photoshop Effects section under the Effect option, Illustrator is going to export the effects you create as raster images. For example, if you create a drop shadow using the Blur Photoshop effect, the drop shadow generated will be a raster image embedded inside the SVG either inline or externally, using <image>. You definitely don’t want that when you work with SVG. To generate your effects as SVG code, you need to use the SVG Filters available: Go to Effect → SVG Filters Choose and use one of the filters available in that panel. 6. Fit Artboard to Drawing. Have you ever embedded an SVG on a page, gave it a specific height and width and then found that it was being displayed at a size smaller than what you specified? In most cases, this is caused by an amount of white space inside the SVG viewport. The viewport is displayed at the size you are specifying in your style sheet, but the extra space inside of it—around the graphic—causes your image to “shrink”, because that white space is taking an amount of, well, space, inside the viewport. To avoid this, you need to make sure your artboard is just big enough to fit the drawing inside of it, but not any bigger. The artboard dimensions are the dimensions of the exported SVG viewport, and any white space in the artboard will be generated as white space inside the viewport. To fit your artboard to your drawing: Select the entire graphic. (I use cmd/ctrl + A.) Go to Object → Artboards and choose the Fit to Artwork Bounds option. 7. Use Good Naming, Grouping and Layering Conventions. I know this sounds like a no-brainer, but it needs to be emphasized for a few reasons: The IDs and class names you use in the graphics editor are going to be translated to IDs and class names in the generated code. The more these names make sense and the clearer they label their respective elements, the less friction there will be when the developer works with the code. Now, I'm not saying you have to think up the perfect names—I'm sure we all have different ways of naming things and naming can be one of the hardest tasks, but labelling groups appropriately goes a long way. For example, if you are drawing a car, then using an ID of wheel to name the layer or group wrapping the shapes making up the wheel would be appropriate. If you are grouping all wheels in one group, you might give it an ID wheels. Simple names to tell elements and groups apart go a long way and save a lot of time, especially if the developer will be editing and manipulating the code by hand. Illustrator does not do the best job at naming things, so specifying names helps reduce the amount of junk it produces. Granted, there will be some extra editing required to get rid of the annoying underscores that Ai insists on generating, but using proper names helps make this process a bit easier. As mentioned before, the next verison of Illustrator will show a big improvement in the way SVGs are generated, including generated IDs. <li><strong>Use layers to group related elements.</strong> Layers are translated into groups in code, so name these well too. Create layers/groups to wrap related elements together, especially those that might be animated as a whole. A lot of time could be spent reordering and grouping elements by hand by the developer if this is not already done in the design phase. To save time, make sure you group appropriately. Talking to the developer in the design phase and designing how the animation will be executed together is a big time saver.</li> <li>If the images you're creating are going to be used to create an SVG sprite, <strong>the names you use can and will be used by most automation tools to generate new files.</strong> So using clear and proper names will result in cleaner file names. </li> 8. Choose The Best Suitable Export Options for the Web. Export > SVG) is available to export web-optimized SVG files for your web and screen design workflows. You can also choose to export individual objects versus the entire artboard. Refer to this article for details. At the time of writing of this article, Illustrator comes with a bunch of export options that allow you to generate a generally better SVG code. To export your SVG: Choose File → Save As Choose SVG from the dropdown menu Click Save. Once you click save, a dialog will show up that contains a set of options that you can customize, and that will affect the generated SVG code: The options shown in the image above are the ones recommended for generating SVG for the web. Of course, you can choose to Outline text if you don’t want to use a web font; Illustrator provides you with an option to do it upon export, as you can see, as well. The Image Location option specifies whether any raster images will be embedded inline in your SVG or will be external with a link inside the SVG. This, again, depends on what you need. Inlining images inside the SVG can increase its file size dramatically. Last time a designer sent me an SVG with an image inlined in it, the file size was more than 1MB! After removing that image (which was caused by the Photoshop Effects used, that we mentioned earlier), the file size dropped to less than 100KB! So, choose wisely. The CSS Properties option gives you the option to choose how you want the styles inside the SVG to be created: using presentation attributes, inline styles, or in a <style> tag. This is also a matter of preference and depends on how you intend to manipulate the SVG once you’ve embedded it. If you’re not the one who’s going to do that, make sure you consult with the developer to choose the option that suits their needs best. The less the number of Decimal Places, the less the file size of the SVG. One decimal place should generally be enough, so I’d go with that. Note that if you choose 3 or 4 decimal places, for example, and then use an optimization tool to optimize the SVG and bring that number down back to 1, the SVG might end up visually broken; so it is best to choose this option early on. There is more to the options panel than what I have covered. Adobe’s Michaël Chaize has written an excellent article about the export panel that explains what each option does exactly. I highly recommend checking his article out: Export SVG for the web with Illustrator CC Now, at the time of writing of this article, Illustrator will still generate unnecessary code such as editor metadata, empty groups, among others, so you will need to optimize the SVG further after you’ve exported it, be it by hand, or using a standalone SVG optimization tool. But before we jump into the Optimization section, I want to note that you may or may not want to check an extra option as you save the SVG: the “Use Artboards” option, in the Save panel: This option is useful for when you are working with multiple SVG images (for example: icons) and you are using an artboard for every icon. Exporting multiple artboards will generate multiple .svg files, one for each artboard (one for each icon). If you are working with only one artboard, this option will be disabled by default. Choosing to export one or multiple SVG files depends on how the SVG is going to be embedded. For example, if you are going to create an SVG sprite for an SVG icon system, there are several ways you can create and use the sprite, and each one would require a different approach: one technique requires the icons to be separate at first, and another requires them to be part of one image. I will be writing a separate post about spriting SVGs and the artboard options, but until then, you can get an overview of the different spriting techniques in the following article I wrote for 24Ways.org: An Overview of SVG Sprite Creation Techniques To Optimize or Not to Optimize... It is usually recommended to optimize the SVG after exporting it from a graphics editor using a standalone optimization tool. The current most popular optimization tool is the NodeJS-based tool called SVGO. But it may not always be a good idea to optimize your SVG, especially if you intend to animate it. If you intend to script and/or animate the SVG, you’re likely to set up a certain document structure—wrapper groups, ID names that you are not using/referencing inside the SVG but intend to use in your JavaScript, etc. This structure is going to change if you optimize your SVG using SVGO (or any other optimization tool). Optimization tools usually remove any unused groupd and IDs, as well as apply many changes to the SVG to make sure it is optimized well. I’ve once optimized an SVG after applying an animation to it using <animate>. The SVG was broken and so was the animation inside of it, because the entire structure was changed. So that is something to keep in mind before optimizing SVGs. If you’ve manually edited and/or generated an SVG with a certain structure that you need, avoid optimizing using an optimization tool, and optimize by hand as much as possible. Some editor junk at the beginning and end of the SVG can be easily removed by hand. Other junk, such as metadata and classes generated by editors like Sketch—which has no SVG optmization options, can be harder to optimize by hand. I generally never use Sketch to generate complex SVGs. I use Illustrator or Inkscape; the latter comes with a default export panel which gives you a lot of options to optimize your SVG before exporting it (see image below). Inkscape generates the cleanest SVG code at the time of writing of this article—that is, if you choose the Optimized SVG option, but the blurriness of the UI on a retina screen as well as its dependency on X11 on OS X make it a pain to use, so I am currently sticking with Illustrator. If you do need/want to optimize your SVG, SVGO is the tool I would recommend. SVGO comes with a bunch of plugins that you can fit into practically any kind of workflow. You can find more information about those tools in the following article I wrote a few months ago: Useful SVGO[ptimization] Tools 9. Communicate. Communicate early. Possibly the most important tip I can give is to communicate, and to do it early in the design process. I’m now assuming that you—the designer creating the SVG—are not the same person responsible for developing the SVG (scripting, animating, embedding, etc.). Almost every one of the above tips requires knowledge of the development phase and what the developer intends to do with the SVG—how they intend to embed, script, style and animate it. So, unless you’re the same person making decisions for both phases, and unless you want to waste a lot of time reiterating and editing the SVGs, you need to make sure you know what the developer needs to do with the SVG and what approach(es) they will be taking. If you’re working on a project that has a tight deadline, you probably can’t afford to waste a big amount of time making changes and revisions to image assets, when you can avoid that by communicating early. Designers and developers can be each other’s best friends. The very nature of SVG requires both design and development phases to be open to one another, and this, in turn, requires the designer(s) and developer(s) to talk, before the design process begins, and throughout the process as well. Thank you for reading.

Developer of the Year 2015 net Award

Last Friday, I gave my first keynote in the UK at Generate Conf. That same day, the net awards were announced. On Saturday, I came back home with an award: the Developer of the Year award. This is a short thank you post to everyone involved. Photo by net magazine. All rights reserved. (Original Photo) A few months ago, many fellow designers and developers nominated me for two net awards: Outstanding Contribution and Developer of the Year. Last Friday, the winners of the different categories were announced, and I’m thrilled to have won the Developer of the Year award. I can’t even begin to explain how happy and humbled that makes me. To be recognized and appreciated by your fellow colleagues is a great privilege, and a badge I wear with pride. I haven’t gotten a chance to say thanks to each and every one who congratulated me over Twitter after the award announcements—the feedback was so overwhelming (and fast!) that I just couldn’t keep up, so I thought I’d wait till I’m back home to write a thank you post instead. So: thank you! Thank you to every one who nominated me and deemed me worthy of this title, and thank you to every one who voted and supported me. Two and a half years ago, when I started working in this field, I didn’t expect to be here today. I had different plans, most of which were unclear, and I never thought when I wrote my first blog post (on a really ugly blog design :P) that I’d end up shifting my overall path and doing all the writing and speaking that I am doing today. I am thankful to God and grateful for each and every step and opportunity I got along the way, and for all your wonderful support. And now, since I’m really bad at coming up with proper ‘speeches’, I’ll keep it short and end with a huge Thank You one more time. You are awesome! ^_^ –S

CSS vs. SVG: The Final Round(up)

This is the last article in the series of article comparing common CSS techniques to their SVG counterparts. This article is a roundup of several CSS and SVG solutions, as opposed to being an article comparing one solution that can be achieved using either CSS and SVG. There are already a bunch of excellent articles out there that cover the details for each of these solutions, so we will get an overview of each solution and link to those articles for each section as we go. I highly recommend you check them all out.

CSS vs. SVG: Shapes and Arbitrarily-Shaped UI Components

This post is the third in the series of posts exploring techniques and examples that can be achieved using both CSS and SVG, and compares them both.In this article, we are going to go over techniques for creating arbitrarily-shaped UI components using CSS properties and SVG’s capabilities, and a mix of both! Specifically, we will be talking about how to create circular menus, as these are the perfect example of usable non-rectangular UI elements.

CSS vs SVG: Styling Checkboxes and Radio Buttons

This post is the second in the series of posts exploring techniques and examples that can be achieved using both CSS and SVG, and compares them both. In this article, we’re going to look into ways to style checkboxes and radio buttons using both CSS and SVG. You will learn how you can create animated checkboxes using SVG's line drawing capabilities.

Building A Circular Navigation with CSS Clip Paths

The CSS clip-path property is one of the most underused and yet most interesting properties in CSS. It can be used in conjunction with CSS Shapes to create interesting layouts, and can be taken to the extreme to create some incredibly impressive layouts and animations like the Species in Pieces project. While exploring the creation of arbitrarily-shaped UI components using CSS and SVG, it occurred to me that the clip-path property, when combined with SVG paths, can be used to create circular menus fairly easily, especially considering the (expected) browser behaviour when handling pointer events on clipped regions as per the specification. In this article, we'll explore this idea further and learn how it's done.

CSS vs. SVG: Graphical Text Effects

This post is the first in a series of posts exploring techniques and examples that can be achieved using both CSS and SVG, and compares them both. Since I am biased to SVG, this series is really intended to prove that SVG — because of its nature as both an image and a document format — is simply better than CSS when it comes to solving certain design problems on the web. But to keep an objective point of view, we will be weighing the pros and cons of each technique and find out where and when CSS or SVG can serve as a better tool to the design goals at hand. In this article, we’re going to look into the CSS background-clip and mask-image properties, as well as SVG pattern fills and masks.

Chapter 4, Smashing Book 5

The new Smashing Book is out! It’s packed with a lot of time-saving, practical techniques for crafting fast, maintainable and scalable responsive websites. I wrote a chapter in the book—Chapter 4: Mastering SVG For Responsive Web Design. Here is an overview of what that chapter covers, and why I think you should buy the book. Photo credit: Mattia Compagnucci I always get questions from my followers about a good place to start learning SVG. I write about SVG a lot, but I realize that it’s always better to have one place where you can jump start whatever you’re learning and then take it from there. I believe the SVG chapter in the book is a great place to do just that. Chapter four of the Smashing Book 5 is 80 pages of SVG, covering everything you need to know to start implementing SVG in your responsive web designs today. —Paul Scrivens, “Smashing Book #5, A Review” So, What Can You Expect To Learn About? Photo credit (and thanks to): Mattia Compagnucci The answer to this question in my head is always a list of what is not covered in the chapter, because the topics covered include so much! Here is an overview of the contents: What is SVG?: a brief overview of the image format and its history. Vector vs. Raster: a comparison between vector and raster image formats such as JPEG, PNG, etc., characteristics of each, and what makes the SVG format stand out. Advantages of SVG: the many, many features that makes SVG a better image format for responsive web design, including but not exclusive to: scalability and resolution-independence, performance, accessibility, animation, and more. Vector vs Raster: Which is the Better Format?: a set of guideliness and things to consider when choosing the image format for your graphic, including why and when SVG might or might not be a good choice. Quick Overview of SVG Syntax and Code including.. Understanding the SVG Viewport and viewBox Creating and Exporting SVGs in Vector Authoring Tools: tips, dos and don’ts for the right workflow when designing SVG images that ensure the resulting code is as optimal as possible. This section includes: Exporting SVG for the Web From Adobe Illustrator: overview of the export options and which ones to pick to make sure you end up with better code. Optimizing SVGs Using Standalone Optimization Tools: there are a lot of tools, each can fit into a different workflow. We go over a list of some of the best tools. Embedding SVGs: the different ways to embed SVGs on a page, and the pros and cons of each, tips on improving performance when choosing some of them. Using SVGs as an Icon Font Replacement (or, How to Create SVG Sprites and Use Them as an Icon System): what the tite says. Sections covered in this master section include: SVGs vs Icon Fonts: SVGs are a far more superior icon system, and this section covers all the reasons why, as in intriduction to.. Spriting SVGs: introduction to the concept, followed up: SVG icon system with icons as background images: the how-to of creating an SVG sprite for icons used as background images on the page, including tools to simplify the process. Covered is also a section about SVG data URIs, including any performance considerations. SVG Icon System with Icons as Foreground Images: how-to and workflow automation tools. Styling the icons and applying transitions to them: including styling the contents of <use>. Providing and Automating Fallback for HTML-Inline SVGs: some known and some lesser known techniques for: SVG fallback as foreground images: how to provide fallback for SVG images that are embedded as foreground images. There are several options, all covered. SVG fallback as background images: also a few options to choose from leveraging different CSS technqiues. SVG Fallback Using SVG Conditional Processing (SVG Fallback as Background Image): SVG’s built-in fallback mechanism. Other Fallback Techniques for different embedding techniques. Better SVG Spriting Using Native Fragment Identifiers: this is my personally-favourite SVG spriting tchnique and one of the lesser used ones, and the one closest to the way PNG image spriting works. Making SVG’s Cross-Browser Responsive with CSS including: Making SVGs Fluid with CSS: everything including browser bugs and workarounds. Making SVGs Adaptive with CSS using CSS Media Queries to show and hide (or even animate) parts of the SVG depending on viewport size. Making SVGs Accessible: the least you can do to provide even the most basic accessibility to your SVG images today. Using SVGS to Optimize the Delivery of Other Image Formats: use cases that go beyond simply displaying or animating vector images. It includes: Using SVG Masks to Optimize Raster Graphics Using SVG As a Container for Serving Responsive Images a.k.a the Clown Car Technique. Where To Go From Here: pointers to more ideas and resources to look into. As you can see the chapter covers a lot. The topics it does not cover (otherwise it would have turned into a book) are: graphical effects (such as filters) and animation. I’m pretty sure there is even more about SVG to get into that the chapter does not cover, but hey, it’s only a chapter of a book! —Bruce Lawson The Reviewers The chapter was reviewed by Dmitry Baranovskiy (creator of the Raphael library and its modern Snap.svg alternative) and Jake Archibald (Google), both experienced SVG developers. A Designer’s Complete Reference The chapters of the book are complimentary to each other, so the entire book is a collection of topics that go extremely well together, giving you a set of diverse topics that are sure to come in handy for any responsive design project you work on. While writing the SVG chapter, I mentioned the problems that non-vector images might bring up, and how the new <picture> element emerged as the almost-perfect solution for that problem. (SVG still has its benefits over these formats, of course, but raster images still have their place and importance where SVGs just can’t fill in.) And since my chapter was focused on SVG, I couldn’t get into the details of how to serve responsive raster images. Yoav Weiss’ chapter fills in that spot and covers everything you need to know about using responsive images. Not only that, but Yoav’s chapter also includes tips that you can apply to SVG images as well, making these two chapters the ultimate reference for images used in responsive design. You can’t expect an SVG chapter to not mention SVG fonts, too. But then again, since that topic is outside the scope of what could be covered in the chapter, Bram Stein’s chapter on web font performance fills in that spot in his chapter that covers everything you need to know about web font formats, performance, fallback, and more. The book was written by some of the brightest people in our industry, all experts in their fields, smarter than me, and known for their expertise in specific topics—all of which they covered in lengthy, very informative articles. You will find topics ranging from design workflows, patterns, to content choreography, images, advanced layout with Flexbox, responsive process, performance optimization, all the way to optimizing for offline experiences. I hope you find the chapter on SVG useful, and I’m confident you will find the remaining chapters insightful as well. I promise you will not regret it. So, what are you waiting for? Go grab your copy and feel free to tweet at us with any feedback or comments (or even pretty pictures)! Buy the Book

Styling the Contents of SVG with CSS

An in-depth article on how to style the contents of the SVG <use> element and overcome some challenges it brings. We get into where the contents are cloned (the shadow DOM!), what limitations that brings up and how to work around them by taking advantage of the CSS cascade and using CSS Variables to get full control over the content while providing fallback for non-supporting browsers.

Art-Directing an SVG Embedded Using
I have recently finished a front-end development project for Provata Health — a US-based health and wellness company specializing in health promotion and behavior change science. As part of their marketing website, I worked on an infographic that showcases the three major health results one can achieve by following their health program. The graphic is a perfect candidate for SVG and you’ll see why throughout this article. But even though almost all of the graphics on the site were vector (which made the entire project exciting to me), I want to focus on this particular graphic and how and why I made the development choices I made while embedding it. I had to make a few “unusual” decisions to make sure I provide the best performance and accessibility possible, including inlining a piece of JavaScript in the middle of the page. So I wanted to share why I made those decisions, and at the same time shed the light on yet another case where SVG could be improved to adapt to our development needs. Also, after tweeting about inlining the JavaScript in the middle of the document, I asked my go-to performance specialist—the nice Mr. Paul Lewis—about any performance implications, he too thought I should write about this and share why I made that decision. So here I am. First, let’s have a look at that graphic and see why it is a perfect SVG candidate, before we get into embedding, art-directing and fallback. The Results SVG Graphic here. This is the SVG graphic I worked on in the website’s Results page, and how it was supposed to look on mobile and desktop, respectively. The Provata Results Graphic as displayed on mobile (left) and desktop (right). You can check the graphic out live here. The text inside of the graphic is just as important as the rest of the HTML text on the page, with the addition of the positioning that illustrates what category each result belongs to in a nice visual manner. When you have text like this, SVG should be the first thing to think about. This kind of graphic (similar to an infographic) is a perfect candidate for SVG and one that makes SVG’s accessibility and visual features shine. Imagine having to absolute-position each and every piece of text and image inside that graphic in an HTML document, taking into account and document flow (or lack thereof); doing this using SVG not only makes more sense but also comes with the advantage of being able to use a graphics editor to achieve all of the positioning visually, instead of hand-coding the positions using pixels or ems (or whatever unit you prefer). Not only that, but you also get the fluidity and responsiveness of SVG images and text by default, so you won’t have to worry about adapting any text and image sizes to different viewport sizes. Not to mention text accessibility inside of the image. Win win win! Choosing The Embedding Technique Since the contents of the SVG are not animated (they were at first, but the UX team decided to drop the animations later for better UX), then the first logical embedding technique that comes to my mind is <img>, or its cool cousin <picture>; either way, it would be embedded as-an-image—as a foreground image, to be specific, because 1) there is no reason to embed it as a background image and 2) because foreground images have better performance metrics than background images. However, there is one important reason why embedding it as-an-image is not an option: not only does the text inside of the image need to be as “real” (read: readable, selectable and searchable) as any other piece of text on the page, but we also need to be able to provide this same text as a raw text fallback in case the SVG fails to load for any reason. So, to recap: The text inside of the image needs to be accessible to screen readers. The text inside of the image needs to be selectable and searchable by the reader. The text inside of the image should be the fallback provided for non-supporting browsers. That is, if the image fails to load for any reason, the text content of the image should be the content to replace it, not a PNG or JPEG version of the graphic. This decision was one of high importance to me because the entire section of that page depended on that text to convey a message, so should the user not be able to read the SVG text, I wanted them to be able to simply read the text content. Given all of the above, <object> was the perfect candidate and the element I eventually used to embed the graphic. To make sure the text inside the SVG is accessible, searchable and selectable, make sure you don’t turn it into outlines. Keep it as default SVG <text>. With this, you also get the ability to apply the page’s font face to the SVG text as well, using @font-face. So you get the text rendered and working just like you expect it to. Between the opening and closing object tags, instead of providing a PNG version of the image for non-supporting browsers—which is what most developers would normally opt for, I provided a raw text alternative to the graphic, and the content of that text was the exact same as the content inside of the SVG graphic. This works pretty well. While testing the graphic on mobile, and before finalizing the JavaScript (see next section), the graphic failed to load in one of the tests because the URL of the image I had specified was incorrect, so I got the text content in that section of the page instead, and it looked and worked perfect for the purpose of that section, as opposed to having loaded a PNG version that could have been unreadable. Having chosen the embedding element, decided for an accessible fallback, and knowing that we need to provide two seperate images for desktop and mobile, it’s time to handle the image swapping.. Art Direction I’m a huge proponent of the viewBox clipping technique. The attribute is extremely powerful and art-directing an image using this attribute is always the first thing that comes to my mind. If you’re not familiar with how this works, you should read my previous blog post explaining exactly how that’s done. However, this is one use case where the viewBox clipping technique would not suffice because clipping would not be enough to hide the parts we do not need on smaller screens, because the viewBox can only clip to rectangular areas, so we would either have to use a custom clip path to clip out the excess content, or we could hide them by making them invisible (using opacity, visibility, display, etc.), and the latter can be easily achieved using CSS media queries. So the way it would work would be: Hide the branched parts (text and small illustrations) on small screens using opacity: 0; or display: none, for example Then clip the canvas to the remaining graphic (the three overlapping colored circles) to get rid of unwanted excess white space resulting from hiding the rest of the graphic. Changing the viewBox using CSS is currently not possible, so that would require JavaScript. Hiding the unwanted parts on small screens is possible in CSS, though. So this makes it possible to do half of the job using JS and the other half using CSS. I don’t like the sound of this, but this is the only way it’s possible now. Ideally, we would be able to change the viewBox using nothing but CSS, thus croppig and hiding the content using a few lines of CSS, but that’s currently not possible. (See previous article for details.) So, we can use one SVG image and art-direct it using CSS and a few lines of JavaScript. Great. However, something else must be kept in mind here: performance. In my previous article on this subject, I mentioned that art-directing SVG using the viewBox attribute is a powerful technique but one you should not pursue if the graphic you are embedding is too big to serve in full composition on mobile. And in the case of the Provata graphic, the hidden parts were indeed non-trivial in contributing to the overall file size, making it significantly bigger, so using the same full image and hiding parts of it on mobile was definitely not a suitable approach in this case. Which brings us to the next section.. Art-Directing The SVG <object> Instead of serving the same graphic for desktop and mobile, we opted for two different graphics. Both of them were embedded using an <object> tag. Had we embedded the SVG as an image, we would have been able to easily switch the source of the image using the <picture> element and its <source> descendant. I wrote all about this in a previous article as well, so you might want to check it out. The code for that would look something like this: But since we need the text fallback and are using <object>, we need to swap out the source of the object using JavaScript because it’s not possible to do so using markup.. Using JavaScript to Switch <object> Source To detect viewport size, I like using Modernizr. So the function swapping the object source looks something like this: Of course, make you sure sure you trigger this function and re-trigger on window resize, and since the function already checks for whether or not the source is the one required at a specific screen size, it won’t keep swapping the source every time (that would otherwise cause a horrible flash making the image unusable). The rest is self-explanatory. Inline or External JS? Sync or Async? I inlined the script right after the </object> tag in the markup, and did not make it async. “Why? 😳” I needed the browser to parse the JS and specify the object source as soon as possible, I did not want it to parse the entire document before it displayed the graphic, because it’s the most important graphic on the page and I wanted it to show up as soon as possible. So, I did not async the inline script. (We devs can turn any word into a verb and it’s totally legit.) (Yes it is.) At first, I was relying on the JS to set the object source on both mobile and desktop. That caused some issues on mobile—loading- and performance-wise, so I ended up setting the data to point to the mobile version of the graphic by default, and have the script do the swapping to the desktop version when on desktop. That got rid the mobile loading issue, and, expectedly, works pretty well on desktop. Now, this works, perf is pretty good on both desktop on mobile and I even got a “looks good to me” from Paul, so I took that as my “good to go” sign. The takeaway here is: always test your pages, no matter what technique you use to achieve something. It turned out that inining small pieces of JavaScript is sometimes even recommended to improve load times, says Google, and that’s exactly what I achieved by inlining the JS in this case. An <object> Extension? As I worked on this project, I tweeted about how nice it would be if we have a <picture> cousin that did the same thing as <picture> does for <img>, but something more object-oriented. (Pun not intended.) Art-directing an SVG embedded as an <object> is something I’ve done more than once, and all in real-life, practical use cases as part of client projects. So this is something that is useful and would make a lot more sense if we could do it using markup without having to resort to (inline) JavaScript. After second thoughts, I think that maybe, instead of coming up with a new element to do this, extending the object element with a <source> or <data> element that is similar to source might be quite handy. So we could do something like: This is just an idea, and probably not even close to something implementable—it is just meant as an idea that might be shaped into something usable/implementable or maybe a similar idea that achieves the same functonality could spawn from it. This is yet another thing added to my SVG wishlist. Until we get anything like that, JavaScript is the way to go to swap object sources. UPDATE: After reading the article, Taylor Hunt pointed me to this specification, which defines a <param> element to extend the options for some SVG elements. Maybe this element or something very similar in concept could achieve the URL-swapping without resorting to script. Just something to keep in mind. Happy User, Happy Client, Happy Dev In that order. The image used was important in conveying a message and was a vital part of the site’s content, so we made sure it was as accessible and good-looking as it could possibly be, using the awesome that SVG is. At Provata, we focus on creating dynamic, interactive, and engaging digital health experiences. So we wanted our marketing website to reflect that. Sara expertly incorporated SVG techniques to deliver a final product beyond our expectations. She is an incredibly knowledgeable and diligent developer. She captured the spirit of our company brilliantly. —Alex Goldberg, CEO Provata Health Final Words Working on this site has been great, and my client was one of the best I’ve worked with. Not only do I love the branding and design, but I also love the spirit behind the health program. (You can learn more about it here.) And my absolute favourite part was getting to work with lots of SVG animations using my favourite animation library. (Thank you, Jack.) The SVG decision-making process is also one I enjoy a lot, even though the amount of options we have can sometimes be overwhelming, and in spite of the fact that we sometimes may need to make certain compromises when choosing one option over the other, and in spite of the lack of full-fledged tools and techniques we got at hand today. I love SVG and enjoy going through the entire process every time. Hopefully things will get better in the future. The more we use SVG, the more practical, real-life use cases come up with, the more features we need, the more features we should request, and hopefully the more features make it to specs and implementation. I also learned quite a few designer-y things while working on this project, and plan on sharing more of those in future articles and talks, so stay tuned! Thank you for reading.

The State of SVG Animation

The state of SVG animation is changing. CSS, SMIL and JavaScript can be used to animate SVGs. However, SMIL is soon to be deprecated and was never supported in Internet Explorer. CSS animations on SVG elements don’t have the best browser support (yet), not to mention are quite buggy in some browsers. JavaScript is currently the best SVG animation tool. In this article, we'll go over the current and future state of SVG animation, giving you an overview of what you can and can't do, and some advice on what to choose for your specific animation needs.

Art-Directing SVG Images With The viewBox Attribute: How-To, Notes, Tips and Why We Need A viewBox Property in CSS

The SVG viewBox attribute is easily one of SVG's most powerful features. Mastering this attribute can take your SVG skills to the next level, especially considering that a couple of the main SVG spriting techniques rely on this attribute to work. Because the viewBox attribute can be used to crop and extend the SVG canvas, it can be used for art-directing SVGs—by using it to crop the SVG to the area that you want to display at a time. In this article, I want to go over how to do this, mention some tips that can save you some time doing it, and show the importance of having a viewBox property in CSS, in hopes that this article would serve as a practical use case that helps push this old SVGWG proposal forward. Since I’ve already covered everything you need to know about the viewBox attribute in a previous post, I will assume that you have a basic understanding of how the attribute works and what each of its values stands for. I will be mentioning some of the basics along the way, but I highly recommend you head to my other article and scan it before you move on with this article if you’re not familiar with the attribute. Quick Overview Of the viewBox Parameters The viewBox attribute is used to specify the origin and dimensions of the user coordinate system of an SVG image. All the drawing inside of the SVG is done relative to this system. And since the SVG canvas is conceptually infinite in all directions, you can even draw shapes outside the boundaries of this coordinate system; but the position of those shapes relative to the SVG viewport can also be controlled by the position of the user coordinate system. The viewBox attribute takes four parameters that specify the position of the origin of the system and its dimensions: x y width height. Initially, this system is identical to the initial viewport coordinate system established by the width and height of the SVG image, and its origin is at (0, 0)—the top left corner of the SVG. By changing the value of the x and y parameters you change the position of the origin. By changing the width and height, you change the dimensions of the system. This eventually allows you to extend and crop the SVG canvas using nothing but the viewBox attribute. Read along for examples. IMPORTANT NOTE: Throughout this article I won't be changing the default behavior (scale and position) of the viewBox inside the SVG viewport. Therefore, as per the default behavior of the attribute, the viewBox will scale as much as possible while still be entirely contained inside the viewport, and positioned at its center. Using the preserveAspectratio attribute, you can change the scale and position of the viewBox to your liking, but that is not required for the technique in this article to work, and therefore we won't be getting into that in this article. Cropping the SVG Using viewBox a.k.a SVG Art Direction Using the viewBox Attribute A while back, a client of mine requested that the SVG header photo of his website change on different screen sizes, so that only one portion of the full composition is visible on small screens, a bigger portion is visible on medium screens, and the full composition be visible on large screens. The first idea that crossed my mind when he requested that was to use the viewBox attribute to crop the SVG and only show the portions of the image he wanted on different screen sizes. By changing the dimensions of the SVG coordinate system and the position of its origin, we can crop an SVG to only show the parts that we want inside the viewport. Let’s see how that’s done. Suppose we have the following SVG image in full composition, that we want to crop on smaller screen sizes. The image is a freebie House vector designed by Freepik and is licensed under Creative Commons Attribution 3.0 Unported License. For the sake of simplicity, we will assume that the image is going to be cropped only once to show one portion on small–medium screens, and the full composition on larger screens, as shown in the image below. The full composition we are going to crop using the viewBox attribute. The image on the right shows the area of the image that we want to show on smaller screens. Now, there are a few considerations when cropping an SVG by changing the value of the viewBox attribute. We’ll get to these shortly. But first, in order to change the coordinate system so that it matches the dashed rectangular area in the above image, we need to change the value from its initial 0 0 800 800 parameters by translating the system’s origin and changing the width and height. But how do you know the new position and dimensions without having to go through a lot of trial and error? There are a couple of ways. Since we’re already in the graphics editor (Ai, in my example), we can use the editor’s panels to retrieve the positions and dimensions of elements. There is a reason why I drew that dashed rectangle to wrap the area I want to show on smaller screens: we can retrieve the position and dimensions of this rectangle and use them as values for the viewBox. Using Ai’s Transform panel (see image below), we retrieve these values. By selecting the rectangle and then clicking the Transform link at the top right corner, we get the panel shown in the image below, with the x, y, width and height values that we are going to use. The Transform panel in Ai can be used to retrieve the values of the selected rectangle's position and dimensions. As you have probably noticed, the values are not rounded, so we can do that ourselves. Using the above information, we change the viewBox value to: 0 200 512 512. Since the aspect ratio of the new viewBox is the same as the aspect ratio of the SVG viewport (both are square), the viewBox is going to scale up and only the selected area will be visible inside of the viewport. The result of changing the viewBox value is: The new cropped SVG. Only the portion we specified using the viewBox attribute is visible inside of the viewport. The blue border represents the SVG viewport. We need to ask a question here at this point: What if the aspect ratio of the cropped area (thus, the viewBox) is not the same as the aspect ratio of the SVG viewport? Well, in this case, there will be visible overflow. By visible overflow I don’t mean overflow extending beyond the boundaries of the SVG viewport, but overflow relative to the new user coordinate system defined by the viewBox. The following image illustrates the problem. If the aspect ratio of the viewBox is different from that of the viewport, and there is content inside the SVG that overflows the user coordinate system, you could end up with something like this. The black border represents the new user coordinate system, and the blue border is the SVG viewport. The black border in the above image on the right is the area defined by the viewBox. As per the default behavior of the viewBox inside the viewport, it has been centered and scaled up as much as possible while remaining fully contained inside the viewport (blue border). Since the SVG canvas is conceptually infinite in all directions, you can draw outside the boundaries of the user coordinate system, and the content would simply overflow the system as shown in the above image. If you change the aspect ratio of the SVG viewport (the SVG width and height) so they match those of the viewBox’s, you won’t see that overflow anymore, since the viewBox will scale to fit the viewport as in the previous example. But, in some scenarios, you may not be able or simply not want to change the aspect ratio of the Svg. An example is if you are using an SVG sprite to display images of a set of avatars on the page. In most cases, the avatars all have a fixed aspect ratio—you won’t be changing the size of each avatar to match the content of the image inside it. Or maybe you’re embedding an icon system and want/need all icons to have the same dimensions all the time. To clip off any excess (for example, part of another icon in the sprite that is showing inside the viewport), you can use a <clipPath> to clip that excess out. The clip path would be a <rect> element that covers the entire viewBox area, and is then applied to the root SVG. There is, however, one thing to keep in mind here: make sure the x and y attributes of the <rect> are identical to those of the viewBox, otherwise the rect will be positioned relative to the old/initial system’s origin and you will end up cropping and clipping an unexpected part of the SVG. Of course, clipping the excess out will mean that you’re still using different aspect ratios and are thus going to end with that extra white space on either side of the content. If the SVG is a continuous scene as in our previous example, this will be unwanted and you will need to adjust the aspect ratio of the viewport. If the SVG is a bunch of icons that you’re showing one at a time inside different viewports, this might not be an issue. The important thing here to keep in mind that the aspect ratio of the viewBox is best kept the same as that of the viewport; else, you will have to apply a fix to avoid any excess unwanted space inside the SVG. So, the viewBox can be used to crop the SVG and only show parts of it when needed. But how would that be done in a practical example? Art-Directing An SVG For Responsive Web Design Nothing new to add in this section, except the actual process with code. So, suppose you have the above SVG and you want to use it as a header image, for example, and you only want to show the cropped part on small–medium screen sizes and the full composition on bigger screens. In order to change the value of the SVG viewport’s width and height, we can use CSS. Simple. But to change the value of the viewBox, we currently need to use JavaScript. Not all SVG presentation attributes are available as CSS properties; only the set of attributes that have CSS property equivalents can be set in CSS. You can see an overview of the set of attributes available as CSS properties in this table. In SVG2, more attributes (like x, y, cx, cy, r, etc.) will be added to the list; but those are the properties we can work with today. In order to show different parts of the SVG by changing the viewBox value based on different media queries, you can, for example, use Modernizr, check for media query conditions, and then change the viewBox accordingly, in JavaScript. An example of that might look like so: This works. But wouldn’t it be much more optimal if we could use CSS to do this? Using a CSS viewBox Property To Art-Direct SVGs DISCLAIMER: At the time of writing of this article, there is no CSS viewBox property. This is just an example to demonstrate why such a property would be useful and an example of how I imagine it would be used. Ideally, we would be able to do something like this: These styles would go inside (or outside) an SVG, and the SVG will then adapt its viewBox according to the viewport size—be it the viewport of the page (in case of inline <svg>), or the viewport established by the dimensions of whichever element is used to reference the SVG (which would lend us something practically identical to element queries). This is currently not possible because we don’t have a viewBox property in CSS. A while back, I asked an SVG spec editor about this, and he said that I could propose it to the SVGWG with a practical use case and example. After some discussion on Twitter, I learned that there already is a fairly old SVGWG proposal thread that goes a few years back. The initial proposal is still there today, and my hope is that, with a practical use case like this, this proposal could be pushed forward and the property implementation specced at some point in the near future. If you would like to see the viewBox property in CSS, please help make this happen by pushing this thread forward and commenting on it. Things To Keep In Mind When Approaching SVG Art-Direction with viewBox While working on my client project, it took me literally less than a minute to art-direct the header image the way he wanted. However, we ended up going for three separate SVGs instead of using the same SVG with different viewBoxes on different screen sizes. The reason we chose to go with three SVGs is that the size of the full composition was too big to serve on mobile—reaching a whopping 100kb+ in size. The initial SVG was around 200kb, and I was able to slash the file size down to half by optimizing the SVG, but the resulting size was still too big to serve on mobile, so we ended up using three different images. This is something to keep in mind when art-directing SVGs: performance matters. A lot. So, if your SVG is too big, don’t art-direct it using viewBox. Now, if you choose to serve three different SVG images, you can do so in one of many possible ways—depending on the way you embed your SVG, and this also depends on what you want or don’t want to do with it. The ideal way to serve different SVG images would be to use the <picture> element. Not only does it allow us to provide different SVGs for the browser to choose from without needing JavaScript, but it also enables us to provide multiple optimized fallback images for non-supporting browsers (think IE8 and below) as well. <picture> is great when used with SVG, and you can read all about providing SVG fallback using <picture> in this article. All this being said, <picture> will not be your best choice if you want to animate or interact with your SVG. Just like an SVG embedded using <img>, the SVG cannot be styled and animated unless the styles and animations are defined inside the <svg> file, the SVG cannot be scripted (for security reasons), and any interactions (CSS or JS) — like hover, for example — will not work. So, as I always say: SVG provides us with a lot of options to do almost everything; you need to weigh things, prioritize, sometimes maybe even make compromizes, and pick your best route based on that. But never compromise performance in favor of development convenience. Before we finish up, and since we’re on the subject of changing the SVG canvas’ size using the viewBox attribute, let’s take a look at another example where we can leverage the power of this attribute to save us some time and effort when working with SVG. Extending the SVG Canvas using viewBox Just like the viewBox attribute can be used to crop an SVG, it can be used to extend the SVG canvas as well. A few weeks ago I created a tool that allows you to generate circular menus in SVG. I created a few examples to show how a generated menu could be animated using JavaScript. The demos are embedded on the app page using the <object> element. The boundaries of the <object> define the boundaries of the SVG viewport, and anything that lies outside these boundaries is considered overflow and will be hidden by default. Note that the phrase "outside these boundaries" refers to content inside the SVG that is still drawn on the infinite SVG canvas, but that extends beyond the finite rectangle defined by the viewport. The menus are created such that the size of the SVG is just big enough to contain the menu, not more, to avoid any excess and unwanted white space around the menu. I applied a staggering, bouncing animation to one of the menus as an example of how the menu can be animated. The bouncing effect “stretched” the menu items, and this led to the items being cut off while they animated. <object> element is just as big as the menu itself, the bouncing effect on the menu items results in these items being cut off when animated. The staggering bouncing animation is applied to the items such that it will scale an item from zero (items are initially not visible, scaled down) to 100% using a bouncing timing function, the effect of which will be scaling the item beyond 100% right before it is scaled back to 100%. This effect causes the item to scale up beyond the boundaries of the SVG and hence get cut off. The following image shows the result of scaling the menu item up beyond the boundaries of the <object> used to embed it (grey border). <object>). Setting overflow: visible on the <object> does not fix this, because <object> is practically similar to an <iframe> in behavior. What we need to do is extend the SVG canvas inside the viewport created by the <object> so that the scaled items have enough space to “bounce” without exceeding its boundaries. We can do this using the viewBox attribute. To extend the SVG canvas, you simply increase its dimensions. So, instead of 500px by 250px—the original dimensions of the SVG menu, we use 700px by 350px; this will increase the height of the canvas visible inside of the viewport by 100px, and its width inside of the viewport by 200px. I chose these values based on how much the menu item is being scaled up in the bounce effect. Depending on your SVG and what you’re working on, these values might be different. Now, to make sure the menu remains centered inside of the viewport, we’re going to shift the position of the coordinate system by 100 pixels in the negative direction (upwards and to the left). Applying this shift to the origin of the coordinate system is practically the same as applying a translation transformation to the menu inside of the system. The result will be that the menu remains centered inside of the viewport. <object>). The grey borders in this image show the initial dimensions of the user coordinate system. The blue numbers and arrows represent the extension of the coordinate system inside of the viewport. By extending the dimensions of the user coordinate system, you are increasing the area of the canvas visible inside of the viewport. The result of doing this will also be that the contents of the canvas will look slightly smaller—depending on how much you increase the canvas. In the case of the menu, the result was perfectly acceptable. The following screen recording shows the result of extending the SVG canvas and how the animation now looks inside the buondaries of the SVG. Changing four values inside the viewBox attribute to extend the SVG canvas was all that was needed to troubleshoot and solve the issue of the items being cut off. Now that’s pretty powerful, isn’t it? Wrapping Up The viewBox attribute is awesome. It is literally SVG on steroids. By using this attribute, you can save a lot of time when working with SVG, troubleshoot SVG quickly without having to resort to a graphics editor, and, all in all, feel more comfortable editing SVG by hand. I highly recommend you learn all about this attribute if you haven’t already, play with its values, and then leverage its power in your work. And if you do decide to use it to art-direct SVGs, don’t forget to keep performance in mind. One of the main objectives of this article was to also shed some light on the importance of having a viewBox property in CSS, so if you’re convinced that this property is needed, please take the time to vote on / respond to the SVGWG thread and support the request. Thank you very much for reading! :)

An Introduction To Graphical Effects in CSS

In this article, we will take a deep introduction into CSS’s graphical effects—specifically, CSS Filters and Compositing and Blending capabilities. We will go over the properties for each, their different values, and usage examples and some of the graphial effects that can be created using nothing but a few lines of CSS.

I Won A Web Platform Award

Today, O'Reilly's Fluent Conf is taking place in San Francisco, California. And as part of the conference, the O'Reilly Web Platform Awards were announced. Apparently, I was nominated for an award and, according to the co-chairs of the conference, I got the most amount of nominations and eventually won an award. O’Reilly Web Platform Awards recognize individual contributors who have demonstrated exceptional leadership, creativity, and collaboration in the development of JavaScript, HTML, CSS, and the supporting Web ecosystem. The nomination process is open to the entire web community and all entries will be judged by the Fluent program committee. This is my first time ever winning a web award, and I feel privileged to have won it from such a prestigious company. Simon sent me the “Congratulations, you won a web platform award!” email a couple of weeks before the awards were announced. My first reaction when I read the email was: “Okay this must have gotten into my inbox by mistake.” So I ended up responding to his message asking him if the email was really intended for me. He said that it was. I couldn’t believe it for a while and it took me some time to let the idea sink in that I had actually won an award. I had no clue. I love doing what I do and sharing what I know. I find great pleasure in helping others with what I know and always have—ever since I can remember. I really don’t know what to say except Thank You to each and every one who nominated me, and to the committee who voted, and to O’Reilly Fluent for this great award. It is such a wonderful and overwhelming feeling to realize that your work has been recognized by the very community you’re part of and have been contributing to. To know that the community appreciates your work and finds it useful is one of the best feelings ever. Thank you.

A Primer To Background Positioning In CSS

An article in which we take a deep dive into CSS’s background positioning properties with visual explanations and examples. Did you know that the CSS background-position property accepts edge offset values? That is, you can position a background image relative to any edge—not just top and left—and specify the offset relative to that edge using a length value. In this article, we will learn all about that, and more.

Building a Circular Navigation with SVG

Last week, I released CIRCULUS.SVG—the SVG circular menu generator. In this article I want to go over why SVG is better suited for creating this kind of UI element, and give you and overview of the SVG code for creating the menu items using SVG elements and transformations. Note that, unlike my usual tutorials, we will not be going over a detailed how-to, but only an overview of the concepts behind this. Creating the menu in detail would require lots of maths and digging into the SVG path data syntax which deserves an article of its own; so, for the sake of brevity, I will not be digging into either of these, but will go quickly over the concepts. Now, to draw the sectors, you can, of course, literally draw them in a graphics editor like Illustrator, Inkscape or Sketch, and then export your graphic as SVG, make it interactive, and embed it. However, since the title says “building”, we’re going to go over how to draw these items with code. If you’re only interested in the end result—a usable circular menu, you can head to the generator and create your own menu there. Otherwise, let’s start with why SVG is better than CSS for creating circular menus. SVG vs. CSS Over a year ago, I wrote an article over at Codrops about using CSS Transforms to create a circular navigation. Even though the technique works, it comes with a couple of browser bugs & inconsistencies, not to mention that it’s practially hacky—we’re bending the rectangular box model to create the menu items by skewing and rotating the list items and cutting them off by hiding the overflow on their container. The innards of the list items need to be “un-skewed”, and everything is positioned absolutely. Placing content other than icons inside the menu can get difficult depending on the type of content. And finally, to make the menu repsonsive, you’re gonna need to use media queries and adjust the different sizes used for different viewport widths (and/or heights!). With SVG, on the other hand, it’s very different. Shapes in SVG are marked up as semantic, fully-accessible XML elements like <rect>, <circle>, <ellipse> and <path>. And with the different drawing elements available, SVG makes for the perfect candidate for drawing non-rectangular shapes and elements. And to top it off, SVG items can be styled and scripted and hence are completely interactive. That’s exactly what we need for our circular menu. Since we are creating circular slices — a.k.a sectors (symbol: ⌔) — as menu items, we will use the <path> element to mark each slice up, since SVG’s path commands will allow us to draw the slices in a more straightforward manner using the line and arc commands available. Drawing the menu items in SVG is much, much more straightforward. Here is an interactive demonstration showing how the items are drawn and positioned inside the menu. Play the animation to see the demonstration. See the Pen Building A Circular Menu With SVG #2 by Sara Soueidan (@SaraSoueidan) on CodePen. Now that is definitely better than the steps taken in CSS, isn’t it? The SVG <path> comes with a bunch of commands for drawing lines and arcs. Let’s take a closer look at the commands and parameters used to draw our menu items. Drawing A Menu Item Using SVG <path> We’re going to need some data to draw our sectors. We will then pass this data to the <path> commands as parameters that define the shapes we’re drawing. A sector is defined by three points, a radius, and an angle. In order to draw a sector using the SVG <path> element, you need to know the coordinates for the three points. Then, using the path commands, we are going to move to the center of the circle (the first point), draw a line to the circle’s circumference (second point), then draw an elliptical arc from the second point to the position of the third point, and then close the path by drawing a line back to the center. The following is an interactive illustration showing how the path will be drawn. Click the button to start the demonstration. See the Pen 24de844274fb139d7eb1702783c9076d by Sara Soueidan (@SaraSoueidan) on CodePen. The three colored points are the points required to draw the sector. So let’s do some simple calculations to determine the coordinates of these points. Determining Point Coordinates In order to build the circular menu, we are going to start with a square SVG canvas that has 500px by 500px dimensions. So, the menu will be centered inside it. The center of the circle will be at the center of the square. The radius will be 250px. So the blue dot in the above demo (point A) will have the coordinates (250px, 250px), and the orange one (point B) will be positioned at (500px, 250px). To determine the coordinates of the third point (C), we need the value of the angle (that is determined based on the number of menu items); then, using the given data and the values of the angle’s sine and cosine, we can get the polar coordinates of the third point. The y value of the pink dot in the polar coordinate system is equal to sin(angle) multiplied by the radius r. The x value is equal to the cos(angle) mutiplied by the radius r. y polar coordinate value of the pink dot in the polar coordinate system is equal to sin(a) (h/r) multiplied by the radius r. The x polar coordinate value is equal to the cos(a) (w/r) mutiplied by the radius r. For the path data, we need the cartesian coordinates of the point, which means that we now need to convert the polar x and y coordinates we have to cartesian coordinates. Using a simple math conversion we can transform those coordinates into cartesian coordinates which will represent the coordinates of the pink dot in the SVG canvas. The conversion formula looks something like this (speaking in JS): Once you have all coordinates, you are ready to draw the sector. Drawing The Sector's Lines And Arc Using the SVG <path> element, each sector can be drawn using one line of SVG: The part we’re interested in is the content of the d (= data) attribute; it is where our coodinates will come in use. Here is a colored breakdown of the path data: M250,250 l250,0 A250,250 0 0,0 466.5063509461097,125 z We’re using four path commands here: M, l (small L), A and z. First, move to (M) the point of coordinates 250,250—the center of the circle. Next, draw a line to (l) the point that is at 250,0 relative to the current position. In other words, when we move to the orange dot, we are not using that point’s coordinates. We are calculating the horizontal and vertical distance of this point relative to the current position—which in this case is the center of the circle. You can, however, use the point’s coordinates if you use the L command (capital letter), which draws a line using absolute coordinates instead of relative ones. Okay so, move from the center 250 units to the right, drawing a line in that direction. Next, draw an elliptical arc (A) defined by: 250,250 0 0,0 (we’ll get back to these shortly), from the current position to the point at 466.5063509461097,125—which are the cartesian coordinates of the pink dot. The capital letter A command will draw an arc using absolute values; that is, it will draw an arc from the current position to the position you specify in the coordinates, and these coordiates will be absolute, not relative to the current position. Then, close the path (z): a line is drawn from the pink dot back to the center, and the sector is complete. But what is that 250,250 0 0,0 part all about? The elliptical arc command takes in a few parameters: (rx ry x-axis-rotation large-arc-flag sweep-flag x y). For our circular menu, the 250,250 part determines the horizontal and vertical radii (rx ry). Both values are equal since we are drawing a circular sector, not an elliptical one. You set these to be equal to the radius of the circle you are working on. For the sake of brevity, I’ll skip the next three parameters for now. What you need to know is that, for our circular menu, you need to set these three parameters to zero since we are drawing small circular arcs. Finally, the coordinates of the point to which the arc will be drawn are provided (x y). With one sector drawn, the others follow the same way. Draw as many sectors as you need. Then, the remaining sectors are rotated by the necessary angle to position them along the circle as we saw in demonstration from the previous section. Since CSS transforms on SVG elements are not supported in IE, I’ve used SVG’s native transformations to rotate the items. The transform attribute takes three parameters: the angle of rotation, and the x and y position of the center of rotation. The center of rotation is the center of the circle at (250px, 250px), and the angle of rotation is calculated based on the number of menu items you choose in the GUI and whether the menu is a full circle or a semi circle. Adding Icons To The Menu Items Since each icon could be more than just an icon—for example, an icon and a label, or just a label, it is best if we had a “wrapper” for whatever the contents of each item’s icon will be. The first thing that comes to mind in this case is using a group element: <g>. However, <g> has its limitations as it does not come with a viewBox attribute, nor does it create a coordinate system for its content to be positioned inside. The next logical option is using an <svg> element as a wrapper. The icons could be wrapped in <svg> elements which will create a coordinate system for the icon’s content. That being said, I chose not to go with this option because it would have required you to get your hands dirtier with the code whenever you wanted to modify or change the icons. I wanted to make it as simple as possible. For that reason, I chose the next best option: <symbol> and <use>. <symbol> accepts a viewBox attribute, and <use> accepts width and height attributes that serve as the viewport for the viewBox specified on the <symbol>. Thus, combined, <symbol> and <use> provide us with what <svg> would have provided us, plus a way to separate icon definitions from their actual use throughout the menu. Perfect. Positioning The Icons We don’t have relative positioning in SVG that allows us to position an element relative to another element, but we can use nested SVGs to work around that. That being said, nesting SVGs to position the icons “relative” to the sectors (or: relative to a common container, to be more accurate) would have been overkill given that we I could do it another way. My objective was to position the icons at the center of the sections and rotate them by an angle so that they look as if they are rotated with the sector. Visually speaking, the icons would be positioned along a virtual line that bisects the sector’s angle, and does not extend beyond the chord joining the orange and pink dots from the previous section’s illustration. Using the SVG DOM API, we can translate the above logic into code by first determining the virtual alignment line for the icon in the middle of the sector, the maximum length of that line which we can specify after getting the point on the chord where the virtual line and the chord would intersect, and then using the SVG getPointAtLength() method to specify where on that line the icon should be positioned. Then, what is left after that is simply rotating the icon by half the angle of the sector and nudging it a little bit so that its center is positioned at the point on the line that we want. Illustration showing icons positioned along a virtual line inside each menu item's sector. The two black dots in the above illustration show the position of the icon along the line (that we can get using getPointAtLength()) and the point of intersection of the line with the sector’s chord. The range control in the app’s GUI that allows you to change the position of the icon inside each item actually changes the result of getPointAtLength(), making sure it does not exceed the point of intersection with the chord. Linking In The Menu Each menu item is made up of the path representing the sector shape and a <use> element referencing a <symbol>. These two elements are wrapped in an anchor element: <a> to make an item clickable. Just like HTML <a> elements, an SVG anchor also has href and title attributes, with one important difference: namespacing. Before the href and title parts, you need to add the xlink namespace such that the link would be marked up like this: Additionally, the menu generator adds the role and tabindex attributes for accessibility. And that’s pretty much all you need for the items. About Styling And Interactivity In the CSS version of this menu, pointer events were buggy in some browsers and z-index was needed to handle stacking the elements on top of each other. With SVG, and because of the nature of elements in SVG, the pointer events are restricted to each shape without having to do anything extra. Since each shape is independent from the other and they do not overlap, no stack handling is required. Everything just works as you’d expect it to. Moreover, the SVG elements can be selected and styled in CSS. In order to make styling the elements and icons easier, I avoided adding any unnecessary presentation attributes. You can interact with the menu items and animate them independently using CSS or JavaScript. The app comes with a guide that includes a few animated examples using JavaScript. I chose the latter over CSS for browser compatibility because, again, IE does not support CSS transformations on SVG elements yet. Final Words SVG is very powerful, and SVG paths are one of the most powerful of its features. The very nature of SVG elements gives us more flexibility for creating and animating non-rectangular UI elements. And the fact that these elements can be drawn while remaining semantic and fully accessible gives SVG an edge for creating visually and functionally superior interfaces. I hope you found this article useful. Thank you for reading.

Extending the Color Cascade with the CSS currentColor Variable

If you use Sass or LESS, then you probably already use variables in your style sheets and know how useful they are. If you don’t use a preprocessor, then you might be curious what the fuss is all about and why variables are so popular and how they can be useful. In this article, we’re going to get an overview of why variables are useful, and get acquainted with one particular variable: currentColor.

Better SVG Fallback and Art Direction With The Element

Besides using an SVG as a background image in CSS, you can serve SVG foreground images in HTML using one of several embedding techniques, each of which has its advantages and use cases. Unless you’re in need of interactivity or external styling, <img> is the standard way for loading an SVG image, but it has one disadvantage: you currently need JavaScript to provide fallback and/or change the image source for art direction. In this post, I’ll talk about a better way to do that, using the <picture> element. This is not a primer to using <picture>. There are a lot of great resources in the wild that contain everything you need to know about the <picture> element, so if you’re not familiar with it, refer to the last section of the article for a list of resources to learn all about it. That being said, the article does not require any special or strong <picture> skills, as the examples are mostly self-explanatory as you will see. available in Russian. The Current <img> Before getting into why <picture> is a great option for SVG, let’s lay down (an overview of) the limitations and disadvantages of using <img> for responsive SVG work. Normally, if you load an SVG using an <img> tag, you can provide fallback and change the source of the image on different viewport sizes using feature detection and media queries in JavaScript. My choice for both would be to use Modernizr for both; that is, unless you’re only serving one image, in which case adding Modernizr might be overwork, and something like this: ..would be simpler and faster. Using Modernizr, you can detect browser support for SVG, and provide an alternative image src for when SVG is not supported. The alternative image URL can be stored in a custom data attribute. This approach is particularly useful for when you have multiple images on the page whose src you need to switch. Using Modernizr, you can detect whether or not the browser supports SVG and then take necessary steps to provide the fallback based on the test result: You can also use Modernizr’s media query detection to change the img src on based on viewport width for when you want to do art direction and not load the same big SVG on smaller screens: You don’t need to store any URLs in data attributes in this case if you are following a specific naming convention for your images. For example, if your images are named view-small.svg, view-big.svg, you can just replace the view-* part with the appropriate one in the JavaScript and be done with it. Now, if you want to provide a PNG or JPEG fallback for your SVG and also provide different sizes of that fallback image to match the viewport size, Modernizr will also do, but it will get slightly more complicated. And the most important part is: you need JavaScript to do it. With the <picture> element, we can do all that and more, without JavaScript. Well, kind of. Read on. The Bigger <picture> The <picture> element provides us with a better JavaScript-less way to change the image we are serving based on different media queries and a for providing fallback for non-supporting browsers (or browsers that can’t load the SVG for any reason). Loading An SVG and Providing Fallback For Non-Supporting Browsers Let’s start with fallback first. Providing fallback for browsers that can’t load the SVG is as simple as wrapping your <img> fallback in a <picture> element, and referencing your SVG in a <source> element: The <picture> element is just a wrapper for the elements used to load the image(s) you want and for the fallback provided with the <img> element. The <img> element is required for <picture> to work and is used to provide backwards compatibility for browsers that don’t support <picture> or, like our case here, browsers that can’t load or don’t support the the image(s) [type] you load in the <source> element. The <source> element is where we specify the image(s) we want. We’re specifying the type of the image we want (SVG) in the type attribute, and providing the URL to that image in the srcset attribute. And that’s all there really is to it; this is how simple it is to provide fallback for an SVG image using <picture>—no JavaScript is needed. You can take this even further and provide multiple fallback images that take screen resolution into account; to do that you can specify those images using the srcset attribute on the <img>. For example: The browser can then choose the image it finds appropriate based on the screen resolution. This is useful for when you are serving the same image size (for example, a one-size logo) but want to provide 2x and 3x versions for higher resolutions. But if you want you can take it even further. With the help of the sizes attribute, you can use media queries on the <img> to change the fallback image size on different screen sizes, providing a bigger image for bigger screens and a smaller one for small screens. What we’ve done here is we told the browser in the sizes attribute what size our image will occupy on the page. In this case, if the width of the viewport is 640px or more, the image will be 80% the width of the viewport, and 100% the width otherwise. Then, in the srcset attribute, we provided the browser with a list of images—they are all the same image, but in different sizes. Based on the sizes specified in sizes, the browser will pick the best fit among these images and display it. If a browser does not support srcset on <img>, it will simply display the fallback specified in the src attribute. For a detailed explanation of how this works, refer to this article over at A List Apart. Art Direction: Loading a Different SVG on Different Screen Sizes The <source> element we use to specify the image(s) we want comes with another attribute: media. This attribute provides us with the same flexibility we have for changing background images in CSS using CSS media queries, by allowing us to pair image sources with layout conditions (the media queries) right in the source code. Since we’re serving an SVG image, we don’t need to serve multiple versions of the image for different screen resolutions because of the infinitely scalable nature of SVG which makes it look great on any resolution. (Yay!) But if we have an SVG that we’re serving on desktop—for example, a wide header image, this image could be hundreds of kilobytes in size. Serving the same big image for small screens might not be the best idea if you look at it from a performance angle. Moreover, maybe you just don’t want to serve the same image on smaller sizes, but a “cropped” version of that image. I recently worked on a client project that required just that. Not only did my client want different images on smaller sizes, but the full composition was more than 100KB in size, which is obviously too much to serve on mobile devices, so we served cropped versions of that image. In such a case, you can specify different SVGs to load on different media conditions using the media attribute on the <source>. In the media attribute, you specify the media conditions similar to how you do it in CSS media queries. Of course, you can specify different fallback images for different resolutions and sizes, similar to what we did in the previous section. For the sake of brevity, I’m going to skip that step in this section, but you get the picture. (See what I did there?) You can also specify multiple sizes of each SVG image and let the browser pick the one it finds best, like we did for the fallback image before. However, due to the scalable nature of SVG, this might not be necessary. As a matter of fact, the options the <picture> element comes with cover practically any scenario. This article on the dev.opera blog covers a lot of these use cases with practical examples and snippets to help you get started. So, you see, with the <picture> element, we no longer need to use JavaScript to provide fallback and/or change the image based on different media conditions. Well, kind of… Browser Support and Polyfilling At the time of writing of this article, browser support for <picture> isn’t at its best, but it is getting better. A lot of smart people are working on <picture> implementation across browsers. Keep an eye on the compatibility table over at CanIUse.com to stay up-to-date on browser support in the future. In the meantime, and until browser support becomes more decent, you can use a JavaScript polyfill for non-supporting browsers. So yes, we do need JavaScript at the moment, but the code you write will be future-proof and all you need to do in the future when support gets better is to remove the polyfill, and your code will work without it as expected. Using <img> you’d need to do much more, or, at least, just keep using Javacript. The Picturefill polyfill by the folks at the Filament Group is the current de facto for cross-browser <picture> support today. The polyfill homepage contains extensive documentation on how to use the polyfill and tips on using <picture> in general along with general patterns. Using the polyfill is as simple as including the script in your page’s head: The async attribute tells the browser that it can load picturefill asynchronously, without waiting for it to finish before loading the rest of the document. According to the Picturefill documentation, If you add this attribute, you’ll need to add a line of script before the script tag as well to allow older browsers to recognize picture elements if it encounters them in the page before Picturefill has finished loading. If you are familiar with HTML5 Shiv, then you already know what this line is needed for. As a matter of fact, if you are already including a recent version of the HTML5 Shiv (sometimes packaged with Modernizr), you may not need this line as it is included there as well. Fixing IE9 While most versions of IE (even older ones!) are supported [by Picturefill] well, IE9 has a little conflict to work around. To support IE9, you will need to wrap a video element wrapper around the source elements in your picture tag. You can do this using conditional comments. — Picturefill homepage As the documentation says, the polyfill provides support for <picture> across browsers, but IE9 requires that you wrap your source elements in a video tag. And since this fix is only required for IE9, you can place it in IE9-targeting conditional comments: Foreground SVG Images with Interactivity and Styleability As mentioned at the beginning of the article, the <img> element, and naturally the <picture> element, only allow you to load a static SVG image, or an SVG with animations defined internally. If you need to load a foreground image and you want that image to be interactive and styleable, you can use one of four available ways: <object>, <iframe>, <embed> and inline <svg>. Both the <iframe> and <object> come with a default fallback mechanism. An inline <svg> requires a different approach to provide fallbacks; one such approach uses the <foreignObject> element. You can read all about it here. Chris has also written about providing fallback for SVG here. Final Words While using <picture> currently does require adding a JavaScript polyfill, using standard HTML5 markup and getting the flexibility of switching images using native elements is extremely powerful, and plugging the polyfill in is as easy as 1. download it, 2. add script to page, 3. you’re done. It’s absolutely worth it if you are doing art direction or providing fallback for multiple foreground SVG images. <picture> is more likely to become the standard way for art-directing SVG and providing img fallback in the future, so why start using it today? Both img way and the new picture require some JavaScript—for now, but the latter is definitely cleaner and more future-proof. Yes, img is also future-proof, but at some point, you get to ditch the polyfill and keep your code unchanged if you use picture, while img will either require you to keep using JavaScript or refactor your markup to make the switch to JavaScript-less picture. Whether you decide to start using <picture> for SVG today or not, it is definitely worth getting to know better and using it for serving other responsive image formats. So here is a list of recommended articles to get you up and running: Recommended Reading on <picture> Introducing the <picture> element Native Responsive Images Responsive Images in Practice Responsive Images: Use Cases and Documented Code Snippets to Get You Started Responsive Images For Designers: The HTML5 picture element

I Wrote A CSS Reference.

Yesterday, we finally released a long-awaited project over at Codrops: Codrops' new CSS Reference, authored by yours truly. Even though I wrote a post over at Codrops introducing the reference and its features, I want to share a little bit more about my experience writing it. Thus, unlike my usual highly-technical blog posts, this is a (possibly-boring, but short!) post sharing a little more about the CSS Reference and how it came to be, and answering a couple of questions I got via Twitter since the release. How It All Started I started writing for Codrops in 2013. Some time at the end of the year, I was thinking to myself: “Codrops would be an ultimate CSS reference if it had a CSS reference” (no pun intended). I thought that it would be fantastic if we had a CSS reference at hand for when someone needs to learn more about a specific CSS property used in one of the many creative demos found there. This idea came to my mind since I used to google for some of the properties I saw in the Codrops demos when I first started learning CSS and checking Codrops out regularly. Around the same time that year, Manoela approached me with the same idea. It was an idea in my head, and part of a vision that Manoela and Pedro have for Codrops. It was only a few days later that I started digging into CSS specifications and writing the reference entries. It took around 7–8 months to finish all of the entries. During that time, I had little time for side projects, but I did keep writing—albeit sporadically—on my blog and other blogs such as A List Apart, among others. Writing The Reference Entries One of the main reasons I looked forward to starting the journey of writing the reference was knowing how much I will learn in the process. For me, that was enough of a reason to instantly say yes when Manoela approached me with the idea. I knew it was a chance for me to know much more about CSS than I would otherwise know in such a short period of time. In order to write the description and information about a specific CSS feature, I had to dig deeper than I usually do into the specification where that CSS feature is defined. As many of you may know, the specifications don’t always contain everything you need to know about a property, and the writing style is not always the clearest (which is one of the reasons we wrote the reference, too!), so I had to do a lot of research for many of the entries, reading great resources here and there, picking up a lot of knowledge and getting a lot of “ah-ha” moments in the process. There was a lot about CSS that I didn’t know, and that I still don’t know. I wrote the CSS entries the same way and same style I usually write my articles. Now, some entries are exceptions because they don’t require a lot of elaboration. For example, properties like border-color are self-explanatory, so the tone of those entries is more “official” and less “me”. So, if you happen to enjoy my writing style, I can tell will enjoy reading the reference entries too. Manoela and Pedro gave me a lot of freedom and flexibility to write the reference at my own pace and my own schedule and time, making sure I still had the time to work on other things as well so that writing the reference does not limit my creativity, my other client work, my blog, and, of course, my life! Releasing The Reference I can’t even begin to describe how excited I was to finally get to the point of releasing the reference! I usually get super nervous (read: almost get a heart attack) before publishing a blog post on my own low-profile blog, so publishing more than 300 short to long articles on Codrops was extremely overwhelming and nerve-wrecking. I can always hear my heart beat when I tweet about a new blog post, and I certainly did when we finally got the word out about the reference. It took us a little over a year to release the reference because of the amount of work each of us at Codrops had, besides the reference. 2014 was the year I started speaking at conferences, and in the second half of it (i.e. after having finished writing the entries) I got my hands full with conference work, writing, and other stuff that took my attention away from the reference for some time. But we finally made it. Questions I got a few of questions from followers and commenters, and two of these questions kept popping up. Is it “the new MDN”? No, it’s not. At least it wasn’t our goal to make it so. It’s not even meant as competition to any other CSS Reference out there. It is simply another knowledge base added to what Codrops already offers on a regular basis. I write about CSS (and SVG) a lot—be it on my blog, on Codrops, or one of the several other places I write at. The CSS Reference is, for me, simply an archive where I collected blog posts about a specific topic (CSS, in this case), and organized them in a way that is easier to browse and simpler for my readers to find what they are looking for. blog posts about a specific topic (CSS, in this case), and organized them in a way that is easier to browse and simpler for my readers to find what they are looking for. I sometimes even think of it as a book! Instead of writing a printed CSS book, I wrote an online book, that is open to your contributions and suggestions via a Github repo that we shared on Codrops. So it has an advantage over a regular book in that you, my dear readers, get to pinpoint any miskates, errors, ask for additions and suggestions, etc. Why didn’t you contribute to MDN instead? I honestly don’t understand the reasoning behind this question. I mean, why would I not write the reference and choose to contribute to MDN instead? That being said, I did mention a few reasons earlier why I chose to write the reference. Add to those that I love Codrops, and Manoela and Pedro gave me a lot of freedom and flexibility to give the reference its own character and style. They asked me to write it because they liked my writing style, and thus gave me the freedom to structure the entries the way I wanted. We did have some specifics—for example, the sections for the official syntax, browser support, etc. that we needed to have in every entry, and the rest was all up to me to write my own way. Now, I don’t know if MDN would have allowed me to do the same, but Manoela knows how much I value the freedom and flexibility of work in my work, and she gave me just that, making the experience much more enjoyable, and feeling a lot less as a task or job. Final Words Writing the CSS reference has been a wonderful experience, and I am happy to have gotten the chance to do it. I know I haven’t literally written a book here (as in: a printed book), but I like to think that I have—maybe because it makes me feel a liiiitle bit less guilty for not having started writing my SVG book yet! I wholeheartedly hope you like it, find it useful, and learn from it as much as I have learned from writing it. Your feedback on Twitter, in the comments and your contributions in the Github repo have been amazing—thank you so much for your support! And thank you for reading this post, and reading the reference entries in the future. –S

Compositing And Blending In CSS

If you’re a designer, then you’ve probably already come across blending effects some time or the other. Blending is one of the most frequently used effects in graphic and print design. You can add texture to text by blending it with its textured backdrop, create an illusion of merged images by blending these images together, and create a wide range of colorful effects that would not be possible without that fine level of color blending control. Examples of typographic and image effects created using CSS blend modes. See following sections for live demos. Graphics editors such as Photoshop or Illustrator come with a set of blending modes. Blend modes allow you to specify how you want your elements to blend together, thus changing the colors of the area where these elements intersect. Each mode uses a specific color formula to mix the colors of the source and the destination. Different modes give different end results. Before we talk about the different blend modes, and since we mentioned the source and destination elements, let’s have a quick look at the concept of compositing, and how it is related to blending in CSS. What Is Compositing? Compositing is the combining of a graphic element with its backdrop. A backdrop is the content behind the element and is what the element is composited with. Compositing defines how what you want to draw will be blended with what is already drawn on the canvas. The source is what you want to draw, and the destination is what is already drawn (the backdrop). So, if you have two elements, and these elements overlap, you can think of the element on top as being the source, and the parts of the element behind that lie beneath it, will be the destination. Using different composite operations (there are 16 operations), you can specify which parts of the two overlapping elements will be drawn, and which will not. These composite operations are known as Porter Duff compositing operations. These operations specify what portions of the source and destination will be drawn, and blend modes specify how how the colors from the graphic element (source) and the backdrop (destination) interact. The illustrations in the above image are from the Compositing and Blending spec. In HTML5 Canvas context, these oprations are specified using the globalCompositeOperation property, and can be used to clip backgrounds to specific shapes, such as text, thus creating the effect of texture-filled text in Canvas. I have written about this process in this article over at Codrops. Together, Porter Duff Compositing and blending form the overall compositing operation for intersecting elements. According to the specification, “typically, the blending step is performed first, followed by the Porter-Duff compositing step. In the blending step, the resultant color from the mix of the element and the the backdrop is calculated. The graphic element’s color is replaced with this resultant color. The graphic element is then composited with the backdrop using the specified compositing operator.” Therefore, the way two intersecting or overlapping elements are handled is by blending their colors based on a blend mode, and then drawing only the parts specified by the composite operation. In CSS, we have no way to specify a composite operation. The default composite operation used is source-over. Both the source and the destination elements remain, and the area where they intersect is blended using the blend mode specified. Before the Compositing and Blending specification was introduced, CSS allowed one type of composite operations: simple alpha compositing. This is what the opacity property is for. By changing an element’s opacity, the browser makes it translucent so that the colors of its backdrop can show through. Today, two main properties exist that allow us to blend elements and backround images by specifying one of 16 available blend modes. These two properties are background-blend-mode and mix-blend-mode. Let’s get to know each. Blending Background Layers: The background-blend-mode Property The background-blend-mode property, as its name suggests, is used to specify a blend mode for an element’s background layer. A background layer can be an image, or the background color. In other words, background-blend-mode allows you to blend together an element’s background image with the images and/or background color behind it. If the element has more than one background image, you can specify multiple blend modes—each blend mode will be used for a background image such that the first blend mode in the list corresponds to the first background image in the list of background images, and so on. Then, each background layer is blended with the element’s background layer that is below it and the element’s background color. Which means that, if you have two background images and a background color: The second-image.png background will blend with the background color using the multiply mode, and then the first-image.png background will blend with the second image and the background color using the screen blend mode. (Reminder: the first background image in the list is the one on top, and the ones following it are beneath it.) Note that an element’s background layers must not blend with the content that is behind the element, instead they must act as if they are rendered into an isolated group. Also note that if the background shorthand is used, the background-blend-mode property for that element must be reset to its initial value. The Blend Modes Okay so we’ve established that each background layer can get its own blend mode which specifies how it blends with the layers beneath it. But what blend mode options do we have? There are 16 blend modes available in CSS: normal (which is the default blend mode and means that no blending is applied), multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color and luminosity. Each filter, when applied to an image, for example, will give a different end result—the colors of the image are going to be changed based on the mode you choose. normal This is the default mode which specifies no blending. The blending formula simply selects the source color. multiply The source color is multiplied by the destination color and replaces the destination. The resultant color is always at least as dark as either the source or destination color. Multiplying any color with black results in black. Multiplying any color with white preserves the original color. screen Multiplies the complements of the backdrop and source color values, then complements the result. The result color is always at least as light as either of the two constituent colors. Screening any color with white produces white; screening with black leaves the original color unchanged. The effect is similar to projecting multiple photographic slides simultaneously onto a single screen. overlay Multiplies or screens the colors, depending on the backdrop color value. Source colors overlay the backdrop while preserving its highlights and shadows. The backdrop color is not replaced but is mixed with the source color to reflect the lightness or darkness of the backdrop. darken Selects the darker of the backdrop and source colors. The backdrop is replaced with the source where the source is darker; otherwise, it is left unchanged. lighten Selects the lighter of the backdrop and source colors. The backdrop is replaced with the source where the source is lighter; otherwise, it is left unchanged. color-dodge Brightens the backdrop color to reflect the source color. Painting with black produces no changes. color-burn Darkens the backdrop color to reflect the source color. Painting with white produces no change. hard-light Multiplies or screens the colors, depending on the source color value. The effect is similar to shining a harsh spotlight on the backdrop. soft-light Darkens or lightens the colors, depending on the source color value. The effect is similar to shining a diffused spotlight on the backdrop. difference Subtracts the darker of the two constituent colors from the lighter color. Painting with white inverts the backdrop color; painting with black produces no change. exclusion Produces an effect similar to that of the Difference mode but lower in contrast. Painting with white inverts the backdrop color; painting with black produces no change. hue Creates a color with the hue of the source color and the saturation and luminosity of the backdrop color. saturation Creates a color with the saturation of the source color and the hue and luminosity of the backdrop color. Painting with this mode in an area of the backdrop that is a pure gray (no saturation) produces no change. color Creates a color with the hue and saturation of the source color and the luminosity of the backdrop color. This preserves the gray levels of the backdrop and is useful for coloring monochrome images or tinting color images. luminosity Creates a color with the luminosity of the source color and the hue and saturation of the backdrop color. This produces an inverse effect to that of the Color mode. This mode is the one you can use to create monchrome "tinted" image effects like the ones you can see in different website headers. The following image shows the result of applying the different blend modes to an image, in the same order mentioned above, starting from the top left corner. For more information about these blend modes, I refer you to this article on the SLR Lounge blog. It claims to be the ultimate visual guide to blend modes, and does include some nice explanations of the blend modes. Personally, I think that even with the definition for each mode at hand, it can be really hard (if not impossible) to predict the result of applying these modes to an image. Picking a suitable blend mode will be—in most cases—a case of trial and error. If you use Instagram you know that sometimes you just go over each of the available filters, applying them one after the other, till you get the effect you’re after. (I know I do that!) With CSS blend modes, it’s practically the same. For that reason, I’ve created a simple interactive demo that you can use to pick the right blend mode for your effects. Screenshot of the CSS Blender demo. You can upload an image, and choose a background color to blend it with. The background color of the live preview (thumbnails) will live-update as you make your way around the color picker. Clicking on a thumbnail will preview the selected blend mode in the larger preview area. Try the blend modes in the demo out. Of course, the effects will be visible only in browsers that support the background-blend-mode property. For more information about browser support, refer to the compatibility table over at CanIUse.com. In addition to blending a background image with a background color in the interactive demo, you can also blend a piece of text with the element that has this background. But blending separate elements together requires a property other than the background-blend-mode property. Let’s have a look at that next. Blending An Element With Elements In Its Backdrop: The mix-blend-mode Property As we mentioned earlier, a backdrop is the content behind the element and is what the element is composited with. The content behind the element can be anything—including other elements. And this is where the interesting effects come in. Think fixed headers blending with the content as the page scrolls down, or text blended with an image in the background, or text blending with other text, etc. Blending elements together is done using the mix-blend-mode property. The mix-blend-mode property is similar to the background-blend-mode property, and takes the same blend mode values. So, you can specify any blend mode to get different blending effects. For example, the text in the following image blends with the image behind it using mix-blend-mode: difference, giving the illusion of the water bubbles passing through and in front of the text. The reason this effect is established is the color inversion process of the difference mode. The area of the image where it overlaps with the text is the text’s backdrop, and that is where the blending happens. You can check the live demo out here. Using mix-blend-mode, you can create many creative effects—far more than I could list in this post. One particularly interesting effect you can create is see-through text. Without CSS blend modes, you would need CSS masking and/or background clipping, along with some CSS hackery to create this effect and make it work. With blend modes, and using the difference blend mode again, you can create this effect by—again—leveraging the color inversion process. The following image shows this effect in action. It is merely a piece of text, positioned on top of an image, and blended with it. That’s pretty cool, isn’t it? You can check the live demo out here. It is worth noting here that the colors you choose strongly affect the end result. That being said, the interactive demo can make picking the right colors for such an effect easier and faster. In the interactive demo, you have an option to add editable text to the preview area, and then style that text and blend it with the preview image using mix-blend-mode. The following is a screenshot showing an example. Screenshot of the CSS Blender demo, with a piece of text blended into the preview image. Check the demo out. Since we’re talking about blending elements together, it only makes sense that we mention stacking contexts, especially considering that they affect how and what elements can be blended together. According to the specification, applying a blend mode other than normal to the element must establish a new stacking context on that element, forming a group. This group must then be blended and composited with the stacking context that contains the element. Also, an element that has blending applied, must blend with all the underlying content of the stacking context that that element belongs to. It will not blend with contents outside that context. For example, the following image shows the result of mix-blending two images with the overlay mode. (Live demo) The code for the above simple example looks like so: I’ve wrapped the image on top (the .source) in a div that I’m going to create a stacking context on. Since the opacity property leads to the creation of a new stacking context when given a value other than th default (1), I’m going to use that. (Try it in the live demo.) By creating a stacking context, the .source image no longer blends with the bottom image, because the latter lies outside the stacking context containing the former. This is because we have isolated the image (and any other contents of the .img-wrapper context) from the rest of the elements, and thus they don’t blend with their backdrops anymore. This brings us to the isolation property. But before we move on, note that the mix-blend-mode property also applies to SVG elements, and can be used to blend overlapping SVG elements together as well. As a matter of fact, the logo for the CSS Blender demo is a result of applying a mix-blend-mode to the three squares that make the demo up. You can see how the areas where these squares overlap have different colors due to the color blending applied. Browser support for the mix-blend-mode property is not as wide as that of the background-blend-mode property. For details, refer to the browser compatibility table over at CanIUse.com. Isolating Elements: The isolation Property When a property that leads to the creation of a stacking context is applied to an element, that element is said to be isolated. The last example in the previous section is an example of this happening. On the other hand, you can use the isolation property to isolate elements. In SVG, this property defines whether an element is isolated or not. For CSS, setting isolation to isolate will turn the element into a stacking context, and thus affect whether or not the element’s contents can blend with their backdrop lying outside this context. By default, the isolation property is set to auto—which implies that they are not isolated. If we were to go back to the previous example with the two blended images, we can prevent the image on top from blending with the image behind it by using the isolation property instead of the opacity property. This has the same effect as using opacity in the previous example. If you use this rule instead of opacity in the live demo, you will get the same result. Note that by creating a stacking context on an element, you are isolating the content of that element and preventing them from blending with the backdrop of that element. However, you can still apply a blend mode to the entire context to blend it with its backdrop. Moreover, If you are using thebackground-blend-mode property, the isolation property is not needed since background layers must not blend with the content that is behind the element, instead they must act as if they are rendered into an isolated group (the element itself), as specified in the specification. This is why the isolation property will have an effect when used with the mix-blend-mode property, but not with the background-blend-mode property. Note: Order Of Graphical Operations CSS blending modes, filters and masks, can all be applied to the same element. But which effect is applied first? According to the specification, first any filter effect is applied, then any clipping, masking, blending and compositing. Final Words With all the graphical operations available to us via CSS, we are getting more possibilities for designing in the browsers—this is particularly interesting if you—like me—are not into graphics editors and don’t know your way around them well. The web platform team at Adobe have been doing a tremendous job bringing many of their tools' graphical capabilities to the web. From filters, to blend modes, clipping and masking, and even CSS Shapes, we are gaining more control over layout and graphics on the web. Many creative effects can be created using CSS blend modes, and when combined with other technologies, they open a door to endless creative possibilities. I hope you liked this article and found it useful. Thank you for reading!

Useful SVGO[ptimization] Tools

One of the steps you need to do when working with SVG is optimizing the SVG code after exporting it from the editor and before embedding in on your web page. For that, several standalone optimization tools exits. The two tools I usually mention in my articles and talks are Peter Collingridge's online editor, and SVGO. In this article, I'm going to introduce you to a new SVGO Tool that provides us with everything Peter's tool does, and a bit more. This is not to say that peter’s tool is no longer useful—it certainly is. But if you use SVGO, then you know how convenient it is with all the available tools it comes with. What is SVGO? For those of you who are not familiar with SVGO: it is a node-js based SVG optimization tool. (SVGO is an abbreviation for SVG Optimization). It comes with a set of tools and plugins that make it a great tool that you can integrate into almost any kind of workflow. (We’ll go over these tools shortly.) However, SVGO has one disadvantage: it can easily break your SVG—especially if it is animated or scripted, the document structure will change and eventually break any animations or scripting applied. Even with the many SVGO tools and plugins available, unfortunately, we had no way to preview the result of applying SVGO optimizations to an SVG, to tell whether they will break it or not.. until now. Introducing SVGOMG Last month, when I wrote the SVG performance article for Perf Calendar, Google’s Jake Archibald tech-reviewed the article. And while discussing the code optimization section, I mentioned how SVGO lacks a GUI that allows us to preview the result of running the optimizations on our SVGs, and how it should be used with caution because of that. A week or two later, Jake made the SVGOMG GUI—an interface that allows you to optimize SVGs by selecting your optimizations, and getting a live preview of how your SVG looks with these optimizations applied. Screenshot of the SVGOMG GUI. If you’ve used Peter’s tool before, you can expect the same from SVGOMG, and more. You can upload an SVG file, paste SVG code in, or load the default demo SVG—if you’re just trying the app out. A set of options will then be revealed on the right side of the screen (see screenshot above). These options represent the optimizations built into SVGO. The SVGO optimizations are plugins that you can enable and disable as needed, and SVGOMG offers you a visual way of doing so. The live preview section will update as you choose your optimizations, allowing you to detect and disable any optimizations that would break your SVG. In the top right corner, you can see the current file size and the optimization percentage. You also have an option to show the original SVG—which will also display the original file size, to compare your it to your optimized version. SVGOMG is an online tool. But if you know Jake then you’ll probably expect it to also work offline, considering that he might just be the biggest proponent of ServiceWorker and offline-first out there. He has written about it a lot on his blog. Thus—expectedly—the GUI works offline too in any browser that’s got ServiceWorker. (For an overview of the state of ServiceWorker, refer to this browser compatibility page.) Once you’ve opened the app (try it in Chrome, for example), you will get a notification a couple of seconds later telling you that the GUI is ready to work offline. Screenshot of SVGOMG showing the notification that the GUI works offline. Very useful, isn’t it? Other SVGO Tools There are quite a few SVGO plugins available that can be used in a variety of ways, depending on your preferred workflow: Adobe Illustrator Plugin A GUI allowing you to select the optimizations you want to apply also exists in another SVGO tool called SVG NOW. SVG NOW is an Illustrator plugin that brings SVGO’s optimizations into Illustrator. It is an alternative SVG exporter for AI, aimed at optimizing SVG files by post-processing the generated SVG code using SVGO. This is useful for sure, but SVG NOW does not show you a live preview of how the SVG is affected by the optimizations you choose. Inkscape Plugin Similar to SVG NOW, SVGO-Inkscape is an Inkscape plugin that allows you to remove a lot of redundant and useless information such as editor metadata, comments, hidden elements, default or non-optimal values and other stuff generated by Inkscape and that can be safely removed or converted without affecting SVG rendering result. Sketch Plugin SVGO Compressor is the Sketch version of the SVGO plugin, which compresses SVG assets using SVGO, right when you export them. As with other SVGO tools, there’s no way of telling how the exported SVG will be affected by the optimizations applied. From my personal experience I’ve found that SVGs exported using Sketch were more likely to break when optimized with SVGO, because of how Sketch exports certain SVG shapes using clip paths and masks. So it’s useful to remember that you might need to re-export and re-optimize the SVG another way if and when this happens. Note that the plugin requires Sketch 3.8, and so it won’t work with older versions of the application. Drag'n'Drop GUI Another kind of GUI for SVGO exists — called SVGO GUI — that allows you to drag-and-drop your SVGs and then optimizes those SVG on-the-fly, replacing your original ones with the optimized versions. This GUI is useful for quick bulk optimizations, but it risky considering that 1) you cannot preview the optimized SVG 2) your original SVGs are instantly replaced by the optimized versions, which means that your SVGs might break, and the broken ones will replace the original ones. If you’re going to use this GUI, make sure you have a backup before you optmize. Grunt and Gulp Plugins SVGO is probably mostly known for its Grunt plugin, and its sister the Gulp plugin. Both of these plugins allow you to enable and disable SVGO optimizations as needed. For example, a default SVGO optimization will remove the viewBox attribute from your SVG. This is something you should completely avoid, because, without the viewBox attribute, the SVG cannot be made responsive. (For more information about the viewBox attribute, refer to my tutorial here.) When you set up SVGO in Grunt, for example, you can disable any plugins you want. For example, to disable removing the viewBox, add removeViewBox: false to the Plugins object in your configuration file. You can refer to the plugin’s Github repo for more information. OS X Folder Action SVGO also comes with an OS X folder action that you can attach to any folder, and then have your SVGs optimized on-the-fly as soon as you place them in that folder. Again, optmized versions will replace the original ones, so be careful. Final Words No matter what your workflow is, SVGO can probably fit into it, one way or another. I’m sure other SVG optimization tools exits, but with all the options SVGO comes with, if you ask me, this is the tool I would recommend. Optimize those SVGs, build something beautiful, and share it with the world. Thank you for reading.

Using The CSS :target Selector To Create JavaScript-less UI Effects

You may or may not have used the :target selector before; and you may or may not have used it to show and hide elements without having to resort to JavaScript to handle this event for you. This article I wrote for the Adobe Dreamweaver team blog, serves as a short introduction to the :target selector, showing how you can use it to create JavaScript-less UI effects—for example, overlays, modals, etc.

Tips For Optimizing SVG Delivery For The Web

SVGs are a great asset in our responsive web design toolkit. But just like any other image format, there are certain steps you should take to make sure you’re delivering optimised resources that don’t have a negative impact on your page’s performance. Here are some things that you can do to make sure you’re delivering better SVGs for the web.

An Overview Of SVG Sprite Creation Techniques

SVG can be used as an icon system to replace icon fonts, and there are several ways to create SVG sprites. This article I wrote for this year's 24Ways will give you an overview of three of them. While we’re at it, we’re going to take a look at some of the available tools used to automate sprite creation and fallback for us.

Styling and Animating SVGs with CSS

CSS can be used to style and animate scalable vector graphics, much like it is used to style and animate HTML elements. In this article I wrote for Smashing Magazine, which is a modified transcript of a talk I recently gave at CSSconf EU and From the Front, I’ll go over the prerequisites and techniques for working with CSS in SVG.

A Guide to SVG Animations (SMIL)

What the title says: a complete guide to SVG animations derived from the SMIl specification. The extensive guide features a lot of demos and goes over the animations syntax, covering almost everything you need to know to get started with SVG Animations today.

Making SVGs Responsive With CSS

An article on how to make embedded SVGs cross-browser responsive. We're going to cover embedding techniques, how to apply the "Padding Hack" and how to use inline media queries to make SVGs adaptive.

Understanding SVG Coordinate Systems and Transformations (Part 3) — Establishing New Viewports

At any point in an SVG drawing, you can establish new viewports and user coordinate systems by either nesting <svg>s or using elements such as the <symbol> element, among others. In this article we're going to have a look at how we can do that and how this can be useful for controlling SVG elements and making them more flexible (and/or fluid). This is the third and last article in a series of articles about SVG coordinate systems and transformations. In the first article, I covered everything you need to know to understand the basics of SVG coordinate systems; more specifically, the SVG viewport, and the viewBox and preserveAspectRatio attributes. In the second article, you can find everything you need to know about how SVG system transformations work. Understanding SVG Coordinate Systems & Transformations (Part 1) – The viewport, viewBox, and preserveAspectRatio Understanding SVG Coordinate Systems & Transformations (Part 2) – The transform Attribute Understanding SVG Coordinate Systems & Transformations (Part 3) – Establishing New Viewports Throughout this article, I’m going to assume that you read the first part of this series about SVG viewports and the viewBox and preserveAspectRatio attributes. You don’t need to have read the second one about coordinate system transformations to follow along this article. Nesting <svg>> Elements In the [first part]({{ site.url }}/blog/svg-coordinate-systems) we talked about how the <svg> element establishes a viewport for the content of the SVG canvas. At any point in an SVG drawing, you can establish a new viewport into which all contained graphics is drawn by including an <svg> element inside another <svg>. By establishing a new viewport, you also implicitly establish a new viewport coordinate system and a new user coordinate system. For example, suppose you have an <svg> and some content inside it: The first thing to note here is that the inner <svg> element does not require specifying a namespace xmlns on it because it is assumed to be the same namespace as the outer <svg>’s namespace. Of course, even the outer <svg> does not require a namespace if it is embedded inline in an HTML5 document. You can use a nested SVG to group elements together and then position them inside the parent SVG. Now, you can also group elements together and position them using the <g> group—by wrapping elements inside a [group <g> element]({{ site.url }}/blog/structuring-grouping-referencing-in-svg), you can position them on the canvas by using the transform attribute. However, an <svg> element has certain advantages over using <g>. Positioning using x and y coordinates is, in most cases, more convenient than using transforms. Moreover, an <svg> element accepts width and height attributes, which the <g> element doesn’t. That said, the <svg> may not always be needed or necessary, because it leads to the creation of a new viewport and coordinate systems, which you may not need or want. By specifying a width and height to the <svg>, you restrict the content inside it to the bounds of the viewport that is defined by the x, y, width, and height attributes. Any content that lies beyond these bounds will be clipped. If you don’t specify x and y attributes, they’re assumed to be zero. If you don’t specify height and width attributes, the <svg> will be 100% the width and height of its parent SVG. Moreover, specifying a user coordinate system other than the default one will also affect the content inside the inner <svg>, too. Percentage values specified for elements inside the inner <svg> will be calculated relative to it, not relative to the outer svg. Percentage values specified on the inner itself <svg> will be calculated relative to the outer svg. For example, the following will result in the inner SVG being equal to 400 units, and the rectangle inside it will be 200 units: If the width of the outermost <svg> is set to 100% (for example, if it is embedded inline in a document and you want it to be fluid), then the inner SVG will expand and shrink as necessary to maintain a width that is half of that of the outer SVG – this is powerful. Nested SVGs are particularly useful for adding flexibility and fluidness to elements on the SVG canvas. We know that, using viewBox values and preserveAspectRatio, we can already create responsive SVGs. The outermost <svg>’s with can be set to 100% to make sure it expands and shrinks as its container (or the page) grows or shrinks. Then, by using viewBox values and preserveAspectRatio, we can make sure that the SVG canvas also responds to the changes in the viewport (outermost svg). I’ve written about responsifying SVGs in my CSSConf talk slides. You can check the technique out here. However, when we do responsify an SVG like that, the entire canvas with all the elements drawn on it will respond and change simultaneously. But sometimes, you may want to have only one element inside the graphic to be flexible, while keeping others “fixed” in position and/or size. This is where nested svgs can be useful. An svg element can have its own coordinate system independent of its parent, and it can have its own viewBox and preserveAspectRatio attributes that allow you to size and position the content inside it any way you want. So, in order to make one element flexible, we can wrap it in an <svg> element, and give that svg a flexible width so that it adjusts to the width of the outermost SVG, and then specify preserveAspectRatio="none" so that the graphic inside it also stretches and shrinks with the container width. (Note that svgs can be nested to many levels, but in order to keep things simple, I’m nesting only one level deep in this article.) To demonstrate how nested svgs can be useful, let’s look at some examples. Example Suppose we have the following SVG: The above SVG is responsive. Resizing the screen will result in the entire SVG graphic responding as necessary. The following screenshot shows the result of shrinking the page, and how the SVG becomes smaller. Notice how the contents of the SVG maintain all their initial positions with respect to the SVG viewport and with respect to each other. Using nested SVGs, we’re going to change that. We can specify a position for individual elements inside the SVG relative to the SVG’s viewport, so that as the SVG viewport size changes (i.e the size of the outermost svg changes), the elements respond independently of each other. We’re going to create an effect such that, when the screen is resized, the upper part of the egg is going to be moved so that the cute chicken inside it peeks out, as shown in the following image: In order to get that effect, the egg’s upper part has to be separated from the rest by wrapping it inside an svg of its own. This svg wrapper will get an ID upper-shell. Then, we’re going to make sure the new svg#upper-shell has the same height and width as the outer SVG. This can be achieved by either specifying width="100%" height="100%" on the svg, or by not specifying any height and width at all. If no width and height are specified on the inner SVG, it automatically expands to 100% the width and height of the outer SVG. And finally, to make sure the upper shell is “lifted” up or positioned at the top center of the svg#upper-shell, we’re going to use the appropriate preserveAspectRatio value which makes sure the viewBox is positioned at the top center of the viewport—the value is xMidYMin. The code for the SVG graphic becomes: I've stripped out the parts that relevant to the article like the gradient used to color the egg shells and the paths forming the shapes, just for the sake of brevity in the example code. At this point, note that the viewBox specified on the nested svg#upper-shell has the same value as that of the outermost svg (before it was removed). The reason we used the same viewBox value is so that, the SVG maintains its original look on big screens. So, the way this goes is: we start with an SVG—in our case, it’s the image of a cracked egg with a chicken hidden inside it. Then, we create another “layer” and promote the upper shell to it—this layer is created by using a nested svg. The nested svg has the same dimensions as the outer svg and the same viewBox. And finally, the viewBox of the inner SVG is set to “stick” to the top of the viewport no matter what the screen size is—this makes sure that, when the screen size is narrow and the SVG is elongated, the upper shell will be lifted upwards, thus showing the chicken “behind” it on the canvas. Once the screen size shrinks, the SVG is elongated, and the viewBox containing the upper shell is positioned at the top of the viewport using preserveAspectratio="xMidYMin meet". svg. The translucent orange box shows the viewBox inside the svg—it is positioned at the top center of the viewport using preserveAspectratio="xMidYMin meet". Click on the following button to see the live SVG. Remember to resize your browser to see the SVG adapt. View Live Example Nesting or “layering” SVGs allows you to position parts of the SVG relative to the changing viewport, while maintaining the elements' aspect ratio. So the image adapts without distorting the elements inside it. If we wanted the entire egg to come off the chicken, we could always wrap the lower shell in an svg layer of its own, having the same viewBox, too. Then, to make sure the lower shell moves down and sticks to the bottom center of the viewport, we position it using preserveAspectRatio="xMidYMax meet". The code would look like this: Each of the svg layers/viewports is equal to 100% the width and height of the outermost svg. So we basically have three clones. Each layer contains an element—the upper shell, the lower shell, or the chick. The viewBox for the three layers is the same, with only the preserveAspectRatio being different. svgs have a 100% height and width value covering the entire outermost viewport. Their viewBoxes are also equal as you can see in the image. Only the position of these viewBoxes is different (specified using preserveAspectRatio). Of course, in this example I started with a graphic of a chicken hiding inside an egg, and that is revealed when the screen becomes smaller. However, you could do something different: you could start with a graphic on a small screen, that then reveals something new as the screen becomes bigger; i.e as the svg becomes wider and there is more horizontal space to show elements. You could get a lot more creative, and show and hide elements according to different screen sizes—using media queries—and have the new elements be positioned in a certain way to achieve a certain effect. The sky is the limit here. Also note that the nested svgs don’t need to have the same height and width as their containing svg; you can specify a height and width and have the content of the svg be limited to and clipped by the boundaries specified by that height and width—it all boils down to what you’re trying to achieve. Making Elements Fluid Using Nested SVGs In addition to positioning elements while preserving their aspect ratios, we can use nested svgs allow only certain elements to be fluid—this can be done by not preserving the aspect ratio of these particular elements. For example, if you want only one element in the SVG to be fluid, you can wrap it in an svg, and use preserveAspectRatio="none" to have that element expand to fill the entire width of the viewport at all times, while maintaining the aspect ratio and positioning of other elements like we did in the previous example. Jake Archibald created a simple and practical use case for nested SVGs that does exactly that: a simple UI that contains elements positioned at the corners of the outermost svg, maintaining their aspect ratios, and a middle part of the UI is fluid and responds to the change in the svg width by shrinking and expanding with it. You can check his demo out here. Make sure you inspect the code in the dev tools to select and visualize the different viewboxes and svgs used. Other ways to establish new viewports svg elements are not the only elements that establish new viewports in SVG. In the following sections, we’re going to go over the other ways to establish new viewports using other SVG elements. Establishing a new viewport by <use>ing <symbol> The symbol element defines a new viewport whenever it is instantiated by the use element. A symbol element can be used by referencing it in the xlink:href attribute of the use element: The question marks used as values above are used only to indicate that these values may or may not be specified—if x and y are not specified, they default to zero, and you don’t need to specify a height and width either. You see, when you use a symbol element, and then inspect the DOM using the dev tools, you will not see the contents of the symbol inside the use tag. The reason for this is that the contents of use are rendered into a shadow tree, which you can inspect if you enable inspecting the shadow DOM in the dev tools. When the symbol is used, it is deeply cloned into the generated shadow tree, with the exception that the symbol is replaced by an svg. This generated svg will always have explicit values for attributes width and height. If attributes width and/or height are provided on the use element, then these attributes will be transferred to the generated svg. If attributes width and/or height are not specified, the generated svg element will use values of 100% for these attributes. symbol is used, it is deeply cloned into the generated shadow tree, with the exception that the symbol is replaced by an svg. Because we end up with an svg in the DOM, and because this svg is practically contained in the outer svg where use is used, we’re left with a nested svg situation not very different from the one we talked about in the previous section—the nested svg forms a new viewport. The viewBox for the nested svg is the viewBox specified on the symbol element. (The symbol element accepts a viewBox attribute value. For more information, refer to the article: Structuring, Grouping, and Referencing in SVG – The <g>, <use>, <defs> and <symbol> Elements). So we now have a new viewport whose dimensions and position can be specified in the use element (x, y, width, height), and whose viewBox value can also be specified in the symbol element. The content of the symbol is then rendered and positioned inside this viewport and viewBox. And last but not least, the symbol element also accepts a preserveAspectratio attribute value, that allows you to position the viewBox inside the new viewport established by use. Pretty neat, right? You can control the newly created nested svg just like we did in the previous sections. Dirk Weber has also created a demo that uses nested SVGs and symbol elements to mimic the behavior of CSS border images. You can check his article out here. Establishing a new viewport by referencing an SVG image in <image> The image element indicates that the contents of a complete file are to be rendered into a given rectangle within the current user coordinate system. The image element can refer to raster image files such as PNG or JPEG or to files with MIME type of “image/svg+xml”. An image element that references an SVG file will result in the establishment of a temporary new viewport since the referenced resource by definition will have an svg element. The <image> element accepts many attributes, some of these attributes—the ones that are relevant to this article—are x and y position attributes, width and height attributes, and preserveAspectratio. Normally, an SVG file will contain a root <svg> element; this element may or may not have position and dimensions specified, in addition to a viewBox and a preserveAspectratio value. When an image element references an SVG image file, the x, y, width and height attributes on the root svg are ignored. Unless the value of preserveAspectRatio on the image element starts with ‘defer’, the preserveAspectRatio attribute on the root element in the referenced SVG image is also ignored. Instead, the preserveAspectRatio attribute on the referencing image element defines how the SVG image content is fitted into the viewport. The value of the viewBox attribute to use when evaluating the preserveAspectRatio attribute is defined by the referenced content. For content that clearly identifies a viewBox (e.g. an SVG file with the viewBox attribute on the outermost svg element) that value should be used. For most raster content (PNG, JPEG) the bounds of the image should be used (i.e. the image element has an implicit viewBox of ‘0 0 raster-image-width raster-image-height’). Where no value is readily available (e.g. an SVG file with no viewBox attribute on the outermost svg element) the preserveAspectRatio attribute is ignored, and only the translation due to the x & y attributes of the viewport is used to display the content. For example, if the image element referenced a PNG or JPEG and preserveAspectRatio="xMinYMin meet", then the aspect ratio of the raster would be preserved, the raster would be sized as large as possible while ensuring that the entire raster fits within the viewport, and the top/left of the raster would be aligned with the top/left of the viewport as defined by the attributes x, y, width and height on the image element. preserveAspectRatio was ‘none’ then aspect ratio of the image would not be preserved. The image would be fitted such that the top/left corner of the raster exactly aligns with coordinate (x, y) and the bottom/right corner of the raster exactly aligns with coordinate (x+width, y+height). Establishing a new viewport using <iframe> An iframe element that references an SVG file establishes new viewport similar to the situation of image element explained above. An iframe element can also have x, y, width, and height attributes, in addition to its own preserveAspectratio. Establishing a new viewport using <foreignObject> A foreignObject element creates a new viewport for rendering the content that is within the element. The foreignObject tag allows you to add non-SVG content into an SVG file. Usually, the contents of foreignObject are assumed to be from a different namespace. For example, you could drop some HTML in the middle of an SVG element. The foreignObject element accepts attributes, among which are x, y, height, and width, which are used to position the object and size it, creating the bounds used to render the contents referenced inside it. There is a lot to say about the foreignObject element besides its creation of a new viewport for its content. If you’re interested, you can check the MDN entry or check this practical use case by Christian Schaeffer on The Nitty Gritty Blog. Wrapping Up Establishing new viewports and coordinate systems—be that by nesting svgs or another element from the ones mentioned above—allows you to control parts of the SVG that you would otherwise not be able to control the same way. The entire time that I was working on this article and thinking of demos and use cases, all I kept thinking of is how nesting SVGs can give us finer control and flexibility for when we’re dealing with SVGs. Adaptive SVGs can be created with neat effects, fluid elements inside SVGs that are independent of the other elements on the page are possible, mimicing CSS border images for crispier backgrounds on high-resolution screens, and so much more. Have you created any interesting examples using nested viewports in SVG? Can you think of more creative examples? This article concludes the series of “Understanding SVG Coordinate Systems & Transformations”. Next up, we’ll be diving into animations, and more! Stay tuned, and thank you for reading!

Understanding SVG Coordinate Systems and Transformations (Part 2) — The transform Attribute

SVG elements can be transformed by scaling, translating, skewing, and rotating—much like HTML elements can be transformed using CSS Transforms. However, there are certain inevitable differences when it comes to the coordinate systems used and affected by these transformations. In this article we'll go over the SVG transform attribute and CSS property, covering how to use it, and things you should know about SVG coordinate system transformations. This is the second article in a series I’m writing about SVG coordinate systems and transformations. In the first article, I covered everything you need to know to understand the basics of SVG coordinate systems; more specifically, the SVG viewport, and the viewBox and preserveAspectRatio attributes. Understanding SVG Coordinate Systems & Transformations (Part 1) – The viewport, viewBox, and preserveAspectRatio Understanding SVG Coordinate Systems & Transformations (Part 2) – The transform Attribute Understanding SVG Coordinate Systems & Transformations (Part 3) – Establishing New Viewports In this part I’m going to assume you read the first one, so, if you haven’t, make sure you do before you continue reading this article. The transform Attribute Values The transform attribute is used to specify one or more transformations on an element. It takes a <transform-list> as a value which is defined as a list of transform definitions, which are applied in the order provided. The individual transform definitions are separated by whitespace and/or a comma. An example of applying a transformation to an element may look like the following: The possible SVG transformations are: rotation, scaling, translation, and skewing. The transformation functions used in the transform attribute work similar to the way CSS transform functions work in the transform property, except that they take different arguments. transform attribute. See the section about transforming SVGs with CSS properties for information on the syntax used in the CSS transform properties. Matrix You can apply one or more transformations to an SVG element using the matrix() function. The syntax for the matrix transformation is: The above declaration specifies a transformation in the form of a transformation matrix of six values. matrix(a,b,c,d,e,f) is equivalent to applying the transformation matrix [a b c d e f]. For those of you who are not math-savvy, you’re probably not going to be using this function. Those of you who are, you can read more about the math behind it here. Since this function is rarely used—if ever—I’m just going to skip to the other transformation functions. Translation To translate an SVG element, you can use the translate() function. The syntax for the translation function is: The translate() function takes one or two values which specify the horizontal and vertical translation values, respectively. tx represents the translation value along the x-axis; ty represents the translation value along the y-axis. The ty value is optional; and, if omitted, it defaults to zero. The tx and ty values can be either space-separated or comma-separated, and they don’t take any units inside the function—they default to the current user coordinate system units. The following example translates an element by 100 user units to the right, and 300 user units to the bottom: The above example is still valid if the transformation was applied using translate(100, 300) where the values are comma-separated. Scaling You can resize an SVG element by scaling it up or down using the scale() function transformation. The syntax for the scale transformation is: The scale() function takes one or two values which specify the horizontal and vertical scaling values, respectively. sx represents the scaling value along the x-axis, used to stretch or shrink the element horizontally; sy represents the scaling value along the y-axis, used to stretch or shrink the element vertically. The sy value is optional; and, if omitted, it is assumed to be equal to sx. The sx and sy values can be either space-separated or comma-separated, and they are unitless numbers. The following example doubles the size of an element by scaling it to twice its original size: The following stretches an element horizontally to 1.5 its original width, and shrinks it vertically to half its original height: The above example is still valid if the transformation was applied using scale(2, .5) where the values are comma-separated. It is important to note here that when an SVG element is scaled, its entire current coordinate system is scaled, resulting in the element also being repositioned inside the viewport. Don’t worry about this now, we’ll get into it in more detail in the next section. Skew An SVG element can also be skewed. To skew it, you can use one or both of the two skew transformation functions: skewX and skewY. The skewX function specifies a skew transformation along the x-axis; and the skewY function specifies a skew transformation along the y-axis. The skew angle specified is a unitless angle that defaults to degrees. Note that skewing an element may result in the element being repositioned inside the viewport. More about this in the next section. Rotation You can rotate an SVG element using the rotate() function. The syntax for the function is: The rotate() function specifies a rotation by rotate-angle degrees about a given point. Unlike rotation transformations in CSS, you cannot specify an angle unit other than degrees. The angle value is specified unitless, and is considered a degrees value by default. The optional cx and cy values represent the unitless coordinates of the point used as a center of rotation. If cx and cy are not provided, the rotation is about the origin of the current user coordinate system. (See Part 1 if you’re not sure what a user coordinate system is.) Specifying a center of rotation inside the rotate() function is like a shorthand way for setting transform: rotate() and transform-origin in CSS. Since the default center of rotation in SVG is the upper left corner of the current user coordinate system in use, and since that may not allow you to create the rotation effect you want, you will probably end up specifying a new center inside rotate(). If you know your element’s dimensions and position in the SVG canvas, you can easily specify its center as the center of rotation. The following example rotates a group of elements around a specified center of rotation positioned at (50, 50) in the current user coordinate system: However, if you want an element to rotate around its center, you’d probably rather specify the center as 50% 50% like you would do in CSS; but unfortunately doing that inside the rotate() function is not possible—you need to use absolute coordinates. However, you can do this using the CSS transform-origin property in conjunction with the CSS transform property. More about this later in the article. Coordinate System Transformations Now that we’ve covered all possible SVG transformation functions, we’ll dig into the visual part and the effect of applying each transformation to an SVG element. This is the most important aspect of SVG transformations. And they are called “coordinate system transformations” not just “element transformations” for a reason. In the specification, the transform attribute is defined as being one of the two attributes that establish a new user space (current coordinate system) on the element it is applied to — the viewBox attribute is the second of the two attributes that create a new user space. So what exactly does this mean? transform attribute establishes a new user space (current coordinate system) on the element it is applied to. This behavior is similar to the behavior of CSS transformations applied to an HTML element—the HTML element’s coordinate system is transformed, and this is usually most obvious when you’re chaining tranformations (we’ll get to this later). Despite being similar in many aspects, HTML and SVG transformations have some differences. The main difference is the coordinate system. The coordinate system of an HTML element is established on the element itself. Meanwhile, in SVG, the coordinate system of an element is, initially, the current coordinate system or user space in use. When you apply the transform attribute to an SVG element, that element gets a “copy” of the current user coordinate system in use. You can think of it as just creating a new “layer” for the transformed element, where the new layer has its own copy of the current user coordinate system (the viewBox). Then, the element’s new current coordinate system is transformed by the transformation functions specified inside the transform attribute, thus resulting in the transformation of the element itself. It is as if the elements are drawn onto the canvas in the transformed coordinate system. To understand how SVG transformations are applied, let’s start with the visual part. The following image shows the SVG canvas we’re going to be working with. The parrot and the dog are the elements (groups <g>) that we’re going to be transforming. The grey coordinate system is the initial coordinate system of the canvas established by the viewBox. For simplicity’s sake, I’m going to not change the initial coordinate system—I’m using a viewBox that is the same size as the viewport, as you see in the above code. transform attribute to an SVG element, that element gets a "copy" of the current user coordinate system in use. Now that we’ve established our canvas and an initial user space, we’re going to start transforming elements. Let’s start by translating the parrot by 150 units to the left and 200 units downwards. The parrot is, of course, made of several paths and shapes. It’s enough to apply the transform attribute to the group wrapping these shapes <g>; this will in turn apply the transformation to the entire set of shapes and paths, and the parrot will be translated as one whole item. See the article on structuring and grouping SVGs for more information. The following image shows the result of translating the parrot by the above translation. The translucent version of the parrot shows the initial position before the transformation was applied. The translation transformation in SVG is as simple and straightforward as it is in CSS when applied on an HTML element. We mentioned earlier that applying the transform attribute to an element establishes a new current user coordinate system on it. The following image shows the “copy” of the initial coordinate system, that is established on the parrot element when it was transformed. Notice how the parrot’s current coordinate system is translated. It’s important to notice here that the new current coordinate system established on the element is a replicate of the initial user space, with the position of the element preserved inside it. This means that it is not established on the element’s bounding box, nor is the size of the new current coordinate system restricted to the size of the element. This is where the difference between HTML and SVG coordinate system shines. not established on the element's bounding box, nor is its size restricted to the size of the element. This is more evident if we are to transform the dog at the bottom right of the canvas. Suppose we want to translate the dog by 50 units to the right and then 50 units downwards. This is how the dog, its initial position, and the new current coordinate system (that is also translated with the dog) will look. Notice how the origin of the dog’s new current coordinate system is not positioned at the top left cornder of the dog’s bounding box. Also notice how the dog and its new coordinate system seem as if they were moved to a new “layer” on top of the canvas. Now let’s try something else. Instead of translating the parrot, let’s try scaling it. We’re going to scale the parrot to double its size: The result of scaling an SVG element differs from that of scaling an HTML element. The scaled SVG’s element’s position changes inside the viewport when it is scaled. The following image shows the result of doubling the size of the parrot. Notice the initial position and size, and the final size and position. What we can notice from the above image is that not only the size (width and height) of the parrot were doubled, but the coordinates (x and y) were also multiplied by the scaling factor (which is two, here). The reason we ended up with this result is something we’ve mentioned earlier: the element’s current coordinate system is transformed, and then the parrot is drawn into the new system. So, in this example, the current coordinate system was scaled. This effect is similar to the effect of using viewBox = "0 0 400 300", which “zooms in” to the coordinate system, thus doubling the size of the content inside it (see part 1 of the series if you haven’t already). So, if we were to visualize the coordinate system transformation showing the current transformed system of the parrot, we’d get the following result: The new current coordinate system of the parrot is scaled up, “zooming in” to the parrot at the same time. Notice that, inside its current coordinate system, the parrot is not repositioned—it is only the effect of scaling the coordinate system that repositions it inside the viewport. The parrot is simply drawn at its original x and y coordinates inside the new scaled up system. Let’s trying scaling the parrot in both directions using different scaling factors. If we scale the parrot by applying transform="scale(2 0.5), we’re doubling its width while making it half its original height. The effect will be similar to applying viewBox="0 0 400 1200". Notice the position of the parrot inside the scaled coordinate system, and compare it to the position in the initial system (translucent parrot): the x and y position coordinates are preserved. Skewing an element in SVG also results in the element being “moved” as a result of its current coordinate system being skewed. Suppose we apply a skew transformation to the dog along the x-axis using the skewX function. We’re going to skew the dog by 25 degrees horizontally. The following image shows the result of applying the skewing transformation to the dog. Its coordinate system is skewed, and so is the dog itself. Note that the position of the dog with respect to its original position also changes, as a result of skewing its coordinate system. The following image shows the result of skewing the dog by the same angle using skewY() instead of skewX: And last but not least, let’s try rotating the parrot. The default center of rotation is the upper left corner of the current user coordinate system. The new current system established on the rotated element will also be rotated. In the following example, we’re going to rotate the parrot by 45 degrees. The positive direction of rotation is clockwise. The result of applying the above transformation looks like this: You are probably going to want to rotate an element around a point other than the default origin of the coordinate system. Using the rotate() function in the transform attribute, you can specify that point explicitly. Suppose we want to rotate the parrot in this example around its own center. According to the width, height, and position of the parrot, I can determine its center to be at approximately (150, 170). The parrot can then be rotated around this point: At this point, the parrot is rotated and will look like so: We said that the transformations are applied to the coordinate system, and because of that, the element is eventually affected and transformed. So how exactly does changing the center of rotation work on the coordinate system whose origin is at the point (0, 0)? When you change the center or rotation, the coordinate system is translated, rotated by the specified angle, and then translated again by specific values depending on the center of rotation you specify. In this example, this: is performed by the browser as a series of translation and rotation operations equivalent to: The current coordinate system is translated to the point you want to be the center. It is then rotated by the angle you specify. And then finally the system is translated by the negation of the values. The above transformation applied on the system looks like this: Before we move on to the next section where we’re going to nest and chain transformations, I want to note that the current user coordinate system established on a transformed element is independent from other coordinate systems established on other transformed elements. The following image shows the two coordinate systems established on the dog and the parrot, and how they are independent from each other. Also note that each current coordinate system still lies inside the main coordinate system of the canvas established using the viewBox attribute on the containing <svg>. Any transformations applied to the viewBox will affect the entire canvas and all elements inside it as well, whether they have their own established coordinate systems or not. For example, the following is the result of changing the user space of the entire canvas from viewBox="0 0 800 600" to viewBox="0 0 600 450". The entire canvas is scaled up, preserving any transformations applied to the individual elements. Nested and Chained Transformations A lot of times you may want to apply several transformations to an element. Applying multiple transformations in a raw is what is referred to as “chaining” transformations. When transformations are chained, the most important thing to be aware of is that, just like with HTML element transformations, each transformation is applied to the coordinate system after that system is transformed by the previous transformations. For example, if you’re going to apply a rotation to an element, followed by a translation, the translation happens according to the new coordinate system, not the inital non-rotated one. The following example does just that. We’re applying the previous rotation, and then translating the parrot using by 200 units along the positive x-axistransform="rotate(45 150 170) translate(200)". Depending on the final position and transformation you’re after, you need to chain your transformations accordingly. Always keep the coordinate system in mind. Note that when you skew an element—and its coordinate system with it—the coordinate system will no longer be an orthogonal one, and the coordinates will no longer be calculated as orthogonal ones—they will be skew coordinates. Simply put, this just means that the coordinate system’s origin is no longer a 90 degrees angle, and hence the new coordinates will be computed based on this new angle. Nested transformations occur when a child of a transformed element is also transformed. The transformation applied to the child element will be an accumulation of the transformations applied on its ancestors and the transformation applied on it. So, in effect, nesting transforms is similar to chaining them; only difference is that instead of applying a series of transformations on one element, it automatically gets the transformations applied on its acestors, and then finally its own transformations are applied to it, just like we applied transformations in the chain above—one after the other. This is particularly useful for when you want to transform one element relative to another. For example, suppose you want to animate the tail of the dog. The tail is a descendant of the #dog group. Suppose we translate the dog group; then rotate its body by some angle around some point, and then we want to animate the tail by rotating it and animating that rotation. When the tail is to be rotated, it “inherits” the transformed coordinate system of its ancestor (#body), which in turn inherits the transformed coordinate system of its transformed ancestor (#dog) as well. So, in effect, when the taill is rotated, it is as though it has been translated (by the same translation of the #dog group), then rotated (by the same rotation of the #body group), and then rotated by its own rotation. And the effect of applying a series of transformations here is the same as we explained in the chaining example above. So, you see, nesting transformations has practically the same effect as chaining them on the #tail. Transforming SVGs using CSS Properties In SVG 2, the transform attribute is referred to as the transform property; this is because SVG transformations have been “exported” into the CSS3 Transforms specification. The latter combines the SVG Transforms, CSS 2D Transforms, and CSS 3D Transforms specifications, and introduces features like transform-origin and 3D transformations into SVG. The CSS transform properties specified in the CSS Transforms specifications can be applied to SVG elements. However, the values for the transform property functions need to follow the syntax specified in the CSS spec: function arguments must be separated with commas — space-separation alone isn’t valid, but you can include one or more white space before and/or after the comma; and the rotate() function does not take <cx> <cy> values anymore — the center of rotation is specified using the transform-origin property. Also, the CSS transformatio functions do accept units for angles and coordinates, such as rad (radians) for angles (among others) and px, em, etc. for coordinate values. An example of rotating an SVG element using CSS may look like the following: And SVG element can also be transformed in three-dimensional space using CSS 3D Transforms. Note that the coordinate systems are still, however, different from the coordinate systems established on HTML elements. This means that 3D rotations will also look different unless you change the center of rotation. Because transforming SVG elements with CSS is pretty much the same as transforming HTML elements with CSS—syntax-wise—I’m going to skip elaborating on this topic in this article. That said, at the time of writing of this article, implementations are still incomplete in some browsers and for some features. Because of how fast browser support changes, I recommend you experiment with the properties to determine what currently works and what doesn’t, and decide on what you can start using today and what not. Note that once CSS Transforms are fully implemented for SVG elements, it is recommended that you use the CSS transforms function syntax even when you apply the transformation in the form of a transform attribute. That said, the above mentioned syntax of the transform attribute functions will still be valid. Animating transform SVG transformations can be animated, just like CSS transforms can be. If you’re using the CSS transform property to transform the SVG, you can animate the transformation using CSS animations and transitions just like you would animate CSS transforms on HTML elements. The SVG transform attribute can be animated using the SVG <animateTransform> element. The <animateTransform> element is one of three elements in SVG that are used to animate different SVG attributes. Details of the <animateTransform> element are outside the scope of this article. Stay tuned for an article I’ll be writing about the different SVG animation elements, including <animateTransform>. Final Words Working with SVGs can be really frustrating at first, if the concepts behind the coordinate system transformations aren’t very clear, especially if you’re coming from a CSS HTML transformations background, and naturally expect SVG elements to respond the same way to transformations as HTML elements do. However, once you get a grip of how they work, you gain a better control over your SVG canvas, and can manipulate elements more easily. In the last part of this series, I’m going to go over nesting SVGs and establishing new viewports and viewboxes. Stay tuned! Freepik.com. I hope you liked this article and found it useful. Thank you for reading!

Understanding SVG Coordinate Systems and Transformations (Part 1) — The viewport, viewBox, and preserveAspectRatio

SVG elements aren't governed by a CSS box model like HTML elements are. This makes positioning and transforming these elements trickier and may seem—at first glance—less intuitive. However, once you understand how SVG coordinate systems and transformations work, manipulating SVGs becomes a lot easier and makes a lot more sense. In this article we're going to go over three of the most important SVG attributes that control SVG coordinate systems: viewport, viewBox, and preserveAspectRatio. This is the first in a series of three articles covering the topic of coordinate systems and transformations in SVG. Understanding SVG Coordinate Systems & Transformations (Part 1) – The viewport, viewBox, & preserveAspectRatio Understanding SVG Coordinate Systems & Transformations (Part 2) – The transform Attribute Understanding SVG Coordinate Systems & Transformations (Part 3) – Establishing New Viewports For the sake of visualizing the concepts and explanations in the article even further, I created an interactive demo that allows you to play with the values of the viewBox and preserveAspectRatio attributes. Check the interactive demo out. The demo is the cherry on top of the cake, so do make sure you come back to read the article if you check it out before you do! The SVG Canvas The canvas is the space or area where the SVG content is drawn. Conceptually, this canvas is infinite in both dimensions. The SVG can therefore be of any size. However, it is rendered on the screen relative to a finite region known as the viewport. Areas of the SVG that lie beyond the boundaries of the viewport are clipped off and not visible. The viewport The viewport is the viewing area where the SVG will be visible. You can think of the viewport as a window through which you can see a particular scene. The scene may be entirely or partially visible through that window. The SVG viewport is similar to the viewport of the browser you’re viewing this page through. A web page can be of any size; it can be wider than the viewport’s width, and is in most cases also longer than the viewport’s length. However, only portions of a web page are visible through the viewport at a time. Whether or not the entire SVG canvas or part of it is visible depends on the size of that canvas* and the value of the preserveAspectRatio attribute. You don't have to worry about these now; we'll talk about them further in more detail. You specify the size of the viewport using the width and height attributes on the outermost <svg> element. In SVG, values can be set with or without a unit identifier. A unitless value is said to be specified in user space using user units. If a value is specified in user units, then the value is assumed to be equivalent to the same number of “px” units. This means that the viewport in the above example will be rendered as a 800px by 600px viewport. You can also specify values using units. The supported length unit identifiers in SVG are: em, ex, px, pt, pc, cm, mm, in, and percentages. Once the width and height of the outermost SVG element are set, the browser establishes an initial viewport coordinate system and an initial user coordinate system. The initial coordinate system The initial viewport coordinate system is a coordinate system established on the viewport, with the origin at the top left corner of the viewport at point (0, 0), the positive x-axis pointing towards the right, the positive y-axis pointing down, and one unit in the initial coordinate system equals one “pixel” in the viewport. This coordinate system is similar to the coordinate system established on an HTML element with a CSS box model. The initial user coordinate system is the coordinate system established on the SVG canvas. This coordinate system is initially identical to the viewport coordinate system—it has its origin at the top left corner of the viewport with the positive x-axis pointing towards the right, the positive y-axis pointing down. Using the viewBox attribute, the initial user coordinate system—also known as the current coordinate system, or user space in use—can be modified so that it is not identical to the viewport coordinate system anymore. We’ll talk about modifying it in the next section. For now, we won’t specify a viewBox attribute value. The user coordinate system of the SVG canvas is identical to that of the viewport. In the following image, the viewport coordinate system “ruler” is grey, and that of the user coordinate system (the viewBox) is blue. Since they are both identical at this point, the two coordinate systems overlap. The parrot in the above SVG has a bounding box that is 200 units (200 pixels in this case) in width and 300 units in height. The parrot is drawn on the canvas based on the initial coordinate system. A new user space (i.e., a new current coordinate system) can also be established by specifying transformations using the transform attribute on a container element or graphics element. We'll talk about transformations in the second part of this article, and then in more details in the third and last part. The viewBox I like to think of the viewBox as the “real” coordinate system. After all, it is the coordinate system used to draw the SVG graphics onto the canvas. This coordinate system can be smaller or bigger than the viewport, and it can be fully or partially visible inside the viewport too. In the previous section, this coordinate system—the user coordinate system—was identical to the viewport coordinate system. The reason for that is that we did not specify it to be otherwise. That’s why all the positioning and drawing seemed to be done relative to the viewport coordinate system. Because once we created a viewport coordinate system (using width and height), the browser created a default user coordinate system that is identical to it. You specify your own user coordinate system using the viewBox attribute. If the user coordinate system you choose has the same aspect ratio (ratio of height to width) as the viewport coordinate system, it will stretch to fill the viewport area (we’ll talk examples in a minute). However, if your user coordinate system does not have the same aspect ratio, you can use the preserveAspectRatio attribute to specify whether or not the entire system will be visible inside the viewport or not, and you can also use it to specify how it is positioned inside the viewport. We’ll get into details and lots of examples for this case in the next section. In this section, we’ll stick to examples where the aspect ratio of the viewBox matches that of the viewport—in these examples, preserveAspectRatio has no effect. Before we get into the examples, we’ll go over the syntax of viewBox. The viewBox syntax The viewBox attribute takes four parameters as a value: <min-x>, <min-y>, width and height. The <min-x> and <min-y> values determine the upper left corner of the viewbox, and the width and height determine the width and height of that viewBox. Note here that the width and height of the viewBox need not be the same as the width and height set on the parent <svg> element. A negative value for <width> or <height> is invalid. A value of zero disables rendering of the element. width: 100% will make the SVG viewport fluid in a document. Whatever value of the viewBox, it will then be mapped to the computed width of the outer SVG element. An example of setting viewBox would look like the following: If you’ve read about the viewBox somewhere before, you may have come across a few definitions saying that you can use the viewBox attribute to transform the SVG graphic by scaling or translating it. This is true. I’m going to go further and say that you can even crop the SVG graphic using viewBox. The best way to understand the viewBox and differentiate it from the viewport is by visualizing it. So let’s start with some examples. We’ll start with examples where the aspect ratio of the viewbox is the same as the aspect ratio of the viewport, so we won’t need to dig into preserveAspectRatio yet. viewBox with aspect ratio equal to the viewport's aspect ratio We’ll start with a simple example. The viewbox in this example will be half the size of the viewport. We won’t change the origin of the viewbox in this one, so both <min-x> and <min-y> will be set to zero. The width and height of the viewbox will be half the width and height of the viewport. This means that we’re preserving the aspect ratio. So, what does viewbox="0 0 400 300" exactly do? It specifies a specific region of the canvas spanning from a top left point at (0, 0) to a point at (400, 300). The SVG graphic is then cropped to that region. The region is scaled up (in a zoom-in-like effect) to fill the entire viewport. The user coordinate system is mapped to the viewport coordinate system so that—in this case—one user unit is equal to two viewport units. The following image shows the result of applying the above viewbox to the <svg> canvas in our example. The grey units represent the viewport coordinate system, and the blue coordinate system represents the user coordinate system established by the viewBox. Anything you draw on the SVG canvas will be drawn relative to the new user coordinate system. I like to visualize the SVG canvas with a viewBox the same way as Google maps. You can zoom in to a specific region or area in Google maps; that area will be the only area visible, scaled up, inside the viewport of the browser. However, you know that the rest of the map is still there, but it's not visible because it extends beyond the boundaries of the viewport—it's being clipped out. Now let’s try changing the <min-x> and <min-y> values. We’ll set both to 100. They can be any number you want. The width and height ratio will also be the same as width and height ratio of the viewport. The effect of applying viewBox="100 100 200 150" is also a crop effect like the one in the previous example. The graphic is cropped and scaled up to fill the entire viewport area. Again, the user coordinate system is mapped to the viewport coordinate system—200 user units are mapped to 800 viewport units so that every user unit is equal to four viewport units. This results in a zoom-in effect like the one you can see in the above screenshot. Also note, at this point, that specifying non-zero values for the <min-x> and <min-y> values has a transformation effect on the graphic; more specifically, it is as though the SVG canvas was translated by 100 units to the top and 100 units to the left (transform="translate(-100 -100)"). Indeed, as the specification states, the effect of the viewBox attribute is that the user agent automatically supplies the appropriate transformation matrix to map the specified rectangle in user space to the bounds of a designated region (often, the viewport). This is just a fancy way of saying what we already mentioned before: the graphic is cropped and then scaled to fit into the viewport. The spec then goes on to add a note: in some cases the user agent will need to supply a translate transformation in addition to a scale transformation. For example, on an outermost svg element, a translate transformation will be needed if the viewBox attributes specifies values other than zero for <min-x> or <min-y>.) To demonstrate the translation transformation even better, let’s try applying negative values (-100) to <min-x> and <min-y>. The translation effect would be then similar to transform="translate(100 100)"; meaning that the graphic will be translated to the bottom and to the right after being cropped and scaled. If were to revisit the second to last example with a crop size of 400 by 300, and then add the new negative <min-x> and <min-y> values, this would be our new code: The result of applying the above viewBox transformation to the graphic is shown in the following image: </figcaption> Note that, unlike the transform attribute, the automatic transformation that is created due to a viewBox does not affect the x, y, width and height attributes on the element with the viewBox attribute. Thus, in the example above which shows an svg element which has attributes width, height and viewBox, the width and height attributes represent values in the coordinate system that exists before the viewBox transformation is applied. You can see this in the above examples as the initial (grey) viewport coordinate system remains unaffected even after using the viewBox attribute on the <svg>. On the other hand, like the transform attribute, it does establish a new coordinate system for all other attributes and for descendant elements. You can also see that in the above examples as the user coordinate system established is a new one—it does not remain as the initial user coordinate system which was identical to the viewport coordinate system before the viewBox was used. And any descendants of the <svg> will be positioned and sized in the new user coordinate system, not the initial one. Our last viewBox example is similar to the previous ones, but instead of cropping the canvas, we’re going to extend it inside the viewport and see how it affects the graphic. We’re going to specify a viewbox with a width and height that are larger than those of the viewport, while also maintaining the aspect ratio of the viewport. We’ll deal with different aspect ratios in the next section. In this example, we’ll make the viewbox 1.5 times the size of the viewport. What will happen now is that the user coordinate system is going to be scaled up to 1200x900. It will then be mapped to the viewport coordinate system so that every 1 unit in the user coordinate system is equal to viewport-width / viewBox-width horizontally, and viewport-height / viewBox-height units vertically in the viewport coordinate system. This means that, in this case, every one x-unit in the user coordinate system is equal to 0.66 x-units in the viewport coordinate system, and every one user y-unit is mapped to 0.66 viewport y-units. Of course, the best way to understand this is to visualize the result. The viewbox is scaled so that it fits inside the viewport as shown in the following image. And because the graphic is drawn on the canvas based on the new user coordinate system, not the viewport coordinate system, it will look smaller inside the viewport. viewBox. So far, all of our examples have been in conformity with the viewport’s height to width aspect ratio. But what happens if the height and width specified in the viewBox have a different aspect ratio than that of the viewport’s? For example, suppose we set the dimensions of the viewbox to be 1000x500. The aspect ratio of height to width is no longer the same as that of the viewport. The result of using viewBox = "0 0 1000 500" in our example looks like the following: The user coordinate system and hence the graphic is positioned inside the viewport so that: The entire viewbox fits inside the viewport. The aspect ratio of the viewbox is preserved. The viewbox was not stretched to cover the viewport area. THe viewbox is centered inside the viewport both vertically and horizontally. This is the default behavior. What controls this behavior? And what if we want to change the position of the viewbox inside the viewport? This is where the preserveAspectRatio attribute comes in. The preserveAspectRatio Attribute The preserveAspectRatio attribute is used to force a uniform scaling for the purposes of preserving the aspect ratio of a graphic. If you define a user coordinate system with an aspect ratio different from that of the viewport’s, and if the browser were to stretch the viewbox to fit into the viewport as we’ve seen in previous examples, the difference in aspect ratios will cause the graphic to be distorted in either direction. So if the viewbox in the last example were to be stretched to fill the viewport in both directions, the graphic would look like so: The distortion is also clearly visible (and unwanted, of course) when using a viewbox value of 0 0 200 300, which would be smaller than the dimensions of the viewport. I chose this value in particular so that the viewbox matches the size of the bounding box of the parrot. If the browser were to stretch the graphic to fill the entire viewport, it would look like the so: The preserveAspectRatio attribute allows you to force uniform scaling of the viewbox, while maintaining the aspect ratio, and it allows you to specify how to position the viewbox inside the viewport if you don’t want it to be centered by default. The preserveAspectRatio syntax The official syntax for preserveAspectRatio is: It is usable on any element that establishes a new viewport (we’ll get into these in the next parts of the series). The defer argument is optional, and is used only when you’re applying preserveAspectRatio to an <image>. It is ignored when used on any other element. Since <image> it outside the scope of this article, we’ll skip the defer option for now. The align parameter indicates whether to force uniform scaling and, if so, the alignment method to use in case the aspect ratio of the viewBox doesn’t match the aspect ratio of the viewport. If the align value is set to none, for example: The graphic will be scaled to fit inside the viewport without maintaining the aspect ratio, just like we saw in the last two examples. All other values of preserveAspectRatio force uniform scaling while preserving the viewbox’s aspect ratio, and specify how to align the viewbox inside the viewport. We’ll get into the values of align shortly. The last argument, meetOrSlice is also optional, and it defaults to meet. This argument specifies whether or not the entire viewBox should be visible inside the viewport. If provided, it is separated from the align parameter by one or more spaces. For example: These values may seem foreign at first. To make understanding them easier and make them more familiar, you can think of the meetOrSlice value as being similar to the background-size values contain and cover; they work pretty much the same. meet is similar to contain, and slice is similar to cover. Here are the definitions and meaning of each value: meet (The default value) Scale the graphic as much as possible while maintaining the following two criteria: aspect ratio is preserved the entire viewBox is visible within the viewport viewBox (i.e., the area into which the viewBox will draw will be smaller than the viewport). (See the last example of The viewBox section.) In this case, the boundaries of the `viewBox` are contained inside the viewport such that the boundaries *meet*. background-size: contain. The background image is scaled as much as possible while preserving its aspect ratio and making sure it fits entirely into the background painting area. If the aspect ratio of the background is not the same as that of the element it is being applied to, parts of the background painting area will not be covered by the background image. slice Scale the graphic so that the viewBox covers the entire viewport area, while maintaining its aspect ratio. The viewBox is scaled just enough to cover the viewport area (in both dimensions), but it is not scaled any more than needed to achieve that. In other words, it is scaled to the smallest size such that the width and height of the viewBox can completely cover the viewport. viewBox does not match the viewport, some of the viewBox will extend beyond the bounds of the viewport (i.e., the area into which the viewBox will draw is larger than the viewport). This will result in part of the `viewBox` being *sliced off*. background-size: cover. In the case of a background image, the image is scaled while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area. So, meetOrSlice is used to specify whether or not the viewBox will be completely contained inside the viewport, or if it should be scaled as much as needed to cover the entire viewport, even if this means that a part of the viewbox will be “sliced off”. For example, if we were to apply viewBox size of 200x300, and using both the meet and slice values, keeping the align value set to the default by the browser, the result for each value will look like the following: meet parameter vs the slice parameter on a viewBox with an aspect ratio different from that of the viewport's aspect ratio. align is xMidYMid, so, in both cases, the graphic is scaled so that its mid axes align with the mid axes of the viewport. The align parameter takes one of nine values, or the none value. Any value other than none is used to uniformly scale the image preserving its aspect ratio, and it is also used to align the viewBox inside the viewport. The align values works similar to the way background-position works when used with percentage values. You can think of the viewBox as being the background image. The way the positioning with align differs from background-position is that instead of positioning a specific point of the viewbox over a corresponding point of the viewport, it aligns specific “axes” of the viewBox with corresponding “axes” of the viewport. In order to understand the meaning of each of the align values, we’re going to first introduce each of the “axes”. Remember the <min-x> and <min-y> values of the viewBox? We’re going to use each of these to define the “min-x” axis and “min-y” axis on the viewBox. Additionally, we’re going to define two axes “max-x” and “max-y”, which will be positioned at <min-x> + <width> and <min-y> + <height>, respectively. And last but not least, we’ll define two axes “mid-x” and “mid-y”, which are positioned at <min-x> + (<width>/2) and <min-y> + (<height>/2), respectively. Did that make things more confusing? If so, have a look at the following image to see what each of those axes represents. In the image, both <min-x> and <min-y> are set to their default 0 values. The viewBox is set to viewBox = "0 0 300 300". The dashed grey lines in the above image represent the mid-x and mid-y axes of the viewport. We’re going to use those to align the mid-x and mid-y of axes of the viewBox for some values. For the viewport, the min-x value is equal to 0, the min-y value is also 0, the max-x value is equal to the width of the viewBox, the max-y value is equal to its height, and the mid-x and mid-y represent the middle values of the width and height, respectively. The alignment values are: none Do not force uniform scaling. Scale the graphic content of the given element non-uniformly (without preserving aspect ratio) if necessary such that the element's bounding box exactly matches the viewport rectangle. viewBox is stretched or shrunk as necssary so that it fills the entire viewport exactly, disregarding the aspect ratio. The graphic may be distorted. <align> is none, then the optional <meetOrSlice> value is ignored.) xMinYMin Force uniform scaling. <min-x> of the element's viewBox with the smallest X value of the viewport. <min-y> of the element's viewBox with the smallest Y value of the viewport. background-position: 0% 0%;. xMinYMid Force uniform scaling. <min-x> of the element's viewBox with the smallest X value of the viewport. viewBox with the midpoint Y value of the viewport. background-position: 0% 50%;. xMinYMax Force uniform scaling. <min-x> of the element's viewBox with the smallest X value of the viewport. <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. background-position: 0% 100%;. xMidYMin Force uniform scaling. viewBox with the midpoint X value of the viewport. <min-y> of the element's viewBox with the smallest Y value of the viewport. background-position: 50% 0%;. xMidYMid (The default value) Force uniform scaling. viewBox with the midpoint X value of the viewport. viewBox with the midpoint Y value of the viewport. background-position: 50% 50%;. xMidYMax Force uniform scaling. viewBox with the midpoint X value of the viewport. <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. background-position: 50% 100%;. xMaxYMin Force uniform scaling. <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. <min-y> of the element's viewBox with the smallest Y value of the viewport. background-position: 100% 0%;. xMaxYMid Force uniform scaling. <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. viewBox with the midpoint Y value of the viewport. background-position: 100% 50%;. xMaxYMax Force uniform scaling. <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. background-position: 100% 100%;. So, using the align and meetOrSlice values of the preserveAspectRatio attribute, you can specify whether or not to scale the viewBox uniformly, how to align it inside the viewport, and whether or not it should be entirely visible inside the viewport. Sometimes, and depending on the size of the viewBox, some values may have similar results. For example, in the viewBox="0 0 200 300" example from earlier, some alignments are identical using different align values. The value of meetOrSlice is set to meet in this case so that the entire viewBox is contained inside the viewport. viewBox using different align values. The meetOrSlice value is set to meet. If we were to change the meetOrSlice value to slice, we’d get different results for different values. Notice how the viewBox is stretched so that it covers the entire viewport. The x-axis is stretched so that the 200 units cover the viewport’s 800 units. In order for this to happen, and to maintain the aspect ratio of the viewbox, the y-axis gets “sliced off” at the bottom, but you can image it extending below the viewport’s height. viewBox using different align values. The meetOrSlice value is set to slice. Of course, different viewBox values will also look different from the 200x300 we’re using here. For the sake of brevity, I won’t get into more examples, and I’ll leave you to play with an interactive demo I created to help you better visualize how the viewBox and different preserveAspectRatio values work together when different values are used. You can check the interactive demo out by visiting the link in the next section. But before we move to that, I just want to note that the mid-x, mid-y, max-x, and max-y values change if the values of the <min-x> and <min-y> change. You can play with the interactive demo and change these values to see how the axes and thus the alignment of the viewBox changes accordingly. The following image shows the effect of using viewBox = "100 0 200 300" on the position of the alignment axes. We’re using the same example as earlier, but instead of having the <min-x> value be set to zero, we’re setting it to 100. You can set them to any number value you want. Notice how the min-x, mid-x, and max-x axes change. The preserveAspectRatio used here is the default xMidYMid meet, which means that the mid-* axes are aligned with the middle axes of the viewport. <min-x> on the position of the x-axes. The translucent blue area shows the area which is considered to be the viewBox area after changing the value of <min-x>. The Interactive Demo The best way to understand how the viewport, viewBox, and different preserveAspectRatio values work and interact together is by visualizing them. For that purpose, I created a simple interactive demo that allows you to change the values of these attributes and see the result of the new values live. Check the interactive demo out. I hope you found this article useful in understanding the SVG viewport, viewBox, and preserveAspectRatio concepts. If you’d like to learn more about SVG coordinate systems, like nesting coordinate systems, establishing new ones, and transformations in SVG, stay tuned for the remaining parts of this series. You can subscribe to the RSS (link below) or follow me on Twitter to stay updated. Thank you very much for reading! Freepik.com. If you enjoyed this article you may also be interested in: Structuring, Grouping, and Referencing in SVG – The <g>, <use>, <defs> and <symbol> Elements Clipping in CSS and SVG – The clip-path Property and <clipPath> Element

Clipping in CSS and SVG — The clip-path Property and Element

CSS and SVG have a lot in common. A lot of the features that we have in CSS today were imported from SVG. One of these features is the Clipping operation. Both CSS and SVG allow us to "clip" elements into custom non-rectangular shapes. In this article we will go over the clipping techniques in both CSS and SVG, covering everything you need to know to get started. this compatibility table out for more information. You don't need to view the live demos to follow up with the article. Not all clipping features are implemented and some features may be buggy. The purpose of this article is to go over how clipping works in CSS and SVG, and serves as a reference for when these features are fully implemented. I'm also not including any vendor prefixes in the code samples here, but they are included in the live demos. What is clipping? Clipping is a graphical operation that allows you to fully or partially hide portions of an element. The clipped element can be any container or graphics element. The portions of the element that are shown or hidden are determined by a clipping path. A clipping path defines a region where everything on the “inside” of this region is allowed to show through but everything on the outside is “clipped out” and does not appear on the canvas. This region is known as the clipping region. Any parts of the element that lie outside of a clipping region are not drawn. This includes any content, background, borders, text decoration, outline and visible scrolling mechanism of the element to which the clipping path is applied, and those of its descendants. A clipping path is conceptually equivalent to a custom viewport for the element it applies to. It influences what parts of the element are rendered on the screen, but it does not affect the element’s inherent geometry—the element will affect the flow around it as it normally would, and every other element on the page will still see and treat the element as if it were still rectangular, even if it’s clipped to a non-rectangular shape. If you want to change the way the content around the element flows and have it respond to the defined shape of the clip path, you can use the CSS Shapes properties. If you want to learn more about how to do that, you can check the articles I wrote about this topic. Clipping in CSS – The clip-path Property The clip-path property is part of the CSS Masking Module. The clipping operation has been a part of SVG since 2000, and has moved into the CSS Masking module so that it now allows clipping HTML elements as well as SVG elements. The clip-path property is used to specify a clipping path that is to be applied to an element. Using clip-path, you can apply an SVG <clipPath> to an element by referencing that path in the property value. You can also define a clipping path using one of the basic shapes defined in the CSS Shapes module. These shapes can be created using shape functions. The shape functions available are polygon(), circle(), inset() (used to define inset rectangles), and ellipse(). Applying a clipping path to an element using the clip-path property is very simple and straightforward: For example, if we were to define a polygonal clipping path using the polygon() function, and then apply it to an image, the code would look like the following: The result of applying the above line of CSS to an image would look like the following: View Live Demo The basic shape functions allow us to create a limited number of shapes; the most complex of these shapes is a polygon. If you want to use a more complex shape that looks like more than just a group of connected straight lines, you can use the SVG <clipPath> element. As the name <clipPath> implies, you can clip to any arbitrary path. This means that you can use the <path> element to create any arbitrary path and use that as a clipping path. In our second example, we’re going to define and use an SVG clipPath. The code for the clip path looks like the following: And this is how the clipping path looks like; it is just a simple path with no fill and a black stroke. We’ll be talking more about SVG <clipPath> in the next section. But for now, we’re just going to reference it and apply it to the image we have. And the result would look like the following: View Live Demo Indeed, the <clipPath> element can contain any number of basic shapes (<rect>, <circle>, etc.), <path> elements, or even <text> elements. If you specify a piece of <text> inside a <clipPath>, that text will be used as a clipping path. Whatever’s under the text will be visible “through” it, and anything outside the text area will not be rendered. Note here that you can clip anything to the text. This opens a door for a lot of possibilities and effects. You can use animated images (such as GIFs) or even videos, and then clip them to some text of your choice. The sky is the limit here. The following is an example of a piece of text used as a clipping path. The cool thing about SVG <text> is that it can be displayed using a custom font, just like HTML text can. In this example I’m using the Vollkorn font from Google Web Fonts. I’ve set the width of the text to be the same as the width of the image, using the textLength attribute, and positioned the text using the x and y coordinates. Note here that the x and y coordinates determine the position of the bottom left corner of the text (where the bottom stands for the baseline of the text). The result of applying the above text clip path to the image looks like so: View Live Demo And as we mentioned, you can also use multiple basic shapes inside <clipPath>. We’ll dig into <clipPath> and its contents in the next section, so, for now, we’ll keep it simple. In this example I’m using multiple <circle>s, each with a different size and position. The image will show through these circles combined, but will not be rendered outside them. View Live Demo As we mentioned at the beginning of this article, you can apply clip paths using the clip-path property to SVG elements too. In all of the above examples, the clipping paths were applied to an HTML <img>. In the following example, a clipping path is applied to the root <svg> element. The same cherry blossoms image we used above is now part of the SVG, referenced using the <image> element. The <image> element in SVG is used to include a graphic that can be either an entire SVG or a raster image. If it’s an SVG you’re referencing in <image>, the width and height attributes will be used to establish the viewport of that SVG. If you’re referencing a raster image (which is what we’re doing here), the image will be scaled to fit in the specified width and height. So I made sure the aspect ratio of the width and height attribute match the aspect ratio of the image I’m using, to prevent it from being distorted. When you create an <svg> document, you establish its viewport by specifying the width and height of the <svg> element. Anything drawn outside the limits of the viewport will be clipped out and will not be displayed. You can establish a new custom viewport of your own with the <clipPath> element. Using clip-path, we’re going to apply the clipPath to the <svg>: View Live Demo More examples applying a clipping path to an SVG element in the <clipPath> section below. A Clipping Path's Reference Box In addition to the clipping path itself, you can define a reference box in the clip-path property when the clipping path applied is a <basic-shape>; that is, a clipping path created using one of the basic shape functions. The reference box is hence only specified for CSS shapes used as clip paths, not for SVG <clipPath>s. For an SVG <clipPath>, the reference box is the border box of an HTML element. So a reference box is specified for a <basic-shape> clip path. If the element being clipped is an HTML element, the reference box can be one of the four basic box model boxes: margin-box, border-box, padding-box, or content-box. Each of these is self-explanatory. If the <basic-shape> clip path is applied to an SVG element, the reference box can be set to one of three keyword values: fill-box – uses the object bounding box as the reference. stroke-box – uses the stroke bounding box as the reference. view-box – uses the uses the nearest SVG viewport as the reference box if no viewBox is specified. If a viewBox is indeed specified, then the coordinate system is established by the origin and dimensions specified by the viewBox. If you set any of the CSS box model boxes as a reference box for an SVG element, the fill-box will be used. And if you use one of the SVG reference boxes on an HTML element, the border-box will be used. If only a reference box is specified in the clip-path property—that is, no basic shape is defined—the browser uses the edges of the specified box, including any corner shaping (e.g. defined by the border-radius property), as clipping path. For example, using the following snippet, the element will be clipped to the rounded corners specified by border-radius: Note that at the time of writing of this article, specifying a reference box in the `clip-path` property doesn't work in Webkit because it's not yet implemented. clip-path Notes: Stacking Contexts, Pointer Events and Animations It is important to know that any value other than the default none for the clip-path property results in the creation of a stacking context on the element the same way the opacity property does. Furthermore, according to the Masking specification, pointer events must not be dispatched on the clipped-out (non-visible) regions of a shape. This means that the element should not respond to pointer events outside the remaining visible area. A clipping path can also be animated. If the clipping path used is an SVG <clipPath>, it can be animated by including an animation inside it (See next section for details). If the cipping path is a basic shape created using a basic shape function, it can be animated using CSS animations and transitions. For details on how to animate a shape created using a shape function, check out the Animating CSS Shapes with CSS Animations and Transitions article I wrote a while back. Clipping in SVG – The <clipPath> Element In SVG, the clipPath element is used to define a clipping path to clip elements. If you don’t want to use CSS to apply the clipping path to an element, you can do it in SVG using the clip-path presentation attribute. here. <svg> <defs> <clipPath id="myClippingPath"> <!-- ... --> </clipPath> </defs> <!-- the element you want to apply the clipPath to can be any SVG element --> <g id="my-graphic" clip-path="url(#myClippingPath)"> <!-- ... --> </g> </svg> Contents Of a <clipPath> We mentioned earlier that an SVG clipPath can contain any number of basic shapes, arbitrary <path>s, and/or <text> elements. It can even contain more than that, and this is where it can get interesting. The <clipPath> content can be descriptive (<title>, <desc>, <metadata>). It can also be a shape (<circle>, <ellipse>, <line>, <path>, <polygon>, <polyline>, <rect>) or a <text>. A <clipPath> can also contain a <use> element or a <script>. Note that <use> in <clipPath> can only reference the simple SVG shapes mentioned above—it cannot be used to reference groups inside <clipPath>, for example; that simply won’t work. And last but not least, a <clipPath> can contain an animation using <animate>, <animateColor>, <animateMotion>, <animateTransform>, or <set>. This opens a door for a lot of creativity, as you can imagine. To demonstrate, I’m just going to add a simple animation to the demo using multiple <circle>s as a clipping path. Every <circle> will get an animation. Because I want to keep it simple, I’m just gonna use the same animation on all of the circles. You can create fancier effects using different effects and playing with animation delays, of course. But, since this is a 101 article, I’m gonna stay on the simple side. The code with the animations look like so: The animation specified for each circle will animate the size of the circle—more specifically, its radius (r)—over the course of three seconds, from 0 to 250 pixels. I’ve also set the animation to repeat indefinitely. Click on the following button to view the live demo. But before you do, note that there is a bug (see bug details here), so the demo may not work for you if you’re on Chrome or Safari. For now, I recommend using Firefox to see the working live demo, until the bug has been fixed. View Animated clipPath Demo Live Note that the content of a <clipPath> also cannot involve groups (<g>s). For example, if we were to add a group element to the demo that uses multiple circles as a clipping path, the demo will no longer work—the clipping path will no longer be applied to the image. The clipPathUnits Attribute The <clipPath> element can have several attributes, including id, class, transforms, and presentation attributes like fill and stroke, among many others. But the one attribute that stands out, and that is particularly useful, is the clipPathUnits attribute. clipPathUnits attribute is used to specify a coordinate system for the contents of the <clipPath>. The clipPathUnits attribute is used to specify a coordinate system for the contents of the <clipPath>. It takes one of two values: objectBoundingBox or userSpaceOnUse. The default value is userSpaceOnUse. userSpaceOnUse The contents of the clipPath represent values in the current user coordinate system in place at the time when the clipPath element is referenced (i.e., the user coordinate system for the element referencing the clipPath element via the clip-path property). user coordinate system (a.k.a local coordinate system) is the coordinate system that is currently active and which is used to define how coordinates and lengths are located and computed. The user coordinate system for an HTML element with an associated CSS box model is different from that of an SVG element with no such box model. <clipPath> containing a <circle> whose center is positioned at cx = "100" and cy = "100", the center will be positioned 100 pixels to the left and 100 pixels down inside the boundaries of the reference box. nearest viewport. In most cases, the nearest viewport is the viewport established by the width and height of the closest <svg> ancestor. If you're not nesting <svg>s, it's simply the viewport you establish on the root <svg>. viewBox attribute, among other attributes which may contribute to changing the coordinate system. However, that's outside the scope of this article. So in this article I'm going to work under the assumption that no viewBox is modified, and hence the browser will use the default coordinate system with the origin at the top left corner, and dimensions equal to the dimensions of the <svg>. objectBoundingBox The coordinate system has its origin at the top left corner of the bounding box of the element to which the clipping path applies to and the same width and height of this bounding box. A bounding box is the object bounding box for all SVG elements (it contains only an element's geometric shape) and the border box for HTML elements with an associated box model. userSpaceOnUse versus objectBoundingBox. The grey border represents the border of the <svg> element where the viewport is set. For the image on the right, I've added a grey border around the clipped image just to show the boundaries of the bounding box. The result of applying the clipPath to an image inside the SVG canvas using userSpaceOnUse (left) and objectBoundingBox (right). objectBoundingBox, the bounding box of the image itself is used as the coordinate system of the clipping path. when you use the objectBoundingBox value, the coordinates specified for the contents of the <clipPath> must be in the range [0, 1]—the coordinate system becomes a unit system, and the coordinates of the shapes inside a clipPath have to be fractions in that range. objectBoundingBox value on the right, versus that used for the userSpaceOnuse on the left. <clipPath> Notes clipPath elements are never rendered directly; their only usage is as something that can be referenced using the clip-path property. The display property does not apply to the clipPath element; thus, clipPath elements are not directly rendered even if the display property is set to a value other than none, and clipPath elements are available for referencing even when the display property on the clipPath element or any of its ancestors is set to none. Remember what we said earlier about pointer events when an HTML element is clipped? The same standard behavior is defined in the SVG Clipping and Masking specification: By default, pointer-events must not be dispatched on the clipped (non-visible) regions of an SVG element. The spec then mentions that later versions of SVG may define new properties to enable fine-grained control over the interactions between hit testing and clipping. Firefox implements the same non-standard behavior we mentioned before—areas outside the clipping regions do not respond to pointer events. Even though Chrome implements the standard behavior for the clip-path property on HTML elements, when you apply a <clipPath> to an SVG element, the behavior is the same as the one implemented in Firefox—only the visible areas respond to pointer events. I’m not sure if this is a feature or a bug. In the following example, an SVG <clipPath> is applied to an SVG <image>. The clip path is similar to the one we used before, where the image is clipped by a number of rectangles. The image becomes translucent when you hover over it. Try The Demo Out Live Also, note that an empty clipping path will completely clip away the element that had the clip-path property applied. Final Words Clipping is one of those graphical operations that allow us to create irregular shapes in an otherwise rectangular web page. Indeed, clipping is a perfect companion to CSS shapes. If you’ve read any of my previous articles about CSS Shapes, then you already know that the clip-path property can be an indispensable companion to CSS Shapes in some use cases. And once CSS Shapes properties can reference SVG paths (CSS Shapes Module Level 2), in addition to the basic CSS shapes, the combination of Shapes and Clipping will allow us to create visually compelling designs that break the norms of the rectangle. I hope you found this article useful. Thank you for reading! –>

Structuring, Grouping, and Referencing in SVG — The, , and Elements

SVG comes with its own ways for structuring a document by means of certain SVG elements that allow us to define, group, and reference objects within the document. These elements make reusing elements easy, while maintaining clean and readable code. In this article we'll go over these elements, highlighting the difference between them and the advantages of each one. Grouping with the <g> element The ‘g’ in <g> stands for ‘group’. The group element is used for logically grouping together sets of related graphical elements. In terms of graphics editors, such as Adobe Illustrator, the <g> element serves a similar functionality as the Group Objects function. You can also think of a group as being similar to the concept of a layer in a graphics editor, since a layer is also a grouping of elements. The <g> element groups all of its descendants into one group. It usually has an id attribute to give that group a name. Any styles you apply to the <g> element will also be applied to all of its descendants. This makes it easy to add styles, transformations, interactivity, and even animations to entire groups of objects. For example, the following is an SVG bird. The bird is made up of several shapes such as circles and paths. If you wanted to move the entire bird from one place to another in Illustrator, you will also want to group the elements together so that you wouldn’t have to select each and every one of them every time you wanted to do so. Grouping in SVG using the <g> element works the same way. In this example we’ve grouped the elements of the body together, the elements of the head together, and then we grouped the two groups into one group with an id of bird. If you were to change the fill color of the #body group, the fill color of all the elements inside the group will change to the color you specify. This is very convenient. Grouping elements is very useful, not just for organizational and structural purposes. It’s particularly useful for when you want to add interactivity or transformations to an SVG graphic that is made up of several items. You can associate those items together in a group and then define transformations to move, scale, or rotate all the items together so that their spatial relations to one another are maintained. If you wanted to scale the entire bird up and make it twice its size, you will be able to do it with one line of CSS if all the elements are grouped together. Grouping makes interactivity, in particular, more convenient. You can attach mouse events to the entire bird and have it respond to the events as a whole group, instead of having to apply the same interactions and/or transformations to every element in that group. The <g> element has one more important and great feature: it can have its own <title> and <desc> tags that help make it more accessible to screen readers, and overall make the code more readable to humans as well. For example: Reusing elements with the <use> element Often times, there are elements that are repeated in a graphic. If you’re working in Illustrator and you want to repeat an element somewhere in the graphic, you would copy the element and then paste it and use it wherever it is you want to use it. Copying and then pasting an existing element is more convenient than having to recreate that element from scratch. The <use> element lets you reuse existing elements, giving you a similar functionality to the copy-paste functionality in a graphics editor. It can be used to reuse a single element, or a group of element defined with the <g> element. <use> element lets you reuse existing elements, giving you a similar functionality to the copy-paste functionality in a graphics editor. The <use> element takes x, y, height, and width attributes, and it references other content using the xlink:href attribute. So if you have defined a group somewhere with a given id, and you want to reuse it somewhere else, you give its URI in an xlink:href attribute, and specify the x and y location where the group’s (0, 0) point should be moved to. For example, if we were to create another bird in our SVG canvas, we could reuse the existing bird like so: Note that you can reference any SVG element inside the xlink:href attribute, even if that element is in an external file. The referenced element or group does not have to exist in the same file. This is great for organizing files (for example you could have a file for reusable components) and for caching the used files. If the bird in our example were created in a seperate file called animals.svg for example, we could have referenced it like so: However, referencing external SVG in <use> doesn’t work in most versions of IE (up to IE 11). I recommend you read this article by Chris Coyier for details and fallback mechanisms. Now, those of you with a sharp bird’s eye (pun not intended), may have noticed that I said that the x and y attributes of <use> specify the location where the group’s upper left corner should be moved to. Moving an element means that you’re starting from its current position and then changing it to another one. Had I said “should be positioned at”, it would have implied that the element will be positioned according to the coordinate system in use on the entire canvas, right? As it turns out, the x and y coordinates are a shorthand for translating an element using the transform attribute. More specifically, the above <use> use is equivalent to: This fact means that the position of the new reused element is relative to the position of the original element that we’re reusing. This isn’t always optimal and can have some drawbacks. x and y coordinates are a shorthand for translating an element using the transform attribute. Another drawback of the <use> element is that the “copies” of the original element will have the exact same styles as the original element. Whenever you apply any style or transformation changes to the #bird group in the above example, all the copies of the bird will get the same styles and transformations. You can use an element and apply an independent transformation to it. For example, the following line will reuse the bird, but it will make it half its original size using a scale transformation: However, you cannot override the styles of the original element (such as fill and strokes) on the copy. This means that if you want to create multiple birds or multiple icons (if you’re working with icons) and you want every icon to have a different color, this won’t be possible with the <use> element (unless the original element is defined inside a <defs> element without these styles applied to it. See next section for more information). The <use> element allows you to reuse an element that is already rendered on the canvas. But what if you want to define an element without displaying it, and then draw it at specific positions when you need or want to? This is where the <defs> element comes in. Reusing Stored elements with the <defs> element The <defs> element can be used to store content that will not be directly displayed. In other words, the <defs> element is used to define elements without directly rendering them. This stored hidden content can then be referenced and displayed by other SVG elements, which makes it ideal for things such as patterns that contain reusable graphics. <defs> element is used to define elements without directly rendering them [..] and that element will serve as a template for future use. So, using <defs> we can define an element that we want to use. This element can be anything, ranging from a group of elements like the bird we saw earlier, to a clipping path, mask, or a linear gradient. Basically, anything that we want to define and store away for later use can be defined inside the <defs> element, and that element will serve as a template for future use, or as a tool that is available for use whenever needed. The template is never rendered, only instances of it are displayed. The following is an example defining an SVG gradient, and then uses it as a fill color for a simple SVG rectangle: Defining the linear gradient inside the <defs> element like that ensures that the gradient will not be rendered unless it is referenced somewhere it is needed. In the previous section we mentioned two drawbacks of the <use> element: The position of the new element is relative to the position of the original element. The styles of the original element cannot be overridden in the individual copies. That, in addition to the fact that the reused element will be rendered on the canvas. All of these drawbacks can be avoided using the <defs> element. Not only is the original element not rendered, but when you want to reuse an element inside <defs>, the position you specify for each instance will be set relative to the origin of the user coordinate system, not relative to the position of the original element (which makes sense considering the original element is a template that’s not even rendered on the canvas). In this example we have a tree. The tree is made up of a bark and a group of leaves. The leaves are grouped into a group with id="leaves", and then this group is grouped with the bark into the larger tree group. And this is how the tree looks like: If we were to wrap the #tree group in a <defs> element, the tree would no longer be rendered on the canvas. Now the tree serves as a template for use. We can use it using the <use> element just like we would use any other element. The only difference in this case is that the x and y attributes are now set relative to the user coordinate system, not relative to the position of the used element. For example, if we were to create three copies of the tree and position them on the SVG canvas, and assuming in this case that the user coordinate system matches the viewport’s height and width with the origin being on the top left corner of the SVG viewport, we’d get the following code with the following result: As you can see in the image above, each of the trees was positioned relative to the origin of the coordinate system which in this case is the upper left corner of the SVG. So the upper left corner of each tree is positioned at its own (x, y) position in the user coordinate system, independent of the other trees and independent of the tree template defined inside <defs>. When you use <defs> to reuse an element, you can apply different styles and fill colors to each individual tree, as long as these styles are not defined on the original tree template. If the tree inside <defs> has styles applied to it, those styles still won’t be overridden by any new ones. So <defs> is great for creating minimal templates and then styling the copies as needed. Without <defs>, this wouldn’t be possible with <use> alone. Note that elements inside the <defs> element are prevented from becoming part of the rendering tree just as if the defs element were a g element and the display property were set to none. However, that the descendants of a defs are always present in the source tree and thus can always be referenced by other elements; thus, the value of the display property on the defs element or any of its descendants does not prevent those elements from being referenced by other elements, even if it is set to none. Grouping elements with the <symbol> element The <symbol> element is similar to the group element <g>—it provides a way to group elements together. However, it differs from the group element in two main things: The <symbol> element is not rendered. It is actually similar to <defs> in this manner. It is only displayed when it is used. A <symbol> element can have its own viewBox and preserveAspectRatio attributes. This allows it to fit into the viewport it is rendered into any way you want it to, instead of fitting in the default way. <symbol> is then mostly suitable for defining reusable elements (or symbols). It also serves as a template that is instantiated using the <use> element. And having viewBox and preserveAspectRatio attributes, it can scale-to-fit within a rectangular viewport defined by the referencing <use> element. Note that symbol elements define new viewports whenever they are instanced by a use element. This feature is great because it allows you to define elements that are independent of the viewport they’re rendered into, hence allowing you to make sure the symbol you’re referencing will always display a certain way inside the viewport. You need to be familiar with the way the viewBox works, and the values of the preserveAspectratio attribute to make the best use of this feature. Chris Coyier wrote an article explaining why the <symbol> element can be a good choice for icons, and how to use it. I will also be writing an extensive article about the `viewport`, `viewBox`, and `preserveAspectRatio` attributes that explains how these attributes work together and how they can be used to control and scale graphics in SVG, so stay tuned for that if you're interested. UPDATE: Article is live here: Understanding SVG Coordinate Systems and Transformations (Part 1) – The viewport, viewBox, and preserveAspectRatio Note that the display property does not apply to the symbol element; thus, symbol elements are not directly rendered even if the display property is set to a value other than none, and symbol elements are available for referencing even when the display property on the symbol element or any of its ancestors is set to none. Wrapping up All of these elements are container structural elements in SVG that helps make reusing elements easier while keeping the code cleaner and more readable. And each of the elements we went over in this article has its own use cases. Now that you know what each one does and how they differ, you can decide for your own which one to use, depending on your needs. That said, don’t forget to keep your SVGs accessible at all times. I hope you liked this article and found it useful. Thank you for reading!

Everything You Need To Know About The CSS will-change Property

What the title says! I wrote this article for the Opera Developers' blog, and it literally contains everything you need to know about the new CSS will-change property, including but not limited to: how to use it, when to use it, when not to use it, performance considerations, and more.

Moving Forward With CSS Shapes

Following up with the CSS Shapes 101 article, I share a list of great resources to learn more about CSS Shapes, including tutorials, examples, and developer tools.

CSS Shapes 101

In this article, you'll learn everything you need to know to get started using CSS Shapes today. We will cover all the prerequisites: establishing a coordinate system, conditions for elements to be eligible for shapes, and more, then moving on to the properties used, their values and how each one affects the shape created, with lots of visual explanations and examples.

CSS Regions Matter

Whether or not CSS Regions can be used to create multi-column or responsive layouts, fact remains that, unlike Flexbox, Multi-Columns, and Grids, CSS Regions are not a layout feature—they're a fragmentation feature that allows us to control or change the flow of content across containers in a page, or across pages. Since CSS Regions are a fragmentation feature, they define where content flows on the screen—unlike Flexbox, floats, Grids, and other positioning features that define how content is laid out on a screen. Layout features position elements and containers; Regions can alter the flow of content that shows up in them. In this article I want to go over some useful examples of use cases for CSS Regions, and highlight some of the challenges that we may face when using CSS Regions, and talk about possible solutions to common Regions problems. I wrote this article before the news came out that Google decided to pull Regions out of Blink, which, in my opinion, is a big loss for the web community. So, even though the content of the article may go in vain, I think it's still worth sharing why I think CSS Regions mattered, and wish they weren't ditched like that. I hope you guys like it anyway. Disclaimer In no way is this article meant as an attack on Mr. Håkon Wium Lie’s article about CSS Regions. Mr. Håkon’s article served as an incentive for me to dig deeper into CSS Regions, and during the process, I learned a lot about them, and about other future CSS features, and this article is the result of what I found out and my personal opinion regarding the usefulness of CSS Regions. CSS Regions Problems and Possible Solutions CSS regions have two prominent “problems” today: non-semantic presentational elements, and the non-responsiveness of regions. The Problem Of Non-Semantic Markup, and Possible Solutions The reason we are using non-semantic elements to create Regions today is that other layout features, such as Grids, for example, have not yet been finalized and are not yet ready to be used. So, instead of using portions or fragments of a CSS Grid layout, for example, as regions, we’re currently stuck with defining regions using “normal” elements such as divs. CSS Regions are designed so that they work now, with normal elements, and also work with future features, instead of waiting for things to be perfect. It is only a matter of time before Regions can be used with other layout features, and then a lot of the current Regions problems can be solved. When Regions are used with other features, such as Grids and Flexbox, they allow us to use fragments of a layout as regions by simply applying the flow-from property to them. No empty elements will be needed to define regions, whatsoever. To demonstrate how Regions can be defined without creating empty elements, I will show a code example provided to me by Adobe’s Catalin Grigoroscuta. In the demo, the pseudo-element ::after is used to define regions to flow content into. So we do not need to add any empty elements to the page to create our regions, and therefore the semantics of the content are not compromised. This demo is a variation of an excellent use case for Regions that Chris Coyier came up with: using regions to shuffle contents on a page, allowing us to reposition ads that are placed inside a sidebar on big screens, and place them in between the text content of an article on small screens, so that they don’t stack up down at the bottom of the article. The layout would start with a sidebar having the ads inside it, much like most blogs and magazines do today. Source And then using CSS Regions, the content is “folded” on smaller screens, allowing ads to be placed between the text content of the article. Without CSS Regions, the ads would appear at the bottom of the article, way down at the bottom. Source Chris did it by introducing empty elements into the article where he wants the ads to appear on small screens. And then, using media queries, he flowed the ads from the sidebar into these elements using the CSS Regions properties flow-from and flow-into. The CSS needed to define the flow of the ads into the regions is shown below. You can see that this use case for Regions is brilliant and very practical. But it has one problem: non-semantic empty elements. A way to avoid using empty elements to define our regions would be to use the ::after pseudo-element on each of the <article> elements, and use the pseudo-element as the region we flow the ads into. The following code shows how this can be achieved using just a few lines of CSS. No code bloating, no non-semantic elements. First we create our markup, similar to the way Chris did it, but we leave out the empty elements. And then using Regions properties, we define our regions on the ::after pseudo-element of each article. This is a brilliant idea that solves the problem of non-semantic elements, and also shows how well Regions can work with other CSS features. You can see a fork of Catalin’s live demo here. And what’s even more awesome is that this technique and the code used for it are 100% reusable. This example shows that the non-semantic elements that are now sometimes needed to define regions, will no longer be a problem when Regions are used in conjunction with other layouts features. Just like we defined regions on pseudo-elements, we would be able to define regions on fragments of the layout that are part of a Grid or Flexbox, for example, and the semantics wouldn’t be affected. Grids and other layout features would provide “slots” to use as regions, just like pseudo-elements can be used as regions. The Responsiveness Of Regions Or Lack Thereof CSS Regions are not responsive by themselves, they need media queries to change. But then again, Flexbox does too, and so do CSS Grids, and that does not mean these features are not useful. Relying on Regions alone to fully “responsify” a layout is not a good idea, but that’s not surprising, considering that it’s not what Regions are made for. The biggest challenge that we could face when making Regions responsive is fitting the content inside a Region that has a fixed height but different widths on different screen sizes. We all know how limiting that is. If we start mobile-first, the content will be too little for the element on bigger screens when it expands horizontally, and if we start desktop-first, the content will overflow the element on small screens. The thing about regions is that it does not define a way to generate new boxes to fit the overflowing content. This is a curse, but also a blessing, because it allows Regions to work well with any other specification that can generate boxes. The repsonsiveness of CSS regions would no longer be a problem when they are combined with other features that can do what Regions can’t do, such as the CSS Overflow Module. If these technologies were to combine, then we would be able to create responsive layouts that have regions defined in them, without having to worry about content overflowing the regions. The CSS Overflow Module is described in the specification as follows: This module contains the features of CSS relating to new mechanisms of overflow handling in visual media (e.g., screen or paper). In interactive media, it describes features that allow the overflow from a fixed size container to be handled by pagination (displaying one page at a time). It also describes features, applying to all visual media, that allow the contents of an element to be spread across multiple fragments, allowing the contents to flow across multiple regions or to have different styles for different fragments. (bold emphasis added by me) Considering how CSS Regions are meant to help us create and control fragments of a layout, this Overflow module looks like a great match for Regions. Together, they could allow us to make Regions responsive by “extending” a region. The Overflow module handles overflow into “fragments”—it duplicates the source element and flows content into it as many times as necessary to fit the whole content. So as the screen becomes smaller, the region can be “extended” to fit its content without having to overflow that content into another region or element. Extending a region would be as simple as defining overflow: fragments; on it, and we would end up with a solution to the fixed region height problem. That sounds really great, doesn’t it? There is also another proposal from Adobe—multiple pseudo-elements—which allows the creation of multiple ::before and ::after pseudo-elements on an element. Similar to the Overflow module, it would allow us to extend an element and use its extension as a region, much like we did in the example in the previous section, where we used the pseudo-element as a region to flow the ads into. We could define as many pseudo-elements as we want to “extend” a region whenever needed, without having to add a single empty element to the DOM. Razvan Caliman has even created a polyfill for pseudo-elements if you’re interested you can check that out. Another challenge we may face when creating regions is having text overflow a region when the text is scaled up (page zoomed in) by the user, or when the contents of a region change such as when the page is translated into another language, for example. A lot of times, we may want to keep the contents of a region inside that region, and not have them flow into another region, even if that other region is an extension of the main region. For this, the CSS Regions specification extends break properties from the Multi-Column Layout specification. These properties can be used to specify whether content inside a region is allowed to overflow to another region or not. More specifically, they allow us to decide whether a region breaks or does not break relative to the content inside it. This technique is useful for keeping related elements grouped together and for preventing important elements from being split. The following image is borrowed from CJ Gammon’s article on Smashing Magazine and shows how the break properties can work when shuffling a layout to fit on small screens. They allow us to prevent the regions from breaking until after each image in the image flow. This is an excellent use case for CSS Regions. You can read more about the example in the article on Smashing Magazine. Brian Rinaldi has also touched on the topic of using CSS Regions in responsive layouts more then once. You can read more about creating simple and more complex layouts with CSS Regions in the following two articles he wrote: Using CSS Regions In Responsive Designs Creating complex layouts for the web with CSS Regions and Adobe Edge Reflow CC CSS Regions Use Cases And Reusability Of Code We can create reusable code using CSS Regions, similar to the way it is possible to create usable components using Web Components. The following examples show some use cases for CSS Regions that would otherwise not be possible without them. The code used to create the functionality in these examples is reusable. I’m sure that once the new features like Grids and Flexbox are more widely supported, a lot more use cases for Regions may rise, so please do not take these examples as the only use cases for CSS Regions. Using Regions To Shuffle Layouts On Different Screen Sizes Regions give you the possibility to freely reshuffle the whole layout at any breakpoint. Even better than flex — Christian Schaefer (@derSchepp) January 23, 2014 The example we saw earlier about “folding” content and displaying ads in the middle of articles on small screens is a perfect example of the ability of CSS Regions to shuffle layouts, which makes them a fantastic tool to have in our responsive web design toolkit. The code used to create the ad-shuffling layout can be reused in any layout that needs the same functionality—you add the necessary regions where you want the ads to appear (flow into), and use the same couple of CSS lines shown earlier to flow the contents of the sidebar (or whichever container contains the ads) into these regions on smaller screens. And, of course, you could also avoid using those extra elements as regions and use the pseudo-element technique for adding the regions between the sections of the article. In addition to defining regions where you want the ads to flow into, you can also style these regions' content using the @region rule. A @region rule contains style declarations specific to a particular region. This also allows for even more modular style sheets that are specific to certain regions. This way, you can add your regions into a page, and hook in their specific style sheet, and end up with contents flowing into those regions being styled the way you expect them to, based on the styles u specify using the @region rule. For example, the following snippet will style all paragraphs that flow into a region by applying an italic font style to them. It is important to note here that, at the time of writing of this article, only a subset of styles are implemented for region styling. Only styles that don’t affect layout can now be applied to content inside regions using @region, like, for example, text and background colors. Styles that do affect layout like display, float, and margin properties do not yet work inside regions. But once they do, we can style region-specific content better and use it to create modular and reusable code. Also, the styles inside the region are applied to the source element which is going to be moved into the region, so you’ll need to remember to use the appropriate class names or IDs as the ones you’re using on your content. Repositioning Menus On Small Screens In this example I am going to use just a couple of lines of CSS to move a navigation from the header into a hidden off-canvas sidebar on small screens. For the sake of brevity and clarity of code, I kept the sidebar visible because I wanted to focus only on the code that accomplishes the responsive menu effect using Regions, and not the actual hiding and showing of that menu. The example is pretty basic, so I’ll just create a navigation menu in a header, and a sidebar to flow the menu into on small screens. Only two lines of CSS are needed to move the navigation from the header into the sidebar. And only a few lines of CSS inside an @region rule are needed to apply styles to the contents inside our region. The navigation which is going to be moved into out region has new styles declared for it inside the @region rule. You can reuse this piece of code anywhere. Just drop that sidebar in and hook those few lines of CSS. Of course make sure the class names and IDs match those of the elements on the page you’re using them for. Because, at this time, only a subset of styles are supported for region styling, I just changed the color of the links inside the sidebar for demonstration purposes, but when more styles are possible, we could have the navigation items stack on top of each other and be styled just like all off-canvas menus we see today. You can see the live demo and check the code out here. Resize the screen to see the effect. Razvan Caliman has also created a slightly more complex responsive menu that uses CSS Regions to flow menu items into a drop-down menu when these items no longer fit on the menu bar. You can see Razvan’s demo here. Examples Of Where One Might Want To Use CSS Regions To Create Columns There is no way in the CSS Multi-Columns module (that I know of) that gives designers the ability to style each column of text individually. The module allows content to be displayed in multiple columns, but it does not give us the power to treat each individual column separately, and give the columns different widths and heights, for example. And this is where CSS Regions have an advantage over Columns. Columns created using CSS Regions are stylable any way we want them to. Each column is a region and each region can have its own styling independently of the other columns. And by styling I mean all kinds of styling: from adding backgrounds to a column, to styling text inside a column, to positioning columns, changing column dimensions, and even transforming columns using CSS Transforms. Now, if creating a simple multi-column layout is the goal, and that layout can be achieved using Multi-Columns alone, then by all means we should use CSS Columns to do it. CSS Regions could do a lot of things, but they should not be used to do everything. Just because we can do something with Regions, does not mean that we should. The first example shows three columns on the right page of a magazine design, each with different heights. Giving different heights to columns is not possible with CSS Multi-Columns alone. But using CSS Regions, each column can be defined as a region and given any height we want. And another example is one I recently created for an article I wrote about combining CSS Regions with CSS Shapes to improve the readability of layouts created using CSS Shapes. Each column shown in the above picture is a region, and each region is shaped using CSS Shapes to get the above result. You can view the live demo here. None of these examples would be possible to create using just CSS Multi-Columns, so it is great to have such a tool at our disposal. And the final example I want to show is one created by Opera’s Chris Mills for an introductory article he wrote about CSS Regions. The demo is an example of how CSS Regions can be used to create text containers that are separate from each other, transformed using CSS Transforms, and positioned on the screen, and then have the text content flow into these containers in the order they appear in the original source. This is a screenshot of the demo: The demo is a nice demonstration of how CSS Regions offer us finer control over fragments of a page and how they allow us to flow content inside containers any way we want them to, while giving us the ability to completely separate content from layout concerns. CSS Regions Versus Future Layout Features CSS Regions can be used today to create and shuffle layouts in many ways. But what happens if a better solution is someday introduced that allows us to do what Regions allow us to do today in a better and more efficient way? Mr. Håkon Wium Lie has already shown some good solutions to certain layout problems he discussed in his article by using CSS Figures instead of CSS Regions. This is actually great, considering that the Figures and Multi-Columns specs are made to do what he used them to do. And when these specifications are implemented, we will probably use them to do what he did too, as they offer a more flexible way to create those layouts than Regions do. As a matter of fact, the CSS Figures specification introduces some really cool and useful features, like vertical floating, where we get to float an element using top and bottom values, in addition to the left and right values that we have today. I can imagine how these values can be useful already. We also get a float offset property which allows us to offset a floated element, which is super useful considering how easy it makes to wrap content around a figure such as an image or a blockquote. We are now able to offset any element by applying a position:relative to it and then using the offset properties (left, right, top, bottom) to “push” it in any direction we want, but that will not affect the flow of content around it, as the position it occupies on the page will be preserved and won’t be occupied by any surrounding element. Using float offsets introduced in the CSS Figures spec, we will be able to wrap content around an offsetted float with so much ease, and this is just brilliant! When new features such as CSS Figures are implemented, we will definitely use those for a lot of use cases where they would fit in better than CSS Regions, but CSS Regions also have other use cases that neither the Multi-Column specification, nor the Figures specification can do. So I believe that it would be great for the future of the web for all of these tools and features to coexist and offer us, designers and developers, a wider range of options that give us more control over our layouts. Final Words CSS Regions give us the ability to do a lot of things that are otherwise not possible without them. They can be a very useful and powerful tool in our responsive web design toolset, and when used in conjunction with other features, can provide us with great solutions to common design problems we are faced with. Just like any other feature, CSS Regions should be used in the right place, and it is our responsibility to use them that way. I believe that we are smart enough to know when and where to use a feature. Do you have any great use cases for CSS Regions? Do you think it will be a valuable tool in our web design toolset? flippinawesome.org on January 27th, 2014.

Animating CSS Shapes with CSS Animations and Transitions

Today we're going to be talking about animating CSS shapes with CSS animations. We'll be creating very basic "shape-shifting" layouts of sort. There are also many considerations to take when animating CSS shapes, so we'll go over all points in this article. This is the third article in a series of articles I’m writing about CSS shapes, so in this article I’m assuming you have a basic understanding of how CSS shapes are created. You may want to check the first article: Creating Non-Rectangular Layouts with CSS Shapes, which covers all the basics to get you started creating CSS shapes in no time. The second article was about combining CSS shapes with CSS regions to create more readable layouts, tackling one face of the accessibility of non-rectangular shaped layouts. Most of this article's demos use the `shape-inside` property, which has been temporarily removed from Webkit and Blink. The principles of animating shapes is applicable to both CSS Shapes *and* CSS Clipping masks. All the demos in this article use clipping masks to visualize CSS Shapes. Hence, the shapes are animated as clipping paths as well. So, you will be able to see the shapes animate in webkit-based browsers at this time, but the content inside the shapes won't be affected by the shapes because of the current state of support for CSS Shapes. For a detailed suppprt table for CSS Clipping and Masking, see the CanIUse.com Support table. current state of browser support for CSS Shapes out. Animatable CSS Shapes There are two ways we can create a shape with CSS shapes: using an image URI which the browser uses to extract the shape from, and using one of the available CSS shapes functions, such as polygon() and circle(), among others. Shapes defined using an image are not animatable. So, if you define a shape using an image, specify a transition, and then define another shape using another image when the element is hovered, for example, the shape applied to the shape will change but it will not animate or transition into the new shape; it will just “jump” from one shape into another in an abrupt manner. The only way a shape can be animated is when it is defined using a shape function. Even so, there is one condition: the number of points defining the final shape must be the same as the number of points defining the initial shape. When you think about it, makes perfect sense: you have a set of points that make up a shape, and then you move those points around and have them form another shape. So the transitions on CSS shapes are really transitions on the individual points making up a shape. More specifically, transitions on the coordinates of each point, where the coordinates are interpolated as real numbers to allow animations and transitions, just like any other animatable CSS values. When I first learned about this condition, I thought it would not be possible to change a simple shape into a more complex one that has more points defining it, but that’s actually not true, it is very doable: start by definining the points needed for the more complex shape, and then rearrange those points to form the simple shape. For example, even if you have 20 points making up the final shape, and you want to start with a simple rectangle defined by 4 points, you can still place those 16 extra points on the rectangular shape by simply placing them on one of the rectangle’s sides, without them affecting the shape of the rectangle. We’ll get into the examples shortly. Now, thinking about the complex shape first does not at all mean that the initial shape must be more complex than the final shape, it just means that you will think ahead and prepare all the requirements before you start coding. You can easily animate a simple shape into a more complex one if you have all the necessary points defined. Things To Consider Before Animating Your Shaped Layouts Content Fitting Inside Different Shapes One thing to consider when animating CSS shapes in general is the fact that the content that fits into one shape may not perfectly fit into another. You may start out with a simple shape, and when you animate that shape into a new one, the content inside that shape may overflow the new shape, or may be too little for the new shape. So you may need to resize the element as you change its shape as well, so, again, the design process has to be thought through in detail. This also means that it wouldn’t be very simple to depend on animated CSS shapes for dynamic content, unless you create the shapes dynamically with Javascript. But that’s a topic for another blog post ;) Animated Text Becomes Temporarily Unreadable Animating text composition in general, whether by animating Shapes or even a simple animation of width, will make the text temporarily unreadable. (Thanks Alan for bringing that to my attention) While it might be an interesting graphical effect for smooth layout changes, the process of text changing its layout blocks the ability of the reader to read your content, and it is only after the animation is over that they will again be able to read the text. That is, of course, assuming that the Shapes are readable to begin with, as we noted before. General Accessibility Be careful what shapes you choose, and consider how they affect the readability of your content. And think twice before integrating CSS animations with CSS Shapes. Also, shapes that are fine on big screens may not be fine on small screens. Personally, I would stick with rectangular layouts on small screens, and progress to more complex (but still readable) shaped layouts on big screens. But then again, this depends on the shapes you choose, and some simple shapes are actually OK on small screens as well. The aim of this article is to discuss and experiment with the different ways and options we have to animate CSS Shapes. Shapes animations should only be used in real projects when there is a practical use-case for these animations (and of course when there is more acceptable browser support ^^). I’m sure someone will think of a nice use-case. So, for now, let’s dig into the actual animation process and have some CSS Shapes fun! 1. Initial and Final Shapes Have Same Number Of Points We’ll start off with very simple examples and then progess to more complex ones. The examples in this section won’t deal with the number of points defining a shape. We’ll leave that for the second section. The best way to visualize a shape animation it to use the shape properties in conjunction with the clip-path property, which will clip any excess parts of the element that are outside the defined shape. I’ve talked about using CSS clip paths with CSS Shapes in detail in my first article, so check that out if you still don’t know how they can relate. Rearranging Points To Create A New Shape So for our first example, we’re going to do just that. And for the sake of simplicity and demonstration purposes, we’re not going to be doing anything fancy. We’ll create a simple shape and animate it on hover using a simple CSS transition. The initial and final shapes will have the same number of points so we won’t have to worry about that for now. All we have to do, is move the points around (rearrange them) and see how the shape transitions smoothly. We’ll start with a simple inverted trapezoid shape, and when you hover over the element, its shape will animate but the final shape will also be a trapezoid. The only thing we’re going here is move the points defining the shape around by changing their coordinate values. We’ll be using the clip-path property to make the shape and the animation clearer and more obvious. The shape-* properties are supported unprefixed in Canary, but the clip-path property still needs its prefix to work. See the Pen animating a css shape by Sara Soueidan (@SaraSoueidan) on CodePen. And it’s as simple as that! Just change the coordinates of the points defining the shape define a transition on the element, and you’ve got yourself a smooth animating shape. You will be able to see how the text inside the shape is animated into the new shape as well. And you can also see that, during the animation process, that text is very unreadable. Now, if you change the shape on hover to another shape by using another shape function for example, or changing the number of points defining the shape, the shape does change, but it will not transition or animate; it will jump from the initial shape to the final one abruptly. For example, the following code: I’ve added this snippet to the above demo. Click the “Edit on Codepen” link on the demo, and uncomment the snippet in the .element:hover rule to see how it affects the animation. Resizing Shapes With No Specific Number Of Points In our second example, we’re going to animate a circular shape by increasing its diameter. The number of points on a circle is undefined, and the only thing defining the circle in the circle() function is its center and radius. We’re going to have the circle increase in size when we hover over it. This sounds a lot like resizing an element in CSS using CSS transforms and the scale() function, but it’s not really the same. When you scale an element using CSS transforms, the entire element including its content will increase in size, and by increasing its size you’re not creating any extra room inside it for more content. But when you resize an element’s defined Shape, you are making more room or taking away from it. So, you could, for example, increase the size of the element’s shape and then dynamically add some content to it and have that content fit inside it, but that’s not possible when you’re scaling the element up with CSS transforms. In this example we’ll first define a circular shape on our element using the circle() shape function, and then animate the circle’s size when the element is hovered. You will be able to see how that will affect the room inside the element. First, we’re going to define the shape on the element and fire an animation on hover. We’ll define a circle of radius 210px whose center is positioned at the center of the element. Then we’re going to define the animation keyframes that will control the scaling of the shape. The final effect will be similar to a beating effect: the radius of the circle is going to increase and then decrease back to its initial size at the end of the animation. And we have set the animation to repeat infinitely as long as you’re hovering over the element. And here is the resulting effect: See the Pen animating a css shape by Sara Soueidan (@SaraSoueidan) on CodePen. You can see that the room for content inside the circle increases, and more text can fit inside the shape when it grows. So, you could, for example, use a growing CSS Shape to show more content information when an element is hovered. 2. Initial and Final Shape Have Different Number Of Points In this section we’re to animate from one shape to another, where the initial and final shapes are visually defined by a different number of points. We’re going to use the polygon() function to define our shapes. As I mentioned at the beginning of this article, only shapes with the same number of points can be animated into one another. So, in order to animate from a shape to another, we have to make sure that the number of points in the definition of these shapes is the same, even if they don’t visually appear to have the same number. Animating A Complex Shape Into a Simple Shape We’re going to start with a very simple demo, where we animate a star shape into a simple rectangle shape. (Not that the star shape is really complex, but it is more complex than the final shape it will be animating into.) The star is defined by 10 points (shown in blue), and the rectangle only needs 4 points to define it. It is true that the rectangle only needs four points to define it, but it can also be defined by as many points as we want it to. The polygon() function we’re going to use to define these two shapes needs to take in the same number of points for the two shapes in order for the animation to be possible. This means that we need to use 10 points to draw the rectangle just like we will use 10 points to draw the star, and there is no problem with this. Why? Because we can simply place the extra points in a way that does not affect the resulting shape we want. So, the rectangle will be defined by 10 points, which we can place as shown in the image below: Of course, we could have placed the extra 6 points anywhere on the rectangle’s edges, but that would change the animating effect. We’ll get to this in a minute. Now that we have the same number of points in both shapes, we can easily transition from one shape to another. We’ll first position the points so that they make up a star. The polygon() function for the star shape looks like following; of course, we’re also going to clip the element to the shape using the clip-path property as we did before. And when the element is hovered, the points will be rearranged to form a rectangle defined as follows: You can see the points being rearranged to form a rectangle in this live demo: See the Pen animating a css shape by Sara Soueidan (@SaraSoueidan) on CodePen. Rearranging the points has a very big effect on the transition. The order of points in the initial shape is preserved when they are rearranged to form the second one, and you need to keep that in mind, otherwise you may end up with a not-so-beautiful transition/animation effect. The following is an example of what could happen if you randomly rearrange the points. You can see where each point will be placed, and you can tell that that is not the best way to do it. See the Pen animating a css shape by Sara Soueidan (@SaraSoueidan) on CodePen. So be careful and always make sure you rearrange the points the best possible way that ensures a nice transitioning effect. Animating A Simple Shape Into a Complex Shape Our last example is the most complex one, but you’ll find that it’s not really complex at all. We’ll be applying the same concept we applied in the previous example, but instead of starting out with a higher number of points we’re going to start with a simple rectangular shape and have it animate into an irregular shape. We’ll have a look at what the final shape looks like, how many points it needs to define it, and then well define the initial rectangle shape using the same number of points. The points will be placed on the edges of the rectangle, and we’ll make sure we place them in a suitable way so that they animate to the final shape the way we’d expect them to. We want to start with a simple two-column layout. Each column is a separate rectangular element. And then when we hover over the columns' container, a shape, a tree in our example, will show in the middle between the two columns, and the two columns will animate their shapes so that they kind of wrap the tree in the middle. This example is inspired by this pen by the Adobe Web Platform Team. So this is how the shapes in our our final demo will look like: I drew this in image Photoshop, even the example tree is actually a shape defined in Photoshop. Again, we’re not going to be doing anything fancy in this article, we’ll leave that to another one! The shapes in the image are similar to the shapes in the final demo. Of course, there are no coordinates in the image above to the shapes will probably differ a bit when we plot their points on the elements' coordinate systems. So, let’s get to it! We’ll start by creating two columns of text inside a container. We’ll use the tree shape as a background to the entire container. At first, the background will be invisible, and then when the container is hovered, the background image will scale up, making it appear as if the tree is scaling up in the middle between the two columns. And as the tree appears, the two columns will animate into their respective shapes shown in the above image. In order to know how many points are exactly needed, so that we can define them on the rectangle, I’m going to start by defining the final shape of the columns, and then move backwards and use the same number of points to define the rectangle. The right column’s final shape can be defined by the following shape function: From the above shape, we can now define the initial rectangular shape, by using the same number of points but placing them on the rectangle’s edges. Because our shape changes only on the left side, we can place all the animating points on the left edge of the recangle, and then have them move horizontally into their places on hover. This means that it’s enough to use the same polygon() function as above, but move those points on the left of the shape to the left edge of the rectangle, by giving them all zero abscissa. So the final code to animate the shape of the right column when its container is hovered looks like the following: Similarly, we can get the shape functions for the left column. First define the final (more complex) shape, to get the necssary number of points. Then rearragne those points into a rectangle. And of course in order to get a smooth shape transition, we need to define a transition on the two columns, and a transition on the container with the same speed and timing function, so that the background and column shapes can animate simultaneously. And this is the final working demo: See the Pen 94e3c9210c418770206487ef8700a1c2 by Sara Soueidan (@SaraSoueidan) on CodePen. It is worth noting here that if the two columns were completely filled with text before they are animated, that text will overflow the shape that it will animate to. This is one of those cases where you would want to take into account the text and shapes before you decide to animate your element’s shape. Final Words In this article we went over the basics of animating CSS shapes. All of the shapes we animated here were static, i.e defined in the CSS and animated there. But sometimes, in order to achieve more compelling visual effects, you may want to dynamically create shapes while some element moves on the page. That kind of shape animations can be achieved by creating and animating CSS shapes using Javascript, and is, for now, outside the scope of this article. The examples and demos I showed in this article are all for demonstration purposes only, and may not make for a practical use-case for animated CSS shapes. But combined with CSS clipping paths, some creative shape-shifting layouts can be created that don’t compromise readability of the content. I hope this article, along with the previous two, helped you get up and running with CSS shapes. Of course, at this time, support for CSS Shapes is still limited, but I highly encourage you to start experimenting with them now, as you could help find and fix bugs, and of course when the time comes and Shapes are widely supported, you’ll be Shapes masters by then. :) I hope you found this article useful. Thank you very much for reading!

Using CSS Regions With CSS Shapes For A Better Reading Experience

Using CSS shapes we can flow our content in non-rectangular areas. And sometimes we want to be able to flow our content into multiple custom-shaped areas inside an element. If you've read my previous article, you already know that this can be done with CSS Shapes, by using an image with alpha transparency with multiple shapes defined in it, and letting the browser extract the content's float areas from it. As appealing as this may sound and as creative as we can get with our shapes, flowing the text into multiple areas can easily make our content almost completely unreadable. This article assumes that you're already familiar with the basics of CSS Shapes and CSS Regions. I've recently written an in-depth comprehensive article about creating non-rectangular layouts with CSS shapes, which is perfect for getting you up and running with CSS shapes. Notes: shape-inside property, which will be temporarily removed from Webkit and Blink. So, for the time being, this article will only show screenshots of how the demo works when shape-inside is implemented again. dropped from Blink, so they currently don't work in Chrome. current state of browser support for CSS Shapes out. CSS shapes can introduce a serious accessibility problem when not used wisely. It’s great to achieve all kinds of creative layouts with custom shapes, but the first and most important thing to keep in mind is that the content is there to be read, so a designer must think accessibility and readability first, then appealing layout second. To explain this better, let’s get into an example of when CSS shapes can cause a really bad reading experience. Although, to be fair, it’s not CSS shapes that does that, it’s the decision the designer makes, but you know what I mean. The Problem: Multiple CSS Shapes Making Text Unreadable A few days ago I tweeted about a “fragmented” magazine layout I made using CSS Shapes and CSS Masks. The layout took literally less than 2 minutes to create after the mask images were ready (I made those using Photoshop). But after finishing the layout, I realized that, even though it looked quite interesting and creative, it was anything but readable. Here’s how the layout looked: Fragmented Magazine Layout created with CSS Shapes and Masks The left part of the layout, where the text is flowing in 3 custom-shaped areas, is where the problem occurred. As with content masking, you can imagine your content as one layer and the mask as another; the content will be “painted” only where the mask is opaque, assuming that we’re working with an alpha mask which has only fully black and fully transparent areas. In this case, the fully black areas determine the areas where the content will be visible. And in terms of CSS shapes, the black areas determine the flow areas where our text will flow. This is the mask I used to create the 3 flow areas for the text: The alpha channel mask used to define the flow areas for the text container Now the problem occurs from the way the browser’s layout engine works to fill these areas with text. When the browser flows the text into the shapes it moves down an element line by line, and starts writing the text in the text’s flow areas, which, when you’re using a mask image, are the areas of the element covered by the black areas of the mask. For regular rectangular elements, i.e. those that don’t have any CSS shape defined on them, that is perfectly fine: just move down the element one line after another, and type the text on those lines. But when an element’s flow area changes, things can easily get messy. The browser starts with the first line on an element, and prints the text on that line only where the line passes through a defined flow area (one of the black areas). So, what happens is that words will end up “scattered” on every line, and the lines divided into several “fragments” depending on the number of flow areas passing through the line. A reader’s eye will have to “jump” from area to area to read the fragments that make up a line. The horizontal "fragmented" flow of text inside multiple flow areas defined by CSS shapes As you can see in the image above, if you start reading a line, your eyes have to jump from area to area for every line, which, after a few of lines, becomes impossible to do, at least for me. When I first started experimenting with CSS shapes I expected the text to flow in each of these custom-shaped areas the same way it does in CSS regions: I expected the browser to treat CSS Shapes' flow areas the same way it treats CSS regions, but it does not. What we would normally want to do, is have the text flow in the individual areas, moving to one area after another one has been filled with content. One way to achieve this (filling areas one after another) is by using CSS regions to create any number of flow areas we want, and then giving each region a custom shape inside it using the shape-inside property. So, for the above mask for example, which has 3 shapes inside it which define 3 flow areas, we will define each of these areas as a region, and then give each region a custom shape so that text flows inside it the way we want it to. This way, the browser will fill the first area (first region) with text, and then when it’s full, it will move into the second region after the first one’s been filled, and so on. This way, the text can be easily read inside each region (as long as you’re not using some crazy shape that will make text unreadable in all cases), as your eyes won’t have to jump between regions for every line. Using CSS regions to define the three areas, text will fill each region before flowing into the next one, making reading a lot easier Now let’s change the above demo I made by introducing CSS regions into it and see how that affects the readability of the layout. The Solution: Introducing CSS Regions Into The Layout What we’re going to do, is create three regions inside our text container, and then give each region a shape using shape-inside so that the text flows inside it in a non-rectangular manner. The right side of the demo, which is a “fragmented” image, is created using CSS masks. A mask is applied to the element, which will “erase” parts of the image where the mask is transparent. We’ll get to this part at the end of this section. First, we’re going to go over the markup for the two “pages”. The page with a class name .text is the left page with the text inside it. Inside this page, we’re going to define 3 regions, and a .content container which will contain the text that we want to flow into these regions. So, the 3 regions are initially empty, and via CSS, we’re going to fill them with the text contained in the .content element. Now that we have our markup ready, we’ll start by defining some general styles before we get into the relevant CSS. We’ll be giving all the elements fixed dimensions; both CSS shapes and CSS regions require an element to have fixed dimensions to work. With these styles set, we can now flow our text content into our regions using CSS’s flow-from and flow-into properties. I’ll be using the -webkit- prefix as the demo will only work in webkit browsers at this time. That’s all you need to flow the text into the regions. The demo would look like the following screenshot. I’ve colored the regions' background so that they are more visible. And for the time being, you can ignore the right side of the page with the fragmented image effect. Like I mentioned earlier, we’ll get to that by the end of this section. Screenshot of the demo when text flows inside the regions before applying the shapes to them The text flows from one region to another starting from the left column to the right, which is exactly what we set out to achieve. Now what we want to do next is apply the same non-rectangular shapes to our 3 columns (regions) as those we saw in the mask used above, so that the end result looks like the demo we want to improve. Because we want to change the flow of text inside the regions, we’re going to use CSS’s shape-inside property to change the shape of the flow area inside the regions. There are two ways we could define our shapes: using an image with an alpha channel like we did in the initial demo before we introduced regions, or by creating these shapes using the polygon() shape function. Because each region will have only one flow area inside it which is a simple polygonal shape, we’re going to use the polygon() function instead of creating 3 images for the 3 regions (the image previously used in the demo to define the 3 flow areas can be divided into 3 masks using Photoshop, each mask containing one of the shapes inside the image). And now the text flows inside our regions in non-rectangular shapes: Screenshot of the demo when shapes are applied to the regions With this result, it’s a lot easier to read the text than it was in the intial demo. Your eyes can move down a column and then move to the next once it’s done with the first. Nonetheless, it’s absolutely necessary that a designer always design shapes that don’t strain the eyes. There’s probably a good reason why rectangular reading areas are the most comfortable to read in, and when designers decide to think outside the box (pun intended), it’s important to remember not to compromise readability and sacrifice a good user experience for beautiful comps. With that said, this is how the demo looks: Screenshot of the final demo And this is how CSS regions can help create a fairly better reading experience when used with CSS shapes. It would be great if browsers filled the CSS shapes the same way it filled CSS regions, but because it’s not a simple task to just change the layout algorithm, we can always use CSS regions to get that result. Creating The "Fragmented" Photo Effect with CSS Masks Last but not least, we’re going to use CSS masks to mask parts of the image in the .photo page, to give it that “fragmented” effect. The mask used to create this effect on the image looks like so: Mask with alpha channel used to create the "fragmented" effect on the image The above mask is an image with an alpha channel, where the opaque areas define where the content will be visible, and the transparent areas are the areas where the content will be “erased”. You can notice that it’s obviously a messy mask :P because that’s what happens when I try to “draw” with a mouse! But then again, it kind of emphasizes that “torn” and “fragmented” effect on the image, which is nice. =) Final Words CSS Shapes will be one of the best things to happen to design on the web, but as we’ve always learned: with great power comes great repsonsibility. It’s estimated that in a year from now many browsers will have implemented CSS shapes, so it’s great to start experimenting with them from now. The more you experiment the more you can help find bugs to fix them before all browsers implement them. And finally, I hope you enjoyed reading this article and found it useful. Thank you for reading.

Techniques For Creating Textured Text

For too long, we've resorted to graphics editors to create images of text that has nice effects such as creative fills or that blends with its background in a nice subtle way. We used those images as a replacement for text on our pages, which made that text unaccessible and un-selectable.. But with all the advances in web design today, we can now create textured text effects using CSS, using SVG, and using HTML5 Canvas. This article introduces and shows you how to do that using all of those techniques.

Techniques For Responsive Typography

Text is the most important part of a website. Did you know that are several ways to make text responsive? Be it big headlines or body copy, the article will cover all those techniques, serving as an ultimate reference for making text responsive. We will cover accessibility, media queries, viewport units, and much more.

CSS Overlay Techniques

Overlays can sometimes be annoying, but also undoubtedly have their useful use cases. There are different approaches to creating overlays, some of them work better than others, and some of them come with gotchas that you need to be aware of, including performance implications. In HTML5, we also get a native way to create modals with less hassle and less code. In this article, we will cover all of that.

Creating Non-Rectangular Layouts With CSS Shapes

Today we can create all kinds of shapes with CSS using CSS transforms, but all these shapes do not affect the flow of the content inside or around them. That is, if you create a triangle or a trapezoid with CSS, for example, the shape created does not define or affect the way the text inside it flows, or the way inline text around it does. With the introduction of CSS Shapes into the web, wrapping content in custom non-rectangular shapes, and recreating print designs and layouts on the web becomes a piece of cake! In this article we're going to go over the basics of declaring shapes, and creating some simple layouts using these new CSS technologies. When more CSS Shapes features are implemented, more complex and awesome layouts will be possible, but even with what we have at hand now, some interesting and very creative layouts can be created with a little extra experimentation. The CSS technologies we’ll be covering in this article may not work in your browser. If you want to see the working live demos you need to make sure you’re viewing them in a browser that supports these technologies. Check the current state of browser support for CSS Shapes out. You don't need a supporting browser to understand the features and demos, though. I've included screenshots of the demos so you can see how the final result looks like. shape-inside property, which has been temporarily removed from Webkit and Blink. So, for the time being, this article will only show screenshots of how the demos work when shape-inside is implemented again. Declaring Shapes All HTML elements have a rectangular box model which governs the flow of content inside and around it. In order to give an element a custom non-rectangular shape, the shape-inside and shape-outside properties are used. At the time of writing of this article, the shape-outside property can be applied to floating elements only, and the shape-inside property isn't completely implemented, so you may still find bugs when u use it. The shape-* properties can also only be applied to block-level elements. Non-block-level elements should be forced to block if you want to use a shape property on them. Shape-* properties take one of three values: auto, a basic shape, or an image URI. If the value is set to auto, the element’s float area uses the margin box as normal. (If you’re not familiar with the CSS box model, make sure you read up on it because you should know how it works). If the value is set to a shape function, then the shape is computed based on the values of one of ‘inset’, ‘circle’, ‘ellipse’ or ‘polygon’. You can learn more about each of these functions in this article by the Adobe Platform team. And finally, if the value is set to an image URI, the browser will use the image to extract and compute the shape based on the image’s alpha channel. The shape is computed to be the path that encloses the area where the opacity of the specified image is greater than the shape-image-threshold value. If the shape-image-threshold is not specified, the initial value to be considered is 0.5. The image should be CORS-same-origin, otherwise, it won't work, and the default value auto will be the value of the computed shape. Shapes defined using the shape-outside property define the exclusion area on an element, while those defined using the shape-inside property define the float area of an element. We'll learn what each of these means in the examples below. The shapes defined by the shape-* properties can be modified by using the shape-margin and shape-padding properties. The margin and padding shape properties are self-explanatory. Establishing a coordinate system on an element For the CSS shape declared to actually be applied on an element, we need to first start with establishing a coordinate system which we’ll be using to draw the shape. A coordinate system is necessary because the shapes you declare will be defined by a set of points (and radii if you’re drawing circles or ellipses for example), and these points have x and y coordinates which will be placed on this coordinate system. The shape-* properties use the content box of the element they’re applied to for their coordinate system, so in order to make them work, you need to specify a fixed width and height for the element which defines its bounding box, which in turn will be used to establish the coordinate system for the shapes you draw. If no explicit width and height are specified, the shape-* properties don’t work. The origin of the coordinate system defined on the element's bounding box is positioned at the top left corner. So, to declare a shape an element you have to start with: Specifying the dimensions of the element getting the shape (remember: the element should be floated when using shape-outside on it). Declaring the shape on that element using the shape-* properties. Applying a background to a custom shape While the boundaries used for wrapping inline flow content outside a float can be defined using shapes, the actual box model does not change. If the element has specified margins, borders or padding they will be computed and rendered according to the CSS3BOX module. —W3C CSS Shapes Module Level 1 In other words, the shape you define on an element using shape-* properties only affects the element’s float area, i.e. the flow of the content inside/outside this element, but all the element’s other properties won’t be affected. For example, suppose you only want to draw a circular shape and have content float on its side like the shape in the image below, you’d first have to declare the circular shape on the element (again, remember to float the element and give it a height and width). Then, say you want to apply a background color to the circular shape to look like the one in the image.. Background applied to a custom declared shape You’d be tempted to just add a background color to the containing element and then end up with the above result (that’s what I did the first time), but doing that won’t do the job. The reason for that is that all properties of the element, other than the flow of content outside it, won’t be affected by the shape you defined inside it, and they will be rendered normally according to the element’s box model (its rectangular shape), as we’ve seen in the spec. So if you apply a background color to it, you’ll end up with this. Background applied to the element's rectangular box shape So, how can we apply the color to the shape only and not the whole element? This is where the clip-path property from the CSS Masking specification can help. The clip-path property will be used to clip parts of the element that we don’t need and keep only the parts inside the shape we defined. That obviously means that we’re not actually applying the color to the shape, we’re just trimming the element and leaving only the shape intact. With this, you’ll end up with a floating circle wrapping text outside it. How, exactly? what value does the clip-path property get to do this? The user coordinate system for the shapes defined by the clip-path property is established using the bounding box of the element to which the clipping path is applied, so the coordinate system is the same one as that of the shape-* properties. Because of this, we can use the same shape defined in the shape-* property for the clip path, which will cut out, or clip, everything inside the containing element that’s outside the boundaries of the shape, and we’ll end up with a custom shape with a background. You can test this concept live in this pen, just make sure you test it in a supporting browser. Quick Reminder At the time of writing of this article, the shape-outside property only works on floats, and both shape-outside and shape-inside properties are applied only to block-level elements, or inline elements forced to block. A shape defined on a float will cause inline content to wrap around the defined shape instead of the float's bounding box. Future levels of CSS Shapes will allow use of shapes on elements other than floats, and when that happens we’ll be able to wrap content on both sides of a shape (as in the image below). So for now, we can only float an element and have content flow on either side of it. Flowing content on both sides of a CSS shape You could also fake wrapping content on both sides using the Exclusion Punch plugin by Bear Travis. Now let’s get our hands dirty drawing some shapes and creating some fun layouts! Each of the following examples will introduce a new tip/idea/technique that are used to define and use CSS shapes and exclusions. You can view the live demo for each example by clicking on the demo's screenshot. Example #1: Floating text around a custom shape with shape-outside We’ll start with a simple example. In this example we’re going to define a custom shape and have content flow on its side. The end result will look like the image below: Screenshot of Demo #1. Click on the screenshot to see the working demo. In the demo we have a container which contains two elements: a .content container with text on the left, and another element with a class.shaped floated to the right, which will get the custom shape and have the text flow on its left side. The heading in the .content area is also getting a similar treatment to the one we're giving the floated div on the right, so I'll skip its explanation and only talk about what we're doing on the .shaped area on the right. We will first start by giving the floated div on the right a specific height and width to establish a coordinate system. We’ll set its height to be the same as its container, which for this demo I’ve set to be the same height as the viewport, using CSS’s vh unit. Now that the coordinate system is ready, we’re going to draw the shape, to define the float and exclusion areas of the element. There are two ways to go about declaring a shape for this demo: Using polygon() For the first method, we’ll be using the polygon() function. This function takes in a set of points that form the polygon, each point defined by x and y coordinates. We're going to define a very simple polygonal shape, with 4 vertices, as shown in the image below (blue and orange discs): Screenshot showing the vertices making up the polygonal shape The coordinates of the points can have either specific values (px or em), or percentage values. In this example we're going to provide percentage values for the vertices visible in the above screenshot. Now all we have to do is just declare this shape on the floated element so that the text flows on its side. And that’s it! the text can now flow in the float area of the element, defined by the custom shape we declared on it. You can also see that I've added a margin to the shape, to push the content away from the shape a little and create a gap. But we have one more thing to add here. Like I mentioned in a previous section, the background of the floated element is applied to its original rectangular shape, not just to the shape we declared on it, because the background property is not affected by the shape declared on the element. So far, the demo looks like this: Screenshot showing the background applied to the element covering its rectangular shape So in order to clip out the excess areas that we don't need, we're going to use the clip-path property, and give it the same value/shape that we gave to the shape-outside property above. So we add this rule to the rule set: And we're done! Simple, right? The page title on the left gets the same treatment as the .floated div on the right. The heading is floated inside its container .content, it is given a specific height and width to establish a coordinate system, and then a shape is declared on it using the shape-outside property just like we did on the .floated element. Using an image URI Another way we could define the shape on our element is by using an image with an alpha channel, that is, any image with transparent areas. For our example here, instead of using the polygon() function to define the shape, we’ll give the shape-outside property an image URI, and the browser will extract the shape from the image, and use it. The image that would define the exclusion area for this example is the one shown below. You can see that the image shows the same shape defined by the polygon() points in the previous method. Image with Alpha Channel whose URI will be used to extract and compute the value of the shape When you’re using an image with alpha channels to define a shape for the shape-outside property, the transparent area of the image will define the area where the inline text flows, this is the area called the float area of the element. The black portion defines the exclusion area of the element. To use this image we write the following: Each of the two methods mentioned has its advantages. You might want to use an image URI for complex shapes that may be cumbersome to define the points for manually, in this case creating an alpha channel image in Photoshop would be much easier and faster than manually adding the points. Another situation where you might want to use an image URI instead of a shape function is when you have multiple float or exclusion areas inside an element, in that case using this method is necessary because you can’t, for now, declare multiple shapes on an element, but if the image contains multiple areas, the browser will extract these areas from the image and use them. Pretty neat, right? :) we’ll see an example of this in the last demo. Exmaple #2: wrapping/flowing text inside a custom shape with shape-inside For the second example we’ll create a simple demo where the end result will look like this: Screenshot of demo #2 The goal of this example is to demonstrate the shape-inside property used to float text inside a non-rectangular shape. We have a container element with some placeholder text inside it, and we applied the photo as a background image to this container. As you can see from the demo screenshot above, the text is wrapped inside a circular shape at the top. So, we know that we’re going to have to declare a circle on our container. Now, like in the previous example, there are two ways we can do that.. Using circle() Using the circle() function we're going to define a circle and position it on our element. The image below shows the coordinate system established on the element, and the position of the circle inside the element. We’re making sure the circle is positioned on top of the pan image inside the photo we’re using as a background, so that it appears as if the text is contained inside that pan. On the image the position of the center of the circle with respect to the coordinate system established on the element is also visible. Coordinate system and shape defined on the container Because we want to wrap text inside a custom shape, and not flow it around it, we’re going to use the shape-inside property on the element containing this text. When you're applying the shape-inside property to an element, you have to remember that this element would have the text content inside it, unlike the previous example, where the content was outside the element we declared the shape on. We’ll specify the coordinates of the center of the circle and we'll set the value of its radius, and apply those to the container: Of course, unless you're attempting to create a perfect circular shape, you can also define the shape using polygon(). Using an image URI We can also use the URI of an image with an alpha channel to extract the shape of the circle from it. The image would look like the following: Image with Alpha Channel defining the circular shape It’s important to note here that when you’re using an image with an alpha channel to define a shape for the shape-inside property, the black (or opaque) area of the image will define the area where the text flows. In the previous example, the opaque area defined the exclusion area of the element we applied the shape to, i.e the area where no text flows. So declare the shape using an image URI instead of the shape function circle(), you'll have to set the value of the shape-inside property to point to the URI of the image: Example #3 : wrapping/flowing text inside a custom shape with shape-inside In this example we're also going to declare a polygonal shape on a container and have its content flow inside this shape. The end result will look like the image below: --> Screenshot of Demo #3 --> Here, too, we can use either a shape function or an image URI to declare the shape on the element. The shape declared on this container is clearly a "random" polygonal shape, not a geometric shape that we could declare using a shape function like circle(), ellipse(), or inset(), so we're going to use the polygon() function to declare it. The shape defined by a set of points is visible in the image below. The polygonal shape defined by a set of points Because there's a fairly large number of points making this shape up, it would be cumbersome to calculate the coordinates of these points, so it would be helpful if there was a visual tool available to help us plot these points on the image, right? Well, there is a tool created by Adobe's Bear Travis, which is actually a collection of tools that can help you when working with CSS shapes. Make sure you check the Shape Tools out because they are very valuable. One of the Shape tools mentioned is called Poly Draw, and it allows you to manually "draw" a shape, a polygon in particular, and then it generates the coordinates of the shape for you to copy and paste into your CSS to declare the shape on your element. I have used the Poly Draw tool to draw the above shape on the image. Now, the tool does not take an image and sets it as a background for the element you define the shape on, so I had to git clone the repo of the tool and fiddle with the tool’s code a bit in the dev tools, and I applied the image to it and plotted the points on it. Razvan Caliman suggested this idea when I asked him about the availability of a tool that allows us to define shapes on top of images right in the browser, just like the one he showed and used in his talk at this year's CSS Conf EU. If you haven't watched his talk yet, make sure you do. The tool he used will some day, soon I hope, be open-sourced by Adobe, and then it'll be an indispensible tool when working with CSS shapes. But until then, you could do with the Poly Draw tool. After drawing the shape with the Poly Draw tool, all you have to do is declare the resulting shape on your element and you're good to go. We could also define the shape above using an image with an alpha channel. The image below shows what that image would look like. Again, the black areas define the float area when using shape-inside, and they're where the text is going to flow. Image with alpha channel defining the shape for demo #2 If you want to go with the image URI instead of the shape function, youd replace the above shape outside value with the following: Example #4 : Multiple float areas with shape-inside In this example we're going to create multiple float areas inside an element to wrap content inside. The result of this demo is shown in the following image: --> Screenshot of Demo #4 --> We have a div with a background image, and we want the text inside this div to flow inside specific areas inside it, all of which have custom shapes. Now, since we can't declare multiple shapes on an element, we're going to use an image with an alpha channel. An image can contain as many shapes and areas as you want, so it's perfect to define multiple shapes on an element, and the browser will extract all the shapes from this image and use them on the element. We'll use the following image to define the shapes. The black areas in the image will define the float area of for the content inside the .container where the text will flow. Image with Alpha Channel defining shapes for demo #3 We'll use the URI of this image as a value for the shape-inside property that we're going to declare on the .container, all the while remembering to set height and width values for the div: And we're done. The browser does the rest of the work for us by extracting the shapes from the image we gave it, and our text flows nicely inside those areas! Using an image to define the shapes is the logical way to go when you have separate areas that are not connected to eachother, i.e that don't form a singe polygonal shape. For this demo, we could have used the polygon() function to define the shape, by defining a polygon that looks like the one in the image below: Image representing the points used to define a single polygon But, as you can notice, this isn't the best way to do this, I just added this to show the difference between using an image and defining the shape with polygon(), and to show that sometimes the best practice or the one that seems more proper and makes more sense is to use an image, even if you can use a shape function to define your shapes. Combining CSS Shapes with Regions and Flexbox to create magazine layouts Typical print magazines usually combine multi-column text layouts with non-rectangular shapes to create creative and appealing designs. The columns are usually equal in height unless needed otherwise. Once future CSS Shapes features are implemented, and wrapping content on both sides of a shape is possible, creating print-like digital magazine designs becomes very much possible when combining Shapes and Exclusions with Regions and Flexbox. Travel Magazine by Bartosz Kwiecień on Behance. Layout like this could be replicated using future CSS Shapes technologies and Regions () Flexbox provides us with the equal-height columns, Regions allows us to flow text into different areas on the page and separate the page content from its layout, and Shapes and Exclusions will allow us to add that final creative touch that takes our magazine layouts to the next level. Final Words I don’t think I’ve been excited about a new CSS feature as I am about CSS shapes and exclusions. The power, flexibility, and creativity that these features combined regions and flexbox can provide is just fantastic! Widespread support for CSS Shapes should be coming soon, as the web platform team at Adobe is constantly working on improving and implementing these features, and providing tools to make working with them easier. The future of web layout is looking brighter and more captivating every day. It's a wonderful time to be a web developer! I hope this article helped introduce you more to the technical part of getting started with CSS Shapes. This will not be my last article on this topic. Combining CSS Shapes with other cutting edge CSS technologies like Regions opens the door to a new world of creativity, and lots of new tutorials! ;) You should subscribe to my blog's RSS feed and follow me on Twitter to stay in the loop for upcoming new articles. Thank you for reading! Resources & Further Learning Bear Travis’s CSS Shape tools W3C's CSS Shapes Working Draft CSSWG Wiki on CSS Shapes and Exclusions use cases examples Adobe’s CSS shapes support matrix Adobe Web Platform's resources for CSS Layout This project by Bear Travis contains a series of exercises demonstrating new web platform layout features including an combining CSS Flexbox, Grid, Regions, Shapes, and Exclusions. CSS Exculsions article by Robert Sedovše This article wouldn’t have been possible without the great help from Razvan Caliman, so a big thanks goes to him.

Navicon Transformicons: Animated Navigation Icons with CSS Transforms

The following is a collaboration post between Bennett Feely and I. After seeing Bennett's impressive animated navigation icon transformations (or "Navicon Transformicons") pens on Codepen, I asked him if he would like to write a tutorial on how he did them as a guest post on my blog. He kindly approved. And as he doesn't have a lot of free time to work the article, we decided to collaborate on it. We'll be covering a few of the icons he created in his pen, and a couple more. If you were to ask me what my most favorite CSS property is I might just answer the transition property. It has proven to be a perfect use case for progressive enhancement and it’s adoption has made countless websites feel smoother. By the way, a heck of a lot of properties are also transitionable. While the prefixed transition property has been supported by the major browsers for a long time now (web speaking), there was quite a dilemma with browsers and their ability to transition and animate pseudo-elements (:before and :after). While Firefox has been doing things right since version 4.0, it wasn’t until March of this year when Chrome finally fixed things. Now, even IE10 supports transitions and animations on pseudo-elements. So what shall we call these transforming CSS icons? How about transformicons? browsers that support the properties used. As the Javascript is very simple (just toggling a class name) we won't be going over it, and you'll also find it in the downloadable source code on Github. Three-line to arrow (arrow left and arrow up) The Markup The three-line menu icon, aka navicon, aka hamburger icon can be accomplished quite a few different ways, but in this case we will use a wrapper element and a child with two psuedo elements to form the three lines. The markup really isn’t heavy. The SCSS First we’ll set up the wrapper around the actual navicon to trigger the transition. $button-size is the width of the lines of the navicon, not the entire target area. And now a mixin that we will use to make a single line. We are using the mixin in the .lines element and its absolutely positioned pseudo elements to create the navicon. We need to line up the transform origin of the pseudo elements (upper and lower lines) carefully if we want everything to line up perfectly. I created a simple pen to show where the transform origin goes and how the pseudo-elements are transformed.:before is red, :after is blue, and .lines is green. Check the pen out here. And here's a simple image to show the transform origins and how the pseudo-elements should align. When we hover over the three-line menu button in it’s original state, we’ll have it expand a little. Finally, let’s transform this three-line menu into a left arrow icon. For this demo, when the .lines-button wrapper clicked, we will add a .close class to it. The arrow looks better when it is scaled down a bit so we will do so using scale3d() rather than just scale(), which will trigger hardware acceleration and should make things run a bit smoother. For the :before and :after lines, we will shorten them a bit and overlay them all on top of each other. Finally, we rotate them 40° in opposite directions to each other. We have made an arrow! For the second navicon transformation into an arrow pointing upwards, the markup remains the same, we’ll just add a class of .arrow-up to the button. This icon will get the exact same styles and transformations as the previous one, but we'll rotate the icon in it's .close state by 90 degrees so the arrow points upwards. Three-line to — The markup for this one is, of course, the same as the markup in the previous section. The button in this example gets a .minus class, which defines the styles that will be applied to it. The SCSS To style this icon we’ll apply the same styles as above too down until the hover state. But where this icon will differ from the previous one is in the styles applied to it when it’s clicked, i.e in the .close state. This icon will transform into a “—” (like a minus sign), which can resemble a “collapse menu” icon, or “show less”, if you’re using it for a mobile navigation. The pseudo-elements (top and bottom lines) won’t be rotated so we’ll reset the transforms to none, and we’ll keep the width of the icon instead of shrinking it, and then we'll just overlay them on top of the .lines element to form one single line instead of three. Three-line to ✕ (#1) This icon will start out the exact same way the previous ones have. The markup structure is the same as the previous three-lines icons, with the same hover state expanding effect. For this transformation, the icon will get a .x class (resembles a transformation to an x shape). When the button is clicked, an .close class is added to it just like in the previous examples. But this is where the new transformation will be defined. The SCSS In order to transform the three lines into an ✕ shape, we're going to change the icon's background into a transparent one (the middle line will disappear), and the upper and lower lines (the pseudo-elements) will be rotated by 45 degrees in opposite directions and overlayed to create the shape. This transformation is very similar to the arrow transformation, but the key notes which make it different is keeping the width of the lines here instead of shrinking them like we did for the arrows, and keeping the transform origin at the center. Three-line to ✕ (#2) This transformation is inspired by the fifth transformation style from Pedro Campos’s pen on Codepen. We’ll make the markup for this one, of course, the same as the markup for all our buttons, with a specific class, in this case .x2. The SCSS This icon will start out with the same transformation as the three-line-to-minus icon, and when the first transformation is finished, the pseudo-elements will rotate and form the ✕ shape. We’ll apply the second transformation when the first one is finished, so for that we’ll need to set a delay for the transitions so that they don’t happen simultaneously. Where this transformation differs from the previous ✕ effect is the order of transformations and the added delays. For the previous effect we rotated and overlayed simultaneously, while in this case we're going to overlay, and delay the rotation till the overlaying is done, and then we'll rotate. We have added a delay on the transition for the lines so that the transformations happen in a row. Next, we’ll define the transition delays and transformations for the pseudo-elements. When the button is clicked, the upper and lower lines will first be translated to overlay on top of each other, the middle line’s background will be set to transparent to hide it, because we don’t want it to be there when the x is formed, and then each of two remaining lines will be rotated by 45deg (and -45deg for the opposite line) to form an ✕ shape. The trick here that’s different from the previous transformations is just to set the transform origin of the pseudo-elements to be their center, and add the proper transition delays. Grid to ✖ (#1) The Markup Similar to the previous markup, we have a .grid-button wrapping a .grid icon. The SCSS For this icon, instead of using psuedo elements we will instead leverage the power of the mighty box-shadow property. To make the code cleaner and easier to modify, we will create a $base and a $space variables. First we will style the .grid-button, wrapper. Now let’s get to the .grid icon itself and the crazy box-shadow property. Think of each comma-separated shadow as a it’s own sort of pseudo- element. It is very important to keep track of the order of each shadow in the box-shadow property or the animation will not look right. The box-shadow property is nice that when a color is not specified, the property simply inherits whatever the color property may be. In a situation like ours, it’s very helpful with an element with a ton of shadows that are the same color to simply leave out the colors and set it once with the color property. When we click on the button, we add the .close class to .grid-button. Because we'll be using two techniques to create an ✖ out of the grid icon, we'll be using two different class names for two two transformations. For the first one we'll use a .rearrange class name, as we'll be rearranging the box shadows. First we’ll spread the box shadows for the icon to form a grid. And when the icon gets the .close class on click, we’ll rearrange the shadows. We have removed all the spaces between the individual shadows (removed all the $space variables), and moved the four corner shadows inward and four side shadows outward by rearranging them. Last but not least, we rotate the whole icon by -45° and scale it, all using hardware acceleration to make the animation run smoothly. And with that we've achieved the first effect. Grid to ✖ (#2) For the second grid to ✖ transformation, we’ll be doing something very similar to what we did previously, but instead of rearranging the shadows we’re going to “collapse” four of them into the main element and bring the other four closer by removing the spaces and thus forming an ✖. We'll give the button with this effect a class .collapse. And when the button is clicked the .close class is added, and the shadows “collapse”. And we're done! I hope you liked these effects and found the tutorial useful!

Draggable Metro App Showcase

Today I'd like to share with you an interactive and touch-optimized metro app showcase concept for showcasing a metro (probably a Windows Phone) app screenshot. The screenshot will be draggable and swipable, and you'll have a couple of extra options to view how the app would look like in a mobile phone frame. Please note that this demo works only in browsers that support the Javascript objects and APIs used. I provided a couple of polyfills but the demo will only work in browsers that these polyfills provide fallback for. See the Javascript section for details. This demo is inspired by the big number of dribbble shots showcasing Windows phone app concepts, so I thought I'd recreate this showcasing concept and add some interactivity to it. The Flat Lumia Phone PSD Mockup used in the demo is by Corey Ginnivan from Dribbble. I provided two colors in the demo resources, a red and a white frame. The Markup We'll wrap our showcase in a as-wrapper wrapper, which will contain a container for the mobile frame + app screenshot, and a section for the app description which will appear at some point during the interaction (we'll get to that in a moment). The mobile frame and the screenshot will be positioned absolutely. The frame needs to be positioned absolutely to overlap the screenshot, and the screenshot will be positioned this way too so that we can change its position via Javascript. The phone frame we're using has 3 buttons in its lower section, what we're going to do is we're actually doing to add 3 buttons on top of these buttons with a transparent background, so that it seems like these built-in buttons are clickable. And then we're also going to add two navigation arrows to the right of the frame to scroll the screenshot left and right. The left-most arrow on the phone frame will scroll the app screen to the left to get it completely inside the boundaries of the phone frame. The windows button will scroll it back out to its initial position. The magnifier will launch the "focus" mode of the showcase, and the left and right navigation arrows will scroll the screenshot left and right respectively. You have probably noticed the class preventSelect that I adde to almost all elements, especially those inside the as-container. What this class does is that it prevents these elements (via CSS) from being selected, otherwise selected elements will get in the way of the drag action and things will get messy! The CSS I'll go over the styles quickly. All styles are basic and easy to understand so I won't be getting into too much detail. The "heart" of this demo is the Javascript part, the CSS is simple and pretty straightforward. I added comments to the CSS code where necessary. We'll start with the general styles relevant to the demo. So far all styles are obvious and straight forward. The frame and screenshot container is given a height equal to the height of the phone frame (simply because we don't need it to be bigger than that), and now we'll move on to the frame and screenshot styles. Note that we need to set the pointer events on the frame to none to make sure it doesn't block the events on the screenshot. Now we'll style and position the control and navigation buttons. Last thing we're going to style is the description section which will appear when the screenshot has been dragged fully into the inside of the phone frame. We'll make the demo as responsive as possible. I'm saying "as responsive as possible" because a draggable showcase like this will look best on big/desktop screens, because of the width of the screenshot, but we'll make it work for all screen sizes. :) On small screens we'll let the screenshot remain inside the phone frame with overflow set to hidden on the container. That's pretty much it for the styles. Now let's move on to the interactive part! The Javascript OK, first things first: polyfills and plugins. For starters, I won't be using any JS framework, we'll be going vanilla. I'll be using the awesome Javascript classList API, which is not fully supported in all browsers, but it's awesome so I'll be using it anyway, and I'll add Eli Grey's classList polyfill which works in IE8, and provides basic classList.add(), classList.remove(), and classList.toggle() support (which is more than enough for this demo) to at least as far back as Android 2.1. For browsers that don't support addEventListener, I'll be using Jonathan Neal's eventListener polyfill. Finally, I'll be using Hammer.js to add touch swipe support for the draggable screenshot. We'll start by caching some variables and initializing others with some basic calculations which we'll need throughout the code. wow that's a lot! so what exactly are all those needed for? First, I cached all DOM elements that we're going to listen for events on so we can attach event handlers to them next. Then, I determined the left and right offsets for each of the draggable screen and the mobile frame, because we'll be needing these for the scrolling and dragging functions. The right offset is calculated by adding the left offset to the width of the element. Next, we'll attach event listeners to the control and navigation buttons, and we'll also add the swipe support with Hammer.js. The scrollScreen(val, dir) function takes in two arguments: a val which is the amount (in px) by which we want to scroll the screen, and a dir which determines the direction in which we want to scroll it. = val){ left -= val; } else{ left -= deltaRight + 5; } } else if(dir == 'right'){ var deltaLeft = frameLeft - left; if(deltaLeft >= val){ left += val; } else{ left += deltaLeft; } } if(left = frameRight - 5){ el.style.left = left + 'px'; elRight = left + elWidth;// in case elRight = frameRight the desc shows showHideDesc(); } } function showHideDesc(){ if( elRight showHideDesc() is called, which shows and hides the app description section based on the position of the screenshot with respect to the frame: if the screenshot's right offset = that of the frame's right offset, i.e the screenshot is fully inside the frame, then the description is shown, else, it's hidden. When the left arrow button (the one on the phone frame) is clicked, the scroll function is called with a value equals to the width of the screenshot, which basically means: scroll the screen to the max until it's fully inside the frame. The focus button (the magnifier) will cause a mode change for the demo. When it is clicked, the container containing the phone frame and the app screenshot will shrink (by adding the .shrink class to it) to fit the size of the frame, and it's overflow is hidden, and it's centered in the screen, this way the frame will contain the app screenshot and you can drag/swipe left and right to view the app inside of it. (see image below) The last thing we're going to do is add the drag functionality to the app screen. We'll be attaching event handlers for mousedown, mousemove, and mouseup events, and their equivalent touchstart, touchmove, and touchend events to support touch devices. What will happen is that every time the mouse is down (i.e the drag starts), the position of the mouse/finger is saved, and the current left offset of the screen is calculated, and a value delta is also calculated, which determines the difference between the mouse position on drag start and the left offset of the draggable element (app screen). After that, as the mouse moves, its position is updated, and as its position changes so will the left offset of the draggable screen, as long as the boundaries of the screen don't exceed the boundaries of the frame from the left and right respectively: the right offset of the screen should not go below the right offset of the frame, and the left offset of the screen should not go above the left offset of the frame. Now that we've cleared up the logic behind the dragging function, here's the code for that function. = frameRight - 5 && elLeft mouseup (and touchend) event, that will call a function which in turn will remove the corresponding event handlers from the mousedown and mousemove events. And that's it, I hope you like this showcase and find it useful! :)

Building A Circular Navigation With CSS Transforms

In this article, we will learn how to apply CSS transforms to fake a "slice" shape, creating a circular navigation using nothing but CSS (and some maths!). The article includes an interactive demo that explains visually and step by step how the technique works and the shapes are created.

S Gallery: A Responsive jQuery Gallery Plugin with CSS3 Animations

Today I'm going to share with you a gallery plugin I built (yeah, like the world needs another gallery plugin, right?) after having stumbled upon SONY's products gallery while I was browsing their website a while ago. Their products' image gallery is a simple one, but two things grabbed my attention about the gallery: It's made with Flash when it can totally be created with HTML, CSS3 and Javascript. It has a neat feature: exiting the slideshow mode back to the grid view mode, the last image which was active in the slideshow mode "returns back" to its position in the grid view, thus the user knows where they have stopped and what images are left in the gallery that they haven't maybe browsed. This is a neat feature which serves as a brain cue and thus is a nice and positive UX-aware touch. Not to mention that the gallery is accessible by keyboard and you can navigate through the images via keyboard shortcuts, and enter into fullscreen mode with only the gallery being in fullscreen, therefore removing all distractions so that you can focus only on the products gallery. The plugin uses HTML5's FullScreen API, and relies heavily on CSS3 animations transforms, so it will work only in browsers that support these features. The Markup The markup needed for the plugin is simple: two unordered lists, the first one for the small versions of the images, and the second one for the big versions, wrapped in a container which I'll be giving an id of #gallery-container. The small images should be scaled versions of the big images, i.e they should all have the same aspect ratio for best results. One more thing is needed in the markup: the controls bar. The controls are used to (duh) control the slideshow and navigate through the images.. The class names are only CSS hooks, so you can change them, but make sure you change them in the stylesheet as well if you do. The control buttons use an image sprite for the icons, which will be included among the plugin assets. And that's all you need in the markup. Dependencies The plugin has two dependencies: the stylesheet for the gallery and jQuery. Also, if you decide to use the same icons for the gallery controls as the ones I'm using, don't forget to include them in your directory as well. Link to the stylesheet in the head of your page (or import the stylesheet to your main stylesheet and concatenate them if you use Sass and Compass). Link to jQuery from a CDN and the plugin script at the bottom of the page right before the ending body tag: In order to optimize this gallery for touch, I added hammer.js into a javascript file called plugins.js, which also includes Screenfull.js by Sindre Sorhus, which is a "Simple wrapper for cross-browser usage of the JavaScript Fullscreen API". You have an option to add full-screen support to your gallery, which you can specify in the options when you call the plugin by setting the value for the option to true (more on this next). Link to the script before you link to the plugin script: Using the Plugin Calling the plugin is very straightforward. The fullScreenEnabled option is set to false by default, you can enable it to add full-screen support by setting it to true: And that's it. I hope you like this plugin and find it useful!

Creative Add/Remove Effects for List Items with CSS3 Animations

It's not enough to bring animations and visual transitions to an interface, they should serve a purpose and goal, and this goal should be improving the user's experience. Transitions [...] provide the grease that smoothes out what happens in the interface. Without transitional effects the user can be left to wonder what just occurred. In today’s tutorial, we’ll be creating some creative animations and transitions for adding and removing items from a list, inspired by the concept from Pasquale D’Silva’s article on Medium. Chris Coyier coded the transitions from Pasquale’s article. In this tutorial I’m extending Pasquale’s example, adding more animations and transitional effects, and I’ll also be using a small snippet from Chris’s article to add an extra step in each animation, which “makes room” for the added items before they are actually added. browsers that support the properties used. So, let’s dig in! The Markup For demonstration purposes, I’ve built a simple reminders app. The app uses HTML5’s localStorage API to save the items to your browser’s local storage. So, you can actually use it to take in-browser notes if you want, it’s actually why I built it in the first place for my own notes. I’m not going to get into details of how to build this app because it’s not the purpose of this tutotial. The markup for the app is just a simple form with a text field and submit button, and an empty unordered list. The items will be added to the list dynamically. There’s also a couple of divs for the notifications which appear after saving or removing an item, and a counter and a button to delete all items at once. So here’s all the markup needed: Item Deleted. Undo?</div> <div class="notification save-notification">Item Saved</div> <div class="reminder-container"> <header> <h1>mini reminders list</h1> </header> <form id="input-form"> <input type="text" id="text" placeholder="Remind me to.."/> <input type="submit" value="Add" /> </form> <ul class="reminders"> </ul> <footer> <span class="count"></span> <button class="clear-all">Delete All</button> </footer> </div> You can add, edit, remove items, and restore them, and it’s actually the removing and restoring where the animations come in place the most. Adding the items is pretty simple, and not much of an animation happens there, except a fading in and falling down animation which we’ll get into as we start with the CSS, so let’s do that. The CSS New items added via javascript get a class of .new-item. Items removed get a .removed-item class, and restored items get a .restored-item class. Each of these classes fires its own animation. The class names are going to be the same for all demos, and it’s the animation @keyframes that will be different for each one. Let’s start with the first demo. Demo 1 Demo 1: Removed items "fall down". Restored items come back in a reverse animation. Newly added items are going to “fall down” from above. This is a very simple but nice effect. Each item starts at a position -400px above their final position, and fall down from that position. Don’t forget that the animation-fill-mode should have a value of forwards to make sure the items stays in their final position inside the list, otherwise it’ll just disappear up again as soon as the animation is finished. Removed items will “fall down” and fade out as they do. The falling down animation is also quite simple: the item is translated downwards along the y-axis, and is rotated as it is falling and faded out until it finally disappears (the Javascript makes sure the item is completely removed from the DOM at the end of this animation). Restoring the item fires an animation which visually reverses the above animation, so the keyframes defined are the exact opposite of the above ones: You can see that I used a keyframe called openspace which I borrowed from Chris Coyier’s article. This makes sure that the items blow the restored item will slide down and make room for the restored item to come back into place. Now, when the items “slide down” to open space for the restored item, they should actually transition down in a smooth manner, but because the items in my app don’t have a fixed height, the keyframes are animating the height to a value of auto, which unfortunately the browser doesn’t really “transition” to, so the items don’t actually “slide” down, they kinda jump down. There’s a way to make items change positions smoothly, it’s a technique by Steve Sanderson which he wrote about, but it uses absolute positioning, and a not-so-little amount of javascript. You can check his article out if you’re interested in knowing more about his technique, and the end result is pretty impressive! Demo 2 Demo 2: Items scale and fade out into the user's face, and are restored in a reverse manner. Credit for this idea goes to Tim Pietrusky who came up with this idea when I told him I was almost out of ideas after making the other 5 demos. :) Newly added items (i.e items that have not been removed and then restored) are faded in into position. When items are removed, they scale up and fade out into the user’s face, and are restored in the opposite way, the animation for restoring items is the exact same as the removing animation but only reversed. And that’s it for demo 2, now let’s move on to demo 3. Demo 3 Demo 3: Restored items slide in the from the right, and removed ones slide out to the left. The third demo is visually simpler than the previous demos. Newly added items will have the same fading in effect as in the previous demo, so we’ll be skipping the animation for these items. Items deleted will slide out to the left, with a nice touch at the beginning of the sliding achieved by using a cubic bezier timing function. You should check the live demo to see how the animation works. Restored items will slide in from the right, with a timing function similar to the above one, but it’s not really the reverse version of it (also check out the demo to see the final result). And that’s it for the third demo, now moving on to the fourth one. Demo 4 Demo 4: Restored items scale and fade in to position, and removed ones scale and fade out of view. This demo is also a simple one. Both new and restored items will be scaling in and fade in into their position, and the removed items will fade and scale out of view. Here are the two keyframes for these animations: Demo 5 In this demo, when an item is deleted, it “hangs” down before it actually “falls down” and fades out. This is kind of the best part of this demo, because the newly added items fall down as in demo 1, and restored items slide in from the right as in demo 3, but with a slightly different timing function, so the animation for removing an item is the only new effect in this one. changing rotation angle for the item at different frames gives the effect of the item “swinging” when it’s hanging, and then falls down. That’s all for demo 5, now to the last demo. Demo 6 Demo 6: Removed items slide out and fall down to the left. Restored and new items slide in from right. In this demo both newly added items and restored ones will get the same animation, where the items slide in from the right, “almost fall out” from the left, and get back into position. Items removed will slide slowly to the left, and then fall down to the left and fade out. Now, an important thing to do here is set an appropriate transform origin position, so that the falling down effect looks more realistic. I set the transform origin to the last point of contact between the item and the row is belongs to, right before it starts rotating and falling down, that way it looks that the item fell down due to its own “weight”. Final Words The possibilities are almost endless, there are lots of other more creative ways for adding/removing items into lists, I’m sure you can also think of your own effects, and I hope you find this tutorial inspiring! I didn’t get into the Javascript part because that’s not the focus of this tutorial. I should also note that there’s kind of a bug in Firefox which causes the page to “flash” or repaint whenever an item is focused on or out (i.e when you click the edit/save button). I don’t know if there’s a way around this, please let me know if you know what causes this flashing and if there’s a way to prevent it. For now, I can say that the demos are best experienced in Webkit browsers. Thank you for reading, I hope you enjoyed this tutorial, and if you did make sure you subscribe to the RSS feed to stay updated!

Horizontal Portfolio Layout with CSS3 Animations and jQuery

In this tutorial today we're going to create a horizontal portfolio layout with cool hover effects inspired by those on Guillaume Tomasi's personal website. The website is made in Flash, so I thought it would be nice to recreate the flash hover effect of the portfolio items using CSS3 animations and transitions, and some jQuery to replicate the image pan effect on hover. I've also added a simple falling down effect on scroll, where the portfolio items fall down as soon as they enter the visible area of the viewport. The artwork used in this demo is used with the permission of their owner Vlad Gerasimov. You can find the original images/wallpapers and more on his website VladStudio.com. Please note that this demo will work only in browsers that support the CSS3 properties used. For the sake of brevity in the example code, I am using the un-prefixed CSS properties, but you will find the prefixes in the downloadeable source code on Github. So, let's get started! The Markup Our list of items is literally a list of items each one with a class item. Each item contains a figure which in turn contains a .view container which wraps an image inside it, and a footer with two paragraph tags that contain the meta information for each image, and a small date tag with its own animation. The CSS Let's start with basic styles for the items before we get into the animations and hover effects. li { display: inline-block; /*aligning items by top baseline makes sure the baseline doesn't change once the hover effect is fired and therefore the other items stay put*/ vertical-align: top; } .item { width: 300px; height: 202px; margin: 150px 20px 0; padding: 5px; border-radius:2px; box-shadow: 0px 10px 10px -5px rgba(0,0,0,0.5); background-color: white; font-size: 14px; /*initially all items are moved 300px up and faded out and rotated, they will fade into view and back to position later via javascript*/ opacity: 0; position: relative; top: -300px; transform: rotate(-135deg); transition: all .3s ease, opacity 2s ease, top 1s ease; } /*even items will be 100px lower than their siblings*/ .item:nth-child(even) { margin-top: 100px; } Now that all items have been styled and placed, we'll define the styles for the inner components of each item. The figure will take up the full width of the parent. The image will get both a height and a width, and we'll apply a transition to the items so that they change smoothly on hover. The figcaption with the metadata will be positioned absolutely, and will be invisible at first so it gets a 0 opacity value. Now that we have all the items styled, we'll define what happens when each item is hovered. When the item is hovered, it increases in height, its padding is increased, thus decreasing the view or "viewport" for each image, while the image keeps its original size. We'll later add a panning effect to the image which makes it possible to view the whole image despite the fact that its viewport got smaller, by changing its position as the mouse moves over it; this is why the image is moved 20px to the left and upwards when its field of view decreases. We'll manipulate these positions with Javascript later. Also on hover, the date tag slides down, the footer is shown and the metadata slides in. Here are the keyframes defined for the above animations: When we defined the initial styles for the items, we defined their position and opacity so that they are not visible at first, but once they are within the viewport's visible area, they get a class (via Javascript) which makes them "fall down" into position. Here is the class added to the items on scroll: For extra styling purposes, we're gonna style the scrollbar of the items' list. But bear in mind that these styles are supported only in Webkit browsers. You can, of course, use one of several javascript plugins available to provide cross-browser scrollbar styles if it's necessary to your overall design. That's all the styling we need and all animations needed for the hover effect. Now we'll start defining the panning effect with Javascript and handling the list scroll function. The Javascript We'll start by defining the scrolling function which will first check for the position of an item on the screen, and return true if the item is in the visible area of the viewport, but it only checks horizontally. Now we're going to define the function what will call this function on the portfolio items to check for their visibility. We'll want to call this function as soon as the page has loaded to check for visible items and add the .falldown class to all items that should be visible in the beginning. Then, we'll want to call this function whenever the list is scrolled as well. The last thing we're going to do is add the panning effect for the images on hover. What this function does is that it checks the position of the mouse cursor when it moves over each image, and moves the image along with the movement of the cursor. It measures the distance between the cursor and the image's view boundaries, and then divides that by the part of the image that's hidden beyond the borders of the view, thus making sure the image does not move any extra than it should. The function calculations should make it clearer: One thing remaining is making sure the image returns to its initial position when the mouse leaves the item so that everything goes back to its initial state: To finish up, we're going to add mouse wheel support using jQuery Mouse Wheel plugin by Brandon Aaron: Aaand we're done! :) I hope you liked this simple hover effect and found it useful. Thanks a lot Fabrice Weinberg for helping me optimize and organize my Javascript code. :)

Lessons from the “Seductive Interaction Design” Book

In this article today, I’m going to share with you some of the lessons I learned from one of the best books I’ve read: Seductive Interaction Design: Creating Playful, Fun, and Effective User Experiences. I believe that you should read this book yourselves to fully appreciate all the information and insight the writer has to share. I will cover only the first half of the book. I will be pasting some excerpts, because there are many things that the writer describes a lot better than I could ever do. I will also be skipping a lot of the content for sake of brevity and of course because you should learn the rest from the book directly, not from me. Disclaimer: Images, blockquotes, and quotes are excerpted from Seductive Interaction Design: Creating Playful, Fun, and Effective User Experiences by Stephen P. Anderson. Copyright © 2011. Used with permission of Pearson Education, Inc. and New Riders. Seductive Interaction Design: Creating Playful, Fun, and Effective User Experiences. OVERVIEW Stephen Anderson shows you in this book how the same tactics humans use to attract a mate can apply to the interactions between humans and interactive devices, to make people “fall in love” with your websites and/or applications. The book focuses on human behavior, in both physical and digital contexts, and talks about what actually drives people and influences their behavior and “seduces” them into taking certain kinds of actions. It also studies a lot of examples of existing web applications, and explores the underlying psychological principles applied to the user experience of these applications, that make them as effective and successful as they are. One of the first examples mentioned in the book is LinkedIn and the effectiveness of the Profile Completeness process, specifically how LinkedIn manages to pull quite a bit of information out of millions of users through a series of prompts that are simple enough and yet very effective. By understanding what motivates people, they were able to get a lot of information out of them. And this is what the book is concerned with: why people do the things they do. The concept of level completeness used in LinkedIn can also be found in games as a “progress dynamic”, with points and levels. It can also be found in other contexts, one of which is martial arts, where each “level” is represented by a colored belt, one you earn while advancing towards the black belt. By having different colored belts [..] you get rewarded and recognized along the path to mastery. These belts are a tangible, achievable goal to work toward.But why do we do the things we do when we have this kind of progress dynamic? We could look at several ideas from psychology: Sequencing: We are more likely to take action when complex tasks are broken down into smaller tasks. Appropriate challenges: We delight in challenges, especially ones that strike a balance between being overwhelming and being boring. Status: We constantly assess how interactions enhance or diminish our standing relative to others and our personal best. Achievements: We are more likely to engage in activities in which meaningful achievements are recognized. So always offer your users some kind of reward after every step they make throughout a sign up form, or any other kind of forms that require several steps along the way to completeness, like surveys, for example, and be clear about why you’re asking for the information you ask for, and help them understand that whatever information you ask from them will actually benefit them, even if you have other reasons you’re asking them for this information. State your reasons in terms of how they would benefit the user to provide this information to you, because we’ve known that we are more interested in people who are interested in us. no one wants to sit and hear someone talk about themselves all night. The same is true in many online interactions. The writer then goes on to mention another example of great UX, which benefits both the user and the owners of the application, which is iTunes. He explains the process of signing up for iTunes in detail, and reveals the psychological part of the process, that makes users want to continue the process: Feedback loops: We’re engaged by situations in which we see our actions modify subsequent results. Curiosity: When teased with a small bit of interesting information, people want to know more. Visual imagery: Vision trumps all other senses and is the most direct way to perception. Recognition over recall: It’s easier to recognize things we have previously experienced than it is to recall them from memory. This kind of perspective offers you a new way to look at user experiences. For example, one example of UX that is different and very attractive and more enjoyable, in my opinion, is the new form and survey experience that Typeform offers, because it uses several concepts including sequencing and visual imagery, and they use images for a lot of their questions and offer multiple choices which are easier to use than having to recall stuff from memory. All these elements make filling up forms and taking surveys easier and more enjoyable, or at the very least, a lot less boring. Screenshot from the preview video on the Typeform website. The application offers users a set of images to choose from. Screenshot from the preview video on the Typeform website. The application offers users an image with the question. "Vision trumps all other senses and is the most direct way to perception". Usability and Psychology A simple and straightforward differentiation between the roles of usability and psychology in user experience design is the following: The danger is in confusing “ease of use” with actually desiring to use something. These are two entirely different things. Both are essential, but simply making something more usable won’t guarantee any more clicks or conversions. in this case, it was psychology that made this so engaging. Here is an image showing the difference in roles between usability and psychology in user experience design: An image representing the role of each of usability and psychology in user experience design. By using psychology to make your website/application move from being functional, reliable, usable, and convenient to being pleasurable and meaningful to the user. With this in mind, the writer then introduces a “user experience hierarchy of needs model” (shown in the image below) User Experience Hierarchy of Needs model. From bottom to top is a basic product maturity continuum: a top to bottom focus starts with the experience you want people to have. So if you want to create a revolutionary product, you have to think beyond basic functionality, usability, and convenience, and think about what kind of experience you want the user to have when using your product/website/application, but without forgetting the basics of usability. Aesthetics, Beauty, and Behavior The first “Weapon” of seduction is Aesthetics. This section explores the relation between aesthetics and human cognition, affect, and how aesthetics help our brains make certain associations between a product, and other real-life objects, and how these associations will end up affecting how we feel about it, and consequently how we behave. Aesthetics and Cognition Cognition is the process of knowing. Based on patterns and experiences, we learn how to understand the world around us [..] and aesthetics play a critical role in cognitive processing, that is, in the way we perceive elements in the digital context. The human brain has its own way of interpreting color, shadows, shading, and other natural occurrences, and the role of aesthetics is to communicate the functionality of the elements we see to our brains. They provide the brain with cues that communicate how we should interact with these elements. So, when designing, designers should think about what each color means, in addition to the role and meaning of shadows and shading. For example, think about a simple button (image below). The shadows, gradients, and beveled edges of the upper right button help the brain understand that this is in fact a button, and therefore it can be pressed, and that we can expect something to happen if we do. In this case, aesthetics communicate function. These shadows, gradients, and beveled edges are perceived affordances—cues that communicate how a user can, and should, interact with an object. translation: if it looks like a button, it must be a button. The second image shows how wrong usage of colors can confuse the brain about the actual meaning and functionality of an element, in this case an alerted message. The use of shadows also plays an important role in determining how elements look on a page, and which elements lay on top of others (stacking context), so special attention should be paid to these kinds of details. One of my favorite paragraphs in this book is this one in which the writer gives a golden tip: So, if you can build a physical model out of a digital design, then it can be interpreted correctly by the brain, otherwise it’s just not right! In addition to cuing the brain to understand the functionality and shape of objects, aesthetics play in a role in determining the relationship between these objects.For example, the law of proximity explains that if i place two or more items in a cluster together, you’ ll assume they are related. Then there is also contrast and connectedness.if one object has different characteristics from other objects, we perceive it as being different. This is known as contrast.” Additionally, elements connected by uniform visual properties are perceived as being more related than elements that are not connected. This is known as uniform connectedness. Additionally, aesthetics help us understand the “space” in which we interact, for example, placing elements behind each other in a 3D space to communicate distance. Another example is the famous “genie effect” animation in Mac OS X, which communicates where a file is being stored/minimized for easy retrieval later. Aesthetics and Emotion Some UX designers believe that by making a product easy to use and convenient, this will directly lead to creating a better, enjoyable user experience. But in this chapter, the writer proves that things that are enjoyable will be perceived as easy to use and convenient. Again to relate digital experiences to real-life interactions between people, Think of how quickly we form judgments about people in the first few moments after we meet them. Conversely, think about how our personal appearance (our personal aesthetic) affects the way people perceive us; or how product packaging influences our perception of the product inside. We may know better, but we continue to judge a book by its cover. The way products and interfaces look says a lot about them. Take for example an application with a lot of attention to details. When you see this kind of attention, you subconsciously trust the application you’re interacting with more. On the other hand, imagine a UI with inconsistent fonts, odd paddings, line heights, and such details that can butcher even the greatest designs, “how might these sloppy UI details affect our perception of the application?” How can you trust an application whose owner wasn’t attentive enough to care about these small details of their own product? How will they be able to pay attention to our needs if they can’t even pay attention to the small details in their product? There are also a lot of studies mentioned in the book that prove that not only do aesthetics affect perceived usability, they also influence actual performance. I’m going to mention only one short experiment for the sake of brevity: All the experiments the writer mentions lead us to one firm conclusion: Aesthetics and Associations Aesthetics play a major role in associations our brains make between objects. Our brains tend to try to connect objects to other objects, and when that is done it shares the characteristics of one of these objects with the other. The best way to explain this point is to just paste one of the (interesting) examples the writer mentions in the book: Apple products! In a 2005 essay on design and perceptions, Luke Williams recounts how another designer discovered why so many people think of the iPod as a “clean” device. Apparently, this designer had been sitting on the toilet (where all great ideas happen!) when it occurred to him that the iPod references the same materials used in a bathroom, “the shiny white porcelain of the bathtub and the reflective chrome of the faucet on the wash basin.” This might sound laughable, until you factor in that Jonathan ives, apple’s senior vice president of design, once worked for an agency that designed—you guessed it— bathroom appliances. Coincidence? Perhaps. What’s important is that “consciously or unconsciously, the iPod materials reference a convention of ‘cleanliness’ that everybody interacts with every day—a bathroom. We’re talking about human perception, and the system of conventions that shapes our perceptions. Perception is essential to the process of design. These aesthetic associations are evident in other apple products. If you own an apple laptop, you may have noticed the soothing sleep-light indicator that’s visible when your computer is “sleeping.” The rate at which this light fades in and out is comparable to that of the average respiratory rate for adults, about 12 to 20 breaths per minute. Coincidence? apple owns the patent for a Breathing status Led indicator (Us 6,658,577 B2), which “mimics the rhythm of breathing which is psychologically appealing". One final example: when apple launched the original iPod shuffle, they compared it directly to a pack of gum, due to the equivalent sizes of the two products. This is a great example of a conceptual metaphor, in which we make sense of new information by associating it with something we’re already familiar with. The Power of Faces Including faces in our online interactions also affects the associations our brains make, because faces carry with them some kind of associations, and can help build trust because of a higher fidelity of information that the application or website presents. One example to best explain this notion is Facebook's logout screen. Playful Seduction Techniques Be Fun We all like funny people. And by funny I don’t mean people who are always making jokes and trying to make you laugh, because those can become really annoying! By funny people I mean people who are fun to be around, who always have their way to make you smile, and who are great talkers, and can get a message to you in a fun way that sticks into your brains and that you’re more likely to remember later, and smile about it! By including humor in digital contexts, you engage people in a meaningful and memorable way. One of the examples that show the kind of fun you can use is the Southwest Airlines company. Some messages that the Southwest Airlines company uses that include fun phrases. Some may argue that humor is not always appropriate, so the writer has another golden advice to give: If it’s appropriate in a real-world interaction, why not online as well? Are we suddenly transformed into emotionless automatons when we sit in front of a screen? No. Humor is appropriate (or inappropriate) based on the situation, not the industry.” Be Unpredictable One of the simplest way to make an experience more enjoyable after repeated visits, is by breaking the routine. One of the simplest and most obvious examples of offering a slight surprise and breaking the routine is the Google Search homepage. The Google logo changes depending on the occasion. This little change adds a new flavor to our daily visits, that would otherwise be all boring and the same, especially that the Google homepage design is already too simple to start with. So add these little design touches help break the routine and keep our brains expecting something new at different occasions. Another example of breaking routines is for example changing the content of a confirmation message every time it pops up so that it’s different every time, or changing an image on the homepage after repeated visits, or delightful messages that pop up in unexpected places. These messages don’t have to be necessary, yet they could be pleasant enough to stick in the head of your users or readers. One perfect example of a delightful surprise the writer mentions is a note he saw while he was going up the stairs in a hotel, where he was surprised by a “Everything is going to be alright” written in uppercase on one of the stairs (image below), that made him grin, and was so pleasant that he still remembers it and thought it was worthy of mentioning as a great example in his book. These kinds of small delightful surprises make the interaction with the digital world seem more human, which is a very important aspect if you’re trying to sell yourself as a trustworthy person. So what makes a good present or surprise? Another golden advice from the writer: Think of the word pump: P is for pleasurable, U is for unexpected, M is for meaningful (useful, not generic), and the last P is for pleasantly packaged. Be Mysterious In new relationships, flirtation often involves some element of playful teasing, and a similar kind of teasing can be applied to the relationship between users and a website or application. Curiosity is a powerful human drive that pushes us to do a lot of the things we do. It’s probably the reason why I read the book in the first place. I was curious to know how a website or application can be “Seductive”, I was even more curious after I started reading to understand how people think, and understand how my brain works, and why I do the things I do. Part of the role of usability is make things clear to the user, and remove all roadblocks and ambiguous elements that make a user experience become a rather frustrating one. Just like we have to care about the basics and make an application or product usable and functional, and after that we can cross that line to make it pleasurable and memorable, we can also start thinking about adding some kind of controlled uncertainty to the experience after having provided the user with the clarity he needs, thus introducing a level of thrill and suspense to the experience. Sometimes giving the user all the information they want from the first visit rids them of their interest and leaves no more room for curiosity to drive them forward to further explore the application at hand. You want to make sure that you tease them with as little information as necessary, enough to drive them into the “curiosity zone”. Information can be presented in a manner that is straightforward or curious. If we opt for the latter, we are guaranteed not only attention, but probably higher engagement as well— curiosity demands that we know more! [..] <p>When we become aware that information is missing—when something changes from being known (or so we thought) to an unknown state—we become curious. This is the explanation of curiosity posed by behavioral economist George Loewenstein in his information gap theory. Loewenstein says, “curiosity happens when we feel a gap in our knowledge.”</p> [..] <p>The feeling we get from these information gaps is best described as deprivation, which is critical to understanding why we are motivated by curiosity. to “eliminate the feeling of deprivation,” we seek out the missing information.</p> [..] <p>Simply stated: I’m curious because there’s a gap between “what I know and what I want to know.</p> It’s human to be curious. And it’s part of our nature to seek to solve mysteries around us. The kind of curiosity the writer refers to in his book is akin to teasing. Teasing people by making them aware that there is something they don’t know. But there are a few ways to make this teasing effective, and I believe the most important one is to let them know that the information you’re hiding away from them will benefit them the most. Also, make sure that once they get to the point where they uncover the information you withheld from them at the beginning, they find that this information meets their expectations, the expectations they built because of you. Also, don’t lure users with something that is given away freely elsewhere. Let others express themselves around you The final principle in the playful seduction section is self-expression. Giving the users the ability to express themselves in your application, by giving them, for example, the ability to customize the application and make it more personal, is very important when the users expect this kind of option to be available to them, and even when they don’t! Some examples of allowing users to express and apply their personal identity to an application would be to allow them to change the theme, or use custom emoticons, or change the content and add/remove what they want, change the layout and theme, and so on. If you’re one of the people who use Windows’ MSN chat application, then you definitely know that for the past couple of months or more, the company was preparing MSN users to switch, or “upgrade”, to Skype. I am one of the individuals who sincerely hated this “upgrade” for one simple reason: Skype doesn’t allow you to use custom emoticons. And after reading a lot of comments on the Skype blog, I realized that I am only one of so many people who hated this “upgrade” as well, and my intention was very clear: to not make the switch. Why? Because my MSN is customized to my needs, and Skype doesn’t allow you to add custom emoticons. I love custom emoticons. I can’t chat without them. And I really believe this should not be called an upgrade because IMO to upgrade means to make better, and when your newer version lacks a lot of the best features of your previous one, then this, IMO, is more of a downgrade. Microsoft should’ve given this move a lot of thought before actually deciding to move forward with it. The point is, giving your users the ability to customize your application or express themselves in any way is a great way to make the application feel more personal and thus enjoyable for them. And if you ever decide to do that, please don’t take that option away from them later. If you add it to your app, just make it stick. Final Words I only covered the first two sections of the book in this article. The amount of information, tips, and insight I wrote here is just a drop from the sea of what you can find in the book. The next two sections are titled “The Subtle Art of Seduction” and “The Game of Seduction”, with a lot more insight and tips in them. If you’re a UX designer, a designer, a web developer, or any person interested in learning more about human behavior, or interested in making your products more popular or trying to build a stronger online existence, then this is definitely a must-read for you. I cannot recommend this book enough. After reading this book, I’m definitely never going to look at applications and UX like I used to, because it gave me a lot of insight, and helped me see and understand the reasons behind successful user experiences, and taught me how I could apply these principles even to a small website, not just a huge application. I hope you enjoyed this article and found it useful. Thank you for reading!

How to Create Windows-8-like animations with CSS3 and jQuery

I have recently realized that CSS3 3D transforms have been out there for quite a long time now and yet I haven't experimented with them yet. I have also been using Windows 8 for a while now, and the first thing that struck me as impressive about it was the transitions and animations built into the dashboard, so I thought it would be really cool if my first experiment with CSS 3D transforms would be to recreate those animations and effects. So, here goes the tutorial on how I did that. Please note that this demo works only in browsers that support the CSS3 properties used. For the sake of brevity in the example code, I am using the un-prefixed CSS properties, but you will find the prefixes in the downloadeable source code on Github. The Markup The demo's structure is pretty simple: The dashboard is a list of tiles, of three sizes, small, big, and 2xbig, floated inside 3 columns. And then there are their corresponding "pages". A page is an overlay which opens when u click on one of the boxes on the dashboard. It represents an app on desktop, with each of the tiles being the shortcut to that app. Each tile will open up a corresponding page. There are two kinds of page transitions included in the Windows 8 dashboard: one that opens the page in a 3D rotating effect from the right of the screen, and one that slides the page in and back to the left. We will define a class name for each type of page as s-page for the pages that slide from and to the left, and r-page for pages that rotate open from the right. Now, for each tile, we need to specify what type of page it opens (depending on the effect you want for that page). We will define the type of the page for each tile in a custom data attribute called data-page-type, this will take care of applying the right class names triggering the right animations later on. Each page should also have a name. The page name for a certain app will be different from that of another app, so the "Skype" tile opens up a page called "skype-app" for example. I've used only two page names in this example, which are repeated for all tiles, and used a custom-page name for the last tile for sake of example. You'll probably have to add a different page for each tile, hence a different page name specified in every tile. Here's the markup for the whole dashboard (tiles and pages): The icon font I'm using is from Icomoon. What will happen is that the Javascript will get the name and type of page to be opened when a tile is clicked, and then, according to the type of the page, it will apply specific class names to the page (whose name we have also retrieved from the data-page-name attribute) to open it with the specified type of animation for each class applied. The CSS Please note that I'm taking a mobile-first approach to the styles, which we'll then make responsive in the media queries section. First, the styles for the demo wrapper, the container in which the whole demo will be contained. We'll define general styles, and make sure to set a perspective to activate the 3D space, otherwise, the whole demo will look flat and two dimensional. Now let's start with the dashboard styles and animations. The first animation applied to the dashboard is fired when the page loads. The dashboard is initially hidden and translated to the right of the screen, and fades and translates in to position on page load. The dashboard also fades into the view and fades back when a tile is clicked. Once a tile is clicked, the dashboard translates back along the z-axis, decreases in size, and fades its opacity gradually till it becomes 0. And when an opened page is closed, the dashboard fades back into the view. The three columns in the dashboard fade in one after the other, with a slight delay between them. When a page is closed, a class name is added to each column (via Javascript), and each of these classes calls the animation with a certain delay. Here are the classes and the animations applied to the dashboard upon clicking the tiles and closing the pages: Now we're going to style the pages. I've set the original position of each r-page in the 3D space by first rotating it about the y-axis (the vertical axis), then I moved the page 5em to the left of the screen by using translateZ. Always remember: when u transform an element in 3D, you transform its coordinate system along with it. What I wanted to do is move the page 5em to the left of the screen, but instead of using translateX I used translateZ, because after the first tranformation (rotation about y axis), the coordinate system was also rotated, so now the z-axis points towards the left, and the x-axis is pointing towards you, the viewer. All the pages, except the s-page app page, have the same initial position in the 3D space. The s-pages, on the other hand, are positioned -150% left of the screen off canvas, so that they slide into view when their animation is fired. These are the class names that trigger the opening and closing of the pages, along with the animations defined for each class. I'm using the animation shorthand property here. The last value forwards corresponds to the animation-fill-mode property, which must be set to forwards, otherwise the page will get back to its initial "closed" position after the animation is over. So, in order to keep the page open, and be able to create sequential animations, the element has to stay in the final state defined by the first animation, and from there start the second animation. These are the animations for the classes applied to the pages: Last but not least we'll style the dashboard tiles and define the transitions and animations applied to them when they are hovered. General styles defining the size of the tiles: A couple of tiles contain an image along with an image caption. These tiles will get a class fig-tile to determine their type in the Javascript code. The colors used for the text and background of the corresponding page will be retrieved from the colors of the caption, so don't forget to define them.The caption can be either fixed, or it can slide in when the tile is hovered: Regular tiles, with no special kind of animation, will change their background and text color on hover. In order to make sure the text is vertically centered in each tile, each one will contain a div with a paragraph containing the text. We'll use the table-cell display property to center this text vertically. I'll skip the general styles of the tiles for sake of brevity, but make sure you set a background and text color on all tiles, even the ones that will be covered by an image, because these colors will be retrieved via Javascript and set as the colors for the corresponding page of this tile. Let's move on to the animations and transitions on the tiles. Tiles with text sliding inside of them will contain two divs, each div will be like a "face" or a block inside the tile. These divs are positioned absolutely, and moved on hover according to the direction of slide we want. For a tile's text to slide up on hover, we'll apply a class slideTextUp. Similarly, tiles with text sliding to the right and left, will get class names slideTextLeft and slideTextRight, with a similar structure as the above tile. A couple tiles have a different hover effect, they rotate to reveal the back face of the tile. This effect is a very simple and basic "card flip" effect. I won't get into the details of this effect, but if you're new to this, you can read more about it in this excellent tutorial by David De Sandro. For this flipping effect, apply a rotate3d class to the tile you want to flip. For a card with a vertical flip we'll add a class rotate3dY, and for a horizontal flip we'll apply a class rotate3dX (in addition to the rotate3d class), and we'll apply the following styles: We'll rotate one of the faces in the tiles so that the two faces are back to back. And when the tile is hovered, the .faces div will be rotated to reveal the back face. For styles rotating in 3D, remember to set a background and text color for the .front face, so that these colors be retrieved and set to the tile's page when it is opened. And that's all for the styles and animations! Now let's define responsive styles for the dashboard. Dashboard columns are initially full-width on small screens (remember we're starting mobile-first), and they will be floated next to each other on big screens. The Javascript All click events will be handled wtih Javascript. I'll be using jQuery for this example. Event handlers are going to be set on each of the dashboard tiles, and when a click event is detected, we're going to retrieve the name and type of the corresponding page from the data-page-type and data-page-name attributes, and use these to open the page. Other click events will be handled when clicking on the close button in each page. The close button for each page type will apply the suitable class names to close this page type. Additionally, in order to give each page the same background color and text color as its corresponding tile, we will first loop through the tiles, retrieve its colors, and then applies it to its corresponsing page. If a tile has a rotate3d class, it looks for the background-color of the front "face" of the tile, and applies that to the page. And that's it! I hope you enjoyed this tutorial and found it useful! :)