Web Standards

An Event Apart: The Way of the Web

LukeW - Mon, 04/02/2018 - 2:00pm

In his The Way of the Web presentation at An Event Apart in Seattle, Jeremy Keith discussed building for the Web today and how to manage the rate of change of technologies and tools for Web development. Here's my notes from his talk:

  • Science fiction is not about predicting the future, it is about looking at the concerns we have today and projecting them forward. Novels are empathy machines. You can really get into what the characters were feeling/experiencing and thereby share their concerns.
  • While science fiction books get some things right about the future, they also have blind spots. For instance, people went to phone booths instead of carrying mobile phones. In the present we have a future that was almost beyond what was predicted in seminal works of science fiction.
  • With where technology is today and what is possible, are we in a utopia or a dystopia? Are we excited or afraid of technology's possibilities. What makes the difference? Why are we excited about some technologies and apprehensive about others?
  • Working on the Web can be overwhelming as we have to endure constant changes in technology and processes. When that rate of change is especially steep, things get worse.
  • Stewart Brand's pace layers outline the rate of change of everything from people to buildings. Fashion changes quickly, culture changes slowly, and that's good. We get apprehensive when things that should move slow start changing too quickly. Example: quick changes in government are usually revolutions.
  • The materials of the Web (HTML, CSS, and Javascript) move slow and are more stable, they are lower pace layers. The tools of the Web move much faster and are more subject to change.
  • If a technology helps the developer but not the end user, there's a balance that needs to be understood. Is the trade-off of developer convenience worth a large download for users?
  • We can map Web technologies to pace layers. The bottom layer is the Internet (TCP/IP). This hasn't changed in decades and you don't want it to change. HTTP is the protocol layer above this and is changes very slowly, which is appropriate. URLs are the layer above, which change often but probably shouldn't. HTML and CSS are changing much more quickly but still not as fast as Javascript.
  • Every week there is a new Javascript library, which is where the Web feels apprehensive. Ideas get vetted out in Javascript and when they stabilize, they move down to HTML and CSS. It's ok that Javascript changes quickly -it needs to in order to work out new ideas.
  • You can choose to build single page Web sites in Javascript only. Going directly to URLs and HTTP. However this sets up a works great or doesn't work model. The power of the Web is that we have different levels of "working", a continuum. Everybody gets something with these in-between levels of experience.
  • The rule of least power: "choose the language of least power to accomplish something" It's not as powerful, but much more stable. Instead of doing everything in Javascript, see what can be done in HTML and CSS first.
  • The Web favors ubiquity over consistency. You can get to the content but it may not look the same to everyone. Start with the simplest element (like a select) and gradually apply styling/code to layer on additional enhancements.
  • This mode of building for the Web isn't just for simple sites. Even "complex" sites can be broken down into simpler elements. There's actually a continuum between simple and complex.
  • Progressive Web apps are Web sites that add HTTPS, a Web app manifest, and a service worker. This layering of technology allows sites to not only run securely but also offline.
  • People want browser features to be supported everywhere before they start using them, but that's not how it works. You can start using these elements now even if they only have partial support and get the benefits where they're available.

An Event Apart: Performance as User Experience

LukeW - Mon, 04/02/2018 - 2:00pm

In his Performance as User Experience presentation at An Event Apart in Seattle, Aaron Gustafson shared a number of ways to optimize Web page performance. Here's my notes from his talk:

  • Our jobs as designers is to reduce friction for our users. Poor performance causes friction and can negatively impact key metrics like conversion and revenue.
  • How do Web pages load: when you enter an address in a URL bar, a DNS look-up replies with an IP address, then there's a TCP handshake followed by the actual request for files/data, once there's a response the browser can actually do something.
  • Once the browser gets a response, it can assemble the document object, the render tree, layout, paint, and finally load. CSS and Javascript can delay this process and sometimes cause it to run again.
Steps for better performance
  • Use native features whenever possible. They are effectively free. Semantic elements not only reduce bytes but also contain attributes that provide a lot of functionality like placeholder, autocomplete, autocorrect, type, etc. System fonts can help reduce the need for custom font downloads. Font stacks can cover fallback issues.
  • Only include assets you actually need. Every tool has a cost, make sure you are really using enough of each tool to justify that cost. Chances are the tool you are trying to use is already on a CDN and you can use resource hints to speed up the download process. But downloading isn't everything as Javascript frameworks also take time to execute, which is slower than native JS processing.
  • Optimize everything. Task runners like Grunt and Gulp can help automate optimizations of Javascript, CSS and HTML. Minify and pre-compress all your files.
  • Think about when you load assets. If you have Javascript files divided into modules, you can defer functions you won't need until the after the DOM is loaded. The async attribute also allows you to load files when it makes the most sense. Just make sure you don't hit any race conditions if some of your Javascript files have dependencies on others.
  • Why so many different files? Under HTTP1, each resources was requested sequentially. Now with HTTP2, you set a single connection and then stream in resources as needed.
  • Consider how you load assets. Start simple by loading just your default (often mobile) CSS file. You can add a media query as a threshold for loading more advanced CSS in browsers than can render it. Conditional comments (which only work in IE8 and below) can either load or hide elements from older browsers. Similar techniques can be used to conditionally load images and animations (via SVG support).
  • Only load assets when they add value. Not every article needs an image, think twice before you include it. Images are 53% of the average web page and very expensive size-wise. If you need an image, use the right format. GIFs ae good for solid colors, JPGs for photographs, PNGs are JPG alternatives with alpha transparency, WebPs are note well supported but optimized in many ways.
  • Images can be optimized by removing color, blurring parts of images, resizing, compressing, and using appropriate formats. We can use the picture element to add WebP images in browsers that support them. Remember to put your smallest files first, because the first one that works is what gets used.
  • Every choice we make affects our users’ experiences. Let’s spend our time to save it for our users.

An Event Apart: Navigating Team Friction

LukeW - Mon, 04/02/2018 - 2:00pm

In her Navigating Team Friction presentation at An Event Apart in Seattle, Lara Hogan discussed what causes teams at work to have issues and how to address them. Here's my notes from her talk:

  • Teams of people are amazing. Its a privilege to work together with people to make things.
  • Bruce Tuckman found a series of stages that groups of people go through: forming (comes together in a new state), storming (some friction emerges), norming (clarity begins to emerge), performing (effective state). This is a cycle that repeats itself regularly.
  • Storming is a natural part of team dynamics but it does create friction. You need to be able to move past the friction in order to focus on what actually matters.
  • It can take a while for managers to identify and resolve points of friction. So what can team members do to address the issue earlier on?
Core Needs
  • Everyone transforms into different versions of themselves sometimes. The rationale part of our brains isn't always in control. Instead, we may be reacting to fear and/or threats that put us into fight or flight mode. These reactions come from more than use physical safety and shelter needs.
  • Modern humans have several core needs. First, people need to belong to a group or community. Second, people need to make improvements and/or progress (for team, company, or personally). Third, people need to be able to make choices about their work -they need flexibility, and decision-making capabilities. Fourth, people need access to equal resources, information, and fairness. Fifth, people require some amount of predictability in their work days. Lastly, people need to feel their work matters -they need recognition and visibility for work.
  • The BICEPS model (the needs above) gives you a way to assess what could be causing team friction.
  • As an example, moving desks are a great example of why people react emotionally to seemingly sound rationale decisions. They impact belonging, choice, predictability, etc. but do so differently for different people. To address these issues, try to identify the core need being effected.
  • To find which core needs are being impacted, look at the types of resistance you are seeing. Doubt: asking lots of questions/debating the issue. Avoid: not showing up. Fight: people create arguments against the issue. Bond: go to friends & peers to find support. Escape-route: changing roles, leaving company to avoid the threat.
Communication Style
  • When you spot some signals, ask open questions (which are different than yes/no questions). This helps you understand which core needs are being threatened on the team. Then you can figure out how to address the issue.
  • Reflect on the dynamics of the room, what are they thinking and/or worried about? Be aware of your medium: what words, body language are you using?
  • When you make an ask of someone, consider if they can act on what you are saying. Don't tear things down, try to elevate the conversation by being transparent.
  • Assume everyone has the best intentions at work and try to empathize with what other people may be going through.
  • Listen to learn: stay genuinely curious. Operate under the assumption that you don't know the whole story. Be excited to have your mind changed, it helps you learn and grow.
  • Humans aren't great at feedback but we can get better. Good feedback is specific and actionable. This kind of feedback helps us improve and grow.
  • Structure your feedback as: observation of a behavior (just the facts)+ impact of that behavior (share how you feel) + question or request. Write it out first to make sure it's communicating what you want.
  • It's ok to cause some friction, that's a natural part of working together. But know how you can move past it.
  • Retrospectives allow people to know their feelings have been heard. Name friction points in these meetings to acknowledge what didn't work.
  • Team charters and docs can helps align people's work against a common vision and clear responsibilities.
  • The absence of trust is the source of most team dysfunctions. How do you get these issues surfaced within a team? Determine if you agree or disagree with decisions and whether or not you can commit to a decision.
  • If/when you need to go to HR or leadership, state what's been tried and what you think could help now. Be prepared that they may take a different action after weighing the situation.

IBM Plex

Css Tricks - Mon, 04/02/2018 - 11:32am

Here’s a free new font for IBM Plex, a family of typefaces by the iconic company of the same name. It's on Google Fonts if you want to use it.

And we're talking about a multifaceted font. It touts having:

  • Roman and Italics
  • Four subfamilies
  • Eight weights
  • Support for 100 languages

The site promoting the font is noteworthy in and of itself. It's been designed to showcase how the typefaces were built as a single, complex system and tells the story in interactive sections using a parallax effect. Even if you’re not a big fan of the typefaces themselves (although I certainly am), it’s still super interesting to see how they visually describe the challenges they faced when in the design process. There’s lots of weird and interesting UI things going on here.

If you love news about companies making their own fonts, there have been a few others lately like U.S. Soccer's 90 Minutes and Netflix Sans.

Direct Link to ArticlePermalink

The post IBM Plex appeared first on CSS-Tricks.

What HQ Trivia Can Teach Us About UX

Usability Geek - Mon, 04/02/2018 - 9:19am
Dear reader, I am sad to report that I have been dragged back in. At first, I had dismissed it as a fad, another Flappy Bird or Trivia Crack. Then, after tentatively dipping my toe in its waters, I...
Categories: Web Standards

Catching up on AMP News

Css Tricks - Mon, 04/02/2018 - 8:55am

The big news since we last talked about AMP is that the AMP team announced that there will be a way for non-AMP sites to make their way into the coveted Google search results carousel. Malte Ubl:

Based on what we learned from AMP, we now feel ready to take the next step and work to support more instant-loading content not based on AMP technology in areas of Google Search designed for this, like the Top Stories carousel.

You can't do it now, nor is it clear exactly how you'll be whitelisted, but apparently Google is open to it. The ticket in will be utilizing hopefully-someday standardized things like Feature Policies, which, like AMP, disallow certain features in the name of... well that's the thing. It used be be in the name of speed, but the messaging seems to be more like in the name of privacy and security now. Also a good goal, just funny that "Pages" is about the last thing left in the AMPcroymn. Sorry.

This is the checklist of related technologies. Makes my eyes glaze over a bit as I know precious little about any of them. Much of it needs to progress through standards processes and browser implementation first, and we'll just have to see how practical it all is. If it means people stop creating amp-dot version of their websites (the new m-dot), that'd be pretty swell.

Tim Kadlec and Yoav Weiss got shout-outs in that AMP announcement for their idea of a "Content Performance Policy". As in, if a website promises and upholds the promises of being fast and not doing nefarious crap, it gets the same benefits as an AMP site.

I mention that as Tim has some new AMP data to share, directly related to AMP's speed. Tim found 50 random news article pages that were using AMP and tested them various ways. I'll summarize the results in best to worst order:

  1. The non-AMP version: not great
  2. AMP version standalone: a bit better
  3. AMP version with cached copy of AMP library: a good bit better
  4. AMP version from Google Search: instant

Tim mentions that it isn't very useful to test against those instant results:

evaluating AMP’s performance based on how those pages load in search results tells us nothing about the effectiveness of AMP itself, but rather the effectiveness of preloading content.

If we can adhere to some standards-based stuff and get Google doing that same preloading for those of us who'd rather not amp-dot, that'd be great. Show me the money. Did I do that movie reference right? I never saw that movie.

The post Catching up on AMP News appeared first on CSS-Tricks.

Know JS online event

QuirksBlog - Mon, 04/02/2018 - 5:24am

On 13th of April the inaugural Know JS online conference takes place. I’m tangentially involved, though I will not speak. The conference is online, and runs from 9am to 6pm Eastern on 13th of April. You can attend from the comforts of your own house.

Know JS is a fairly special type of online conference. Four speakers, Kyle Simpson, Bianca Gandolfo, Kent C. Dodds, and Jem Young, will give not a conference talk, but a full two-hour workshop about a topic of their choice. By buying a ticket you get access to all four of these workshops.

In addition, all four speakers will release a pre-recorded short presentation that sets the tone for their workshops, and these presentations will be available for anyone, not just for ticket holders. They will be published as they come in, starting today.

Tickets are $299, and we decided to cap their number at 50, so that some sort of live interaction between the attendee (that’s you!) and the teacher is possible.

This is a fairly unique type of conference, and credit wholly goes to Kyle, who came up with the idea. His fellow organisers, Brian Rinaldi and me, thought this was a very interesting take that we should try. So here we are, trying it.

This project started with Brian and me meeting in Sofia, and since we’re both conference organisers the conversation quickly turned to conference organising. We found that both of us would like to run a JavaScript event that was not focused on one or more of the popular framenworks, but instead on the language itself. We feel this topic is somewhat underrepresented in today’s conference cycle.

We decided to get Kyle Simpson on board, and our thoughts started to run toward an online event. Although all three of us would prefer a real conference, we weren’t sure how well the topic would be received. So we’re testing the waters, as it were, and if this event is a success, we’ll probably make the jump to an offline conference, ideally with editions in the States and in Europe.

We’ll see what happens next. But if you’re interested in JavaScript the language, please take a good look at what we’re offering.

Iron Man’s Arc Reactor Using CSS3 Transforms and Animations

Css Tricks - Mon, 04/02/2018 - 3:29am

Alright Iron Man fans, fire up your code editors! We are going to make the Arc reactor from Iron Man’s suit in CSS. Here’s what the end result will look like:

See the Pen Iron Man's Arc Reactor by Kunal Sarkar (@supersarkar) on CodePen.

The Full Page Wrapper

We will make our Arc reactor on a dark full-page background. Here’s our code to make a full page wrapper element:

body { margin: 0; } .fullpage-wrapper { height: 100vh; background: radial-gradient(#353c44, #222931); }

Why do we declare no margin on the body? The <body> element has some margin set to it by default in the user agent stylesheet. This prevents the elements inside the <body> to touch the edges of the screen. Since we want our wrapper to cover the entire screen, edge to edge, we removed that default margin on <body> element by setting it to 0.

We’ve given our .fullpage-wrapper the full height of the viewport. We don’t have to specify a width because a div is full width by default. We could have gone with another approach by setting both the width and height of the element to 100% but that comes with some possible drawbacks as more elements are added to the screen. Using viewport units ensures our wrapper always occupies the full vertical space of the screen, regardless of what it is or what other elements are added to the layout.

We also used a radial gradient on our wrapper using radial-gradient() CSS function. The parameters inside the function are the color start and end points. So, the center of the background will be more #353c44 and more #222931 towards the edges. It’s subtle, but a nice touch.

Centering the Reactor Container

Before we start creating our reactor, let’s create a container for it and center it:

.reactor-container { width: 300px; height: 300px; margin: auto; border: 1px dashed #888; }

This gives us a 300px x 300px box with dashed border. The margin: auto; declaration ensures equal horizontal spacing.

But why it doesn’t center it vertically?

Per CSS2 specs, if we give auto margin to the left and right side, then the entire available space will be equally divided to left and right margin. This isn’t the same case for the top and bottom margin though. For top and bottom margin the CSS2 spec says:

If margin-top, or margin-bottom are auto, their used value is 0.

However, we do have a good news. The flexbox layout follows new rules of alignment, and here’s what the Flexbox spec has to say:

Prior to alignment via justify-content and align-self, any positive free space is distributed to auto margins in that dimension.

This means if the element in consideration is displayed as a flex item, then margin: auto; will work in both the directions. Let’s make our wrapper a flex container and its child elements flex items:

.fullpage-wrapper { width: 100%; height: 100vh; background: radial-gradient(#353c44, #222931); display: flex; }

There, that’s much better:

There are many other methods to center elements in HTML. There’s a detailed guide on centering right here on CSS-Tricks to learn more.

The Reactor Core: Concentric Circles in CSS

We know that new elements in HTML are created from left to right (for left-to-right languages), or top to bottom. Elements never overlap, until you provide some negative margin.

So, how are we going to display concentric circles? We will use absolute positioning.

The default value of position property is static. Static and relative positioning follow the flow of top to bottom and left to right. However, an absolutely positioned element is not treated as a part of the document flow and can be positioned anywhere using the top, right, bottom and left properties.

Let’s start by creating the smallest circle:

<div class="fullpage-wrapper"> <div class="reactor-container"> <!-- the smallest circle --> <div class="core-inner"></div> </div> </div> .core-inner { position: absolute; width: 70px; height: 70px; border-radius: 50%; border: 5px solid #1b4e5f; background-color: #fff; }

We need to center this div. You might be tempted to apply the same flexbox concept we used on the reactor element to center this circle as well. But, here’s what CSS2 spec has to say about setting margin: auto; on absolutely positioned elements:

If none of the three (top, height, and bottom) are auto: If both margin-top and margin-bottom are auto, solve the equation under the extra constraint that the two margins get equal values.

This means if an absolutely positioned element has any value for top, height and bottom other than auto, then setting the top and bottom margin to auto will center the element vertically.

Same case for horizontal centering: if an absolutely positioned element has any value for left, width and right other than auto, then setting the left and right margin to auto will center the element horizontally.

That means we don’t need flexbox layout to center an absolutely positioned element with a known height and width. We just have to make sure that we give some value to top, right, bottom and left other than auto. So, we will use 0:

.core-inner { position: absolute; width: 70px; height: 70px; top: 0; right: 0; bottom: 0; left: 0; margin: auto; border-radius: 50%; border: 5px solid #1b4e5f; background-color: #fff; }

We do not want to repeat these five lines for all the concentric circles we are going to have, so let’s create a separate class for this. We also don’t want to define border-radius: 50%; for all the divs that we want to display as circles, so we will create a class for that too:

.circle { border-radius: 50%; } .abs-center { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; } .core-inner { width: 70px; height: 70px; border: 5px solid #1b4e5f; background-color: #fff; }

Also, add these new classes to out .core-inner element:

<div class="fullpage-wrapper"> <div class="reactor-container"> <!-- the smallest circle --> <div class="core-inner circle abs-center"></div> </div> </div>

Okay, our concentric circle is centered. Let’s make it glow.

But CSS doesn’t have any "glow" property.

Don’t worry, we have the box-shadow property. Instead of giving the shadow a dark color, we will give it a bright color to make the shadow look like glow. Pretty clever, isn’t it? &#x1f609;

Let’s do this:

.core-inner { width: 70px; height: 70px; border: 5px solid #1b4e5f; background-color: #fff; box-shadow: 0px 0px 7px 5px #52fefe; }

Let’s take a break and understand the syntax of box-shadow first because we will be using it a lot. Here are what those values for box-shadow mean in that order:

  • x-offset: how much we want to push the shadow on the right side (x-axis). Negative values will push the shadow to the left side.
  • y-offset: how much we want to push the shadow up or down (y-axis).
  • blur-radius: how blurry we want our shadow to be.
  • spread-radius: how much we want our shadow to spread.
  • color: color of the shadow.

Play with these values a bit to see their effects in real time.

In real life, shadows don’t drop only outside of an object. Shadows drop upon the objects too. Imagine a pit dug by a dog, it will have a shadow inside it, right?

We can give a shadow inside an element using the inset keyword in the box-sizing property. To give an element both, outside and inside shadow, we simply separate them with a comma. Let’s do this to get an outside and inside glow to our reactor’s inner core:

.core-inner { width: 70px; height: 70px; border: 5px solid #1B4e5f; background-color: #fff; box-shadow: 0px 0px 7px 5px #52fefe, 0px 0px 10px 10px #52fefe inset; }

Now it’s starting to look sci-fi!

Let’s create one more circle on top. We want the inner circle to display on top of the other circles, so we will add new circle divs *above* the inner-circle in code:

<div class="fullpage-wrapper"> <div class="reactor-container"> <!-- the second circle --> <div class="core-outer circle abs-center"></div> <!-- the smallest circle --> <div class="core-inner circle abs-center"></div> </div> </div>

The elements down in the code, are displayed above on the screen. If we put the core-outer below the core-inner in the code, then core-inner won’t be visible, because core-outer will cover it.

Let’s give style to outer-code. The outer core will be a little bigger than the inner core and we will give an outer and inner glow to core-outer too:

.core-outer { width: 120px; height: 120px; border: 1px solid #52fefe; background-color: #fff; box-shadow: 0px 0px 2px 1px #52fefe, 0px 0px 10px 5px #52fefe inset; }

I want you to do one thing: look at the shadows (glow) and try to identify which one is of which circle. There are four shadows and two circles (until now).

To finish designing the core, we will need one more circle that will wrap the inner and outer circles:

<div class="fullpage-wrapper"> <div class="reactor-container"> <!-- the third circle --> <div class="core-wrapper circle abs-center"></div> <!-- the second circle --> <div class="core-outer circle abs-center"></div> <!-- the smallest circle --> <div class="core-inner circle abs-center"></div> </div> </div>

This one will be a little bigger, and will again have same shadows, we will use a dark background for core-wrapper:

.core-wrapper { width: 180px; height: 180px; background-color: #073c4b; box-shadow: 0px 0px 5px 4px #52fefe, 0px 0px 6px 2px #52fefe inset; } Creating Reactor Coils and Rotating with CSS3 Transforms

We have the core of the reactor, now we need a tunnel around the core. Actually, we can create an illusion of a round tunnel by drawing just one more circle little bigger than the core-wrapper. Let’s do it:

<div class="fullpage-wrapper"> <div class="reactor-container"> <!-- the largest circle --> <div class="tunnel circle abs-center"></div> <!-- the third circle --> <div class="core-wrapper circle abs-center"></div> <!-- the second circle --> <div class="core-outer circle abs-center"></div> <!-- the smallest circle --> <div class="core-inner circle abs-center"></div> </div> </div>

...a little wider and add same glow to the tunnel:

.tunnel { width: 220px; height: 220px; background-color: #fff; box-shadow: 0px 0px 5px 1px #52fefe, 0px 0px 5px 4px #52fefe inset; }

Our tunnel is ready.

Make sure you do not just copy paste the code. Have a look at the glows of the circles and identify which glow is of which circle, whether it is outside glow or inset glow.

Now, we need eight coils on this tunnel. The coils are simple rectangles, but the major challenge is that we need the coils to run along the round path of the tunnel; not in straight line.

One way to do this would be to create eight small rectangles, shift their center to the center of the reactor, and rotate each coil by an increasing angle (in multiples of 45deg).

Let’s not complicate it and make one rectangle coil at a time:

<div class="fullpage-wrapper"> <div class="reactor-container"> <div class="tunnel circle abs-center"></div> <div class="core-wrapper circle abs-center"></div> <div class="core-outer circle abs-center"></div> <div class="core-inner circle abs-center"></div> <div class="coil-1"></div> </div> </div> .coil-1 { position: absolute; width: 30px; height: 26px; background-color: #073c4b; box-shadow: 0px 0px 5px #52fefe inset; }

Now, we want to place this coil in the center at top of the tunnel. Like this:

Our reactor-container is 300px x 300px, so the center is at 150px from top and left. The tunnel is 220px wide, so its radius will be 110px. This gives us the top offset of the coil: 150px - 110px.

We can keep left of the coil to 150px, but since our coil is 30px wide, it will shift the middle of the coil by 15px to right, that’s why we need to subtract 15px from 150px to get the left offset of the coil.

We can either calculate these ourselves and put the value, or we can use the CSS calc() function. Let’s use the CSS calc() function to calculate the top and left properties of the coil:

.coil-1 { position: absolute; width: 30px; height: 20px; top: calc(50% - 110px); left: calc(50% - 15px); background-color: #073c4b; box-shadow: 0px 0px 5px #52fefe inset; }

As you can see, the calc() function takes a mathematical expression as its argument and solves it.

Now we need eight such coils but they must lie on the tunnel. To do that, as discussed, we can simply place the eight coils at this same place, then transform their origin to the center of the reactor, and rotate each coil by an increment of 45 degrees.

We need to update the coil’s origin because by default it is set to the center of the coil; we want it at center of the reactor:

We will use transform-origin property to set the origin of the coil:

.coil-1 { position: absolute; width: 30px; height: 20px; top: calc(50% - 110px); left: calc(50% - 15px); transform-origin: 15px 110px; background-color: #073c4b; box-shadow: 0px 0px 5px #52fefe inset; }

The first value, 15px, in transform-origin is the x-offset (horizontal distance) from the top-left corner of the element, and the second value, 110px, is the y-offset (vertical distance) from the top-left corner of the element.

The coil’s origin is now at the center of the reactor, let’s rotate it by 45 degrees using the CSS3 transform property and see what happens:

.coil-1 { position: absolute; width: 30px; height: 20px; top: calc(50% - 110px); left: calc(50% - 15px); transform-origin: 15px 110px; transform: rotate(45deg); background-color: #073c4b; box-shadow: 0px 0px 5px #52fefe inset; }

Great! That’s exactly what we want.

Before creating all the eight coils, let’s create a coil container div that will contain all the eight coils:

<div class="fullpage-wrapper"> <div class="reactor-container"> <div class="tunnel circle abs-center"></div> <div class="core-wrapper circle abs-center"></div> <div class="core-outer circle abs-center"></div> <div class="core-inner circle abs-center"></div> <!-- the coil container --> <div class="coil-container"> <div class="coil coil-1"></div> </div> </div> </div>

You will notice we also added a class "coil" to the "coil-1" element. We will keep all the common styles for coils in the "coil" class, and the individual coil element classes will only have their angle of rotation:

.coil-container { position: relative; width: 100%; height: 100%; } .coil { position: absolute; width: 30px; height: 20px; top: calc(50% - 110px); left: calc(50% - 15px); transform-origin: 15px 110px; background-color: #073c4b; box-shadow: 0px 0px 5px #52fefe inset; } .coil-1 { transform: rotate(45deg); }

The output will remain same.

Now, let’s make all the eight coils inside .coil-container:

<div class="fullpage-wrapper"> <div class="reactor-container"> <div class="tunnel circle abs-center"></div> <div class="core-wrapper circle abs-center"></div> <div class="core-outer circle abs-center"></div> <div class="core-inner circle abs-center"></div> <!-- the coil container --> <div class="coil-container"> <div class="coil coil-1"></div> <div class="coil coil-2"></div> <div class="coil coil-3"></div> <div class="coil coil-4"></div> <div class="coil coil-5"></div> <div class="coil coil-6"></div> <div class="coil coil-7"></div> <div class="coil coil-8"></div> </div> </div> </div>

...and give different rotations to all the coils (in increment of 45 degrees):

.coil { position: absolute; width: 30px; height: 20px; top: calc(50% - 110px); left: calc(50% - 15px); transform-origin: 15px 110px; background-color: #073c4b; box-shadow: 0px 0px 5px #52fefe inset; } .coil-1 { transform: rotate(0deg); } .coil-2 { transform: rotate(45deg); } .coil-3 { transform: rotate(90deg); } .coil-4 { transform: rotate(135deg); } .coil-5 { transform: rotate(180deg); } .coil-6 { transform: rotate(225deg); } .coil-7 { transform: rotate(270deg); } .coil-8 { transform: rotate(315deg); }

Our reactor is almost ready.

Animating the Coils With CSS3 Animations

In Iron Man’s Arc reactor, the coils don’t move but they will in our reactor. We will animate the coils to rotate along the tunnel and will use CSS3 animations for this—no JavaScript.

To create an animation, you need to know the initial and final states of the object you are going to animate. We define these initial and final states in CSS by using @keyframes at-rule:

@keyframes reactor-anim { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

We want the element to be at 0 degrees and animate it until it reaches 360 degrees. And we named this animation as "reactor-anim."

The element we want to animate is .coil-contailer. Notice, we didn’t define which object to animate yet, we have only defined the initial and the final state and name of the animation.

We need to link the element to the animation in order to take effect. We do it by using animation-name property on .coil-container:

.coil-container { position: relative; width: 100%; height: 100%; animation-name: reactor-anim; animation-duration: 3s; }

Notice, we also gave the duration of animation using animation-duration property. This defines how much time it should take to go from the “from” state to the “to” state defined using the @keyframes at-rule.

See the Pen Arc-Reactor-Ease-In by Kunal Sarkar (@supersarkar) on CodePen.

We need to change two things here: we want the animation to go on infinitely and we want a linear animation. You can see the animation is slow at the beginning, then fast, then again slow at the end—this behavior is defined by the timing function of an animation.

Let’s make these changes:

.coil-container { position: relative; width: 100%; height: 100%; animation-name: reactor-anim; animation-duration: 3s; animation-iteration-count: infinite; animation-timing-function: linear; }

We used animation-iteration-count property to set the animation to infinite, and animation-timing-function to make the animation linear, the default value of animation-timing-function is ease.

See the Pen Arc-Reactor-Linear-Infinite by Kunal Sarkar (@supersarkar) on CodePen.

We can combine all of these animation properties...

animation-name: reactor-anim; animation-duration: 3s; animation-iteration-count: infinite; animation-timing-function: linear;

...into one shorthand property like this:

animation: 3s infinite linear reactor-anim; Final Touches to the Reactor Container

Our reactor is ready, now let’s make some final changes to the .reactor-container. First, we will need one dark circle behind the reactor:

<div class="fullpage-wrapper"> <div class="reactor-container"> <!-- dark circle behind the reactor --> <div class="reactor-container-inner circle abs-center"></div> <div class="tunnel circle abs-center"></div> <div class="core-wrapper circle abs-center"></div> <div class="core-outer circle abs-center"></div> <div class="core-inner circle abs-center"></div> <div class="coil-container"> <div class="coil coil-1"></div> <div class="coil coil-2"></div> <div class="coil coil-3"></div> <div class="coil coil-4"></div> <div class="coil coil-5"></div> <div class="coil coil-6"></div> <div class="coil coil-7"></div> <div class="coil coil-8"></div> </div> </div> </div>

Let’s give a dark background and add some glow to it:

.reactor-container-inner { height: 238px; width: 238px; background-color: rgb(22, 26, 27);; box-shadow: 0px 0px 4px 1px #52fefe; }

See the Pen Arc-Reactor-Semi-Final by Kunal Sarkar (@supersarkar) on CodePen.

See how the dark background and the glow creates an emboss effect?

Next, let’s make the .rotator-container round and give it some shadow and border, then we are done:

.reactor-container { width: 300px; height: 300px; margin: auto; border: 1px dashed #888; position: relative; border-radius: 50%; background-color: #384c50; border: 1px solid rgb(18, 20, 20); box-shadow: 0px 0px 32px 8px rgb(18, 20, 20), 0px 0px 4px 1px rgb(18, 20, 20) inset; }

See the Pen Iron Man's Arc Reactor by Kunal Sarkar (@supersarkar) on CodePen.

Cheers! Our Arc Reactor is ready and even with a little animation as an added bonus. To level this up, we could explore using custom properties to create reusable variables for our color and number values for easier maintenance. Similarly, we could look into using a preprocessor—like Sass, Less or PostCSS—to write functions that do the mathematical lifting for us. Would love to see examples like that in the comments!

The post Iron Man’s Arc Reactor Using CSS3 Transforms and Animations appeared first on CSS-Tricks.

An Event Apart: Content Performance Quotient

LukeW - Sun, 04/01/2018 - 2:00pm

In his Beyond Engagement: the Content Performance Quotient presentation at An Event Apart in Seattle, Jeffrey Zeldman introduced a new metric for tracking how well Web sites are performing. Here's my notes from his talk:

  • The number one stakeholder request for Web sites is engagement: we need people using our services more. But is it the right metric for all these situations?
  • For some apps, engagement is clearly the right thing to measure. For others, more time spent might be a sign of frustration.
  • Most of the Web sites we work on are like customer service desks where we want to give people what they need and get them on their way.
  • Content Performance Quotient (Design CPQ) is a metric of how quickly we can get the right content to solve the customer's problem. The shortest distance between problem & solution. This tracks your value to the customer by measuring the speed of usefulness.
  • Pretty garbage: when a Web site looks good but doesn't help anyone. Garbage in a delightfully responsive grid is still garbage.
  • Slash your architecture and shrink your content. Ask: "why do we need this?" Compare all your content to the goals you've established. Design should be intentional. Have purpose-driven design and purpose-driven content.
  • We can't always have meetings where everybody wins. We need to argue for the customer and that means not everyone in our meetings will get what they want. Purpose needs to drive our collaborations not individual agendas, which usually leak into our Web site designs.
  • It’s easy to give every stakeholder what they want. Don't take the easy way out. It’s harder to do the right thing. Harder for us, but better for the customer & bottom line.
  • Understanding the customer journey allows us to put the right content in the right place. Start with the most important interaction and build out from there. Focus on key interactions and build out form there.
  • Customers come to our sites with a purpose. Anything that gets in the way of that is a distraction. Constantly iterate on content to remove the cruft and surface what's needed.
  • When you want people to go deeper and engage, to slow down... scannability, which is good for transactions, can be bad for thoughtful content. Instead slow people down with bigger type, better typographic hierarchy, more whitespace.
  • Which sites should be slow? If the site is delivering content for the good of the general public, the presentation should enable slow, careful reading. If it’s designed to promote our business or help a customer get an answer to her question, it must be designed for speed of relevancy.

An Event Apart: Scenario-Driven Design Systems

LukeW - Sun, 04/01/2018 - 2:00pm

In her Scenario-Driven Design Systems presentation at An Event Apart in Seattle, Yesenia Perez-Cruz shared lessons learned building design systems for multiple brands/Web sites and how specific user-scenarios are key to making flexible solutions. Here's my notes from her talk:

  • Design systems have helped many organizations build better, more cohesive experiences faster. but what's really behind a design system? is it a set of components? a common language? or something more?
  • A good design system feels cohesive, unified, and connected. It achieves something.
  • Bad design systems fail when there's too much focus on elements and not enough focus on how common components work together to create an experience.
  • We need to start our design systems with user-scenarios, not with individual components.
Starting with Elements
  • Vox wanted a design systema nd common platform for their 8 brands and 350+ Web sites. They made a lot of assumptions in the beginning that didn't work. Primarily: a set of flexible, brand-agnostic modules with a theming system would give them the most range. Essentially, legos.
  • This approach was too focused on layout and the end result was that each of the sites felt too similar. Critical content and focus differences were missing. The end result did not not allow Vox to tell better stories faster, as it only defined common modules not ways to solve common user problems.
  • Vox learned they needed to start with something specific in order to develop a flexible system. You can’t start with individual components because successful design patterns don’t exist in a vacuum.
Starting with Purpose
  • The next iteration of Vox's design system started with people and content. What goals did the audience have? What range of content and tone needed to be supported? What was the editorial workflow of the people making content?
  • This requires user-scenarios driving design not hypothetical situations. We need to ground our design systems in tasks people and companies actually have not trying to account for "what if" ideas.
  • Instead of starting with an inventory of UI components, start with an inventory of core workflows/tasks, and then identify common patterns in these workflows. All patterns should solve a specific problem.
  • Identify core workflows and the patterns that need to support these workflows. Understand the role each pattern plays in a user’s journey. Define how the patterns work together to create a cohesive experience.
  • Thinking and organizing a design system in terms of workflows, makes it easier for teams to know which patterns to apply when faced with a user problem.
  • At Vox, a scenario-based design system allowed the team to turn 18 distinct templates into a unified structure. They identified common audience goals but supported variants driven by differences in content.
Supporting Variants
  • Variants can help components address specific user-scenarios by highlighting specific content that matters to audience goals. These content-specific components can be re-used across themes/brands.
  • Scenario-driven variations can help brands feel unique/deliberate vs. becoming too generic/unspecific.
  • Naming elements very specifically helps people agree on their function. This ensures each element supports the right level of customization & functionality.
  • How do we theme a design system? Brands need to support distinct visual designs that support the unique audience and content within a site.
  • When varying fonts across brands, you need a flexible type scale to ensure legibility across different font faces. Similarly, color variables can be used to manage different colors schemes across brands.
  • When should you support variations in your design system? Only add a layout if there’s a content need. Does it add value? Is it available to more than 3 brands? Is it a must-have for 1 brand?
  • When are variations in your design system a bad thing? Visual variation on components that serve the same function across brands and/or don’t do much to strengthen brand voice.
Finding a Balance
  • There's a constant push/pull between appropriate levels of consistency and customization. Finding the right middle ground is a constant process of iteration.
  • Successful design patterns don't exist in a vacuum. Instead of focusing on individual components, look at the ecosystem: the people, content, and complete design. Successful design systems solve specific problems and start with people & content.

w descriptors and sizes: Under the hood

Css Tricks - Sun, 04/01/2018 - 3:23am

Eric Portis digs into how the browser decides which image to downloads when you give it <img srcset="" sizes"">. Notably, a browser can do whatever it wants:

Intentionally un-specified behavior lets browsers provide innovative answers to an open-ended question.

Still, calculations happens based on what you give it and you can still do a good job with that part.

The very weirdest part about all this is that the sizes attribute can alter an images "natural width", which can lead to unexpected upscaling, a thing we're trained to loathe. If you're in that situation, you can either...

  • use an inline width attribute
  • set an inline style with a max-width
  • embrace the fact you might experience occassinal upscaling

Direct Link to ArticlePermalink

The post w descriptors and sizes: Under the hood appeared first on CSS-Tricks.

A DevTools for Designers

Css Tricks - Sat, 03/31/2018 - 3:39am

There has long been an unfortunate disconnect between visual design for the web and web design and development. We're over here designing pictures of websites, not websites - so the sentiment goes.

A.J. Kandy puts a point on all this. We're seeing a proliferation of design tools these days, all with their own leaps forward. Yet...

But, critically, the majority of them aren’t web-centric. None really integrate with a modern web development workflow, not without converters or plugins anyway; and their output is not websites, but clickable simulations of websites.

Still, these prototypes are, inevitably, one-way artifacts that have to be first analyzed by developers, then recreated in code.

That's just a part of what A.J. has to say, so I'd encourage you to read the whole thing.

Do y'all get Clearletter, the Clearleft newsletter? It's a good one. They made some connections here to nearly a decade of similar thinking:

I suspect the reason that nobody has knocked a solution out of the park is that it's a really hard problem to solve. There might not be a solution that is universally loved across lines. Like A.J., I hope it happens in the browser.

Direct Link to ArticlePermalink

The post A DevTools for Designers appeared first on CSS-Tricks.

Tracking Uncertainty of Work

Css Tricks - Fri, 03/30/2018 - 9:24am

Ryan Singer writes about project and time management issues that I’ve been experiencing lately. He describes two states of every project: uncertainty and certainty, or “figuring things out” and “making it happen.”

Ryan describes it like this:

Work is like a hill with two sides. There's an uphill phase of figuring out what to do and how to approach the problem. That’s the climb. After you reach the top, there aren’t anybody [sic] ruinous unknowns. You can see down to the other side and finish executing. It's straightforward to estimate and finish the work from that point.

As far as I see it, the hardest thing about the first half of every project is making sure that everyone on a team is communicating constantly as tiny design decisions can have enormous, cascading effects on an engineer. I think that’s something I’ve always struggled with since I just want to get to the "making it happen" part as soon as humanly possible. It also goes back to something Geoff wrote a little while back about setting good expectations before and during the project process.

Direct Link to ArticlePermalink

The post Tracking Uncertainty of Work appeared first on CSS-Tricks.

Vue Design System

Css Tricks - Fri, 03/30/2018 - 3:51am

We talk a lot about Vue around here, including some practical applications of it, but haven't gotten deep into designing for it. In this post, Viljami Salminen describes his Vue design process and the thinking that led him to build the Vue Design System:

A design system can help establish a common vocabulary between everyone in an organization and ease the collabo­ration between different disciplines. I’ve seen it go the other way around too when important decisions have been made in a rush. To avoid that, Vue Design System introduces the following framework for naming that I’ve found working well in the past...

Viljami lists Design Principles, Tokens, Elements, Patterns, and Templates as the way in which he structures a system and I think it’s a pretty interesting approach and a parallel to Lucas Lemonnier's post on creating design systems in Sketch, using Atomic Design as the structure. I particularly like how Viljami fits everything together in the example style guide that’s provided.

Direct Link to ArticlePermalink

The post Vue Design System appeared first on CSS-Tricks.

Solved With CSS! Colorizing SVG Backgrounds

Css Tricks - Fri, 03/30/2018 - 3:41am

CSS is getting increasingly powerful, and with features like CSS grid and custom properties (also known as CSS variables), we’re seeing some really creative solutions emerging. The possibilities are still being explored on what CSS can do to make writing UI’s simpler, and that’s exciting!

One of those is now one of my favorite CSS features: filters. Let’s look at how we can use filters to solve a problem you may have encountered when working with SVG as a background image on an element.

CSS Filters

First, let’s start by with an overview of filters. They include the following functions:

  • blur()
  • brightness()
  • contrast()
  • drop-shadow()
  • grayscale()
  • hue-rotate()
  • invert()
  • opacity()
  • saturate()
  • sepia()

These effects can also be achieved with SVG filters or WebGL shaders, but CSS filters are the easiest way to implement basic transformations in the most browser-efficient manner. Because they are shortcuts of SVG filter effects, you can also use filter: url() and specify a filter effect ID onto any element. If you want to play around with custom filters, I recommend checking out cssfilters.co.

The Problem: Editing SVG Backgrounds

I love using the SVG (scalable vector graphics) format for web design. SVG is a great image format for the web, and since it’s based on code, it allows for high-quality responsive and interactive content. When you inject SVG onto the page, you have access to each of its internal elements and their properties, allowing you to animate them, update values (such as color), and dynamically inject additional information. SVG is also a great icon format, especially instead of icon fonts, and in smaller UI elements due to its high quality (think: retina screens) and small image size (think: performance).

I find that often, when SVG is used for these smaller elements, or as a large area of illustration, it’s included as a background image for simplicity. The drawback to this is that the SVG is no longer under your control as a developer. You can’t adjust individual properties, like fill color, of an SVG background because it is treated just like any image. This color conundrum can be solved with CSS! Filters to the rescue!

Adjusting Brightness

The first time I discovered the SVG background challenge was when I was working on a website that had white SVG icons for social share icons that lived on a background determined to match that application. When these icons were moved onto a white background, they were no longer visible. Instead of creating a new icon, or changing the markup to inject inline SVG, you can use filter: brightness().

With the brightness filter, any value greater than 1 makes the element brighter, and any value less than 1 makes it darker. So, we can make those light SVG’s dark, and vice versa!

What I did above was create a dark class with filter: brightness(0.1). You can also do the opposite for darker icons. You can lighten icons by creating a light class with something like filter: brightness(100) or whatever is suitable to your needs.

Icons with a fill color of #000, or rgb(0,0,0) will not brighten. You need to have a value greater than 0 in any of the rgb channels. fill: rgb(1,1,1) works great with a high brightness value such as brightness(1000), but even brightness(1000) will not work on pure black. This is not an issue with light colors and white.

Adjusting Color

We’ve now seen how to adjust light and dark values with a brightness() filter, but that doesn’t always get us the desired effect. What if we want to inject some color into those icons? With CSS filters, we can do that. One little hack is to use the sepia filter along with hue-rotate, brightness, and saturation to create any color we want.

From white, you can use the following mixtures to get the navy, blue, and pink colors above:

.colorize-pink { filter: brightness(0.5) sepia(1) hue-rotate(-70deg) saturate(5); } .colorize-navy { filter: brightness(0.2) sepia(1) hue-rotate(180deg) saturate(5); } .colorize-blue { filter: brightness(0.5) sepia(1) hue-rotate(140deg) saturate(6); }

The world is your oyster here. SVG is just one use case for multiple filters. You can apply this to any media type—images, gifs, video, iframes, etc., and support is pretty good, too:

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari18*15*35No176*Mobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox6.0-6.1*37*No4.4*6457

One final note here is to remember your user! Filters will not work in Internet Explorer, so please send a visible image to all of your users (i.e. don’t use a white SVG with an applied filter on a white background, because your IE users will not see anything). Also, remember to use alternative text for icon accessibility, and you’ll be golden to use this technique in your own applications!

The post Solved With CSS! Colorizing SVG Backgrounds appeared first on CSS-Tricks.

Focusing on Focus Styles

Css Tricks - Thu, 03/29/2018 - 7:14am

Not everyone uses a mouse to browse the internet. If you’re reading this post on a smartphone, this is obvious! What’s also worth pointing out is that there are other forms of input that people use to get things done. With these forms of input comes the need for focus styles.


People are complicated. We don’t necessarily perform the same behaviors consistently, nor do we always make decisions that make sense from an outsider’s perspective. Sometimes we even do something just to… do something. We get bored easily: tinkering, poking, and prodding things to customize them to better suit our needs, regardless of their original intent.

People are also mortal. We can get sick and injured. Sometimes both at once. Sometimes it’s for a little while, sometimes it’s permanent. Regardless, it means that sometimes we’re unable to do things we want or need to do in the way we’re used to.

People also live in the world. Sometimes we’re put into an environment where external factors conspire to prevent us from doing something the way that we’re accustomed to doing it. Ever been stuck at your parents’ house during the holidays and had to use their ancient-yet-still-serviceable desktop computer? It’s like that.


Both mouse and touch input provide an indicator for interaction. For touch, it is obvious: Your finger acts as the bridge that connects your mind to the item on the screen it wants to activate. For mice, a cursor serves as a proxy for your finger.

However, these aren’t the only forms of input available to us. Keyboards are ubiquitous and can do just about anything a mouse or touch input can accomplish, provided you know all the right keys to press in the right order. Sometimes it’s even easier and faster than using a mouse!

Think about the last time you were using Cut, Copy, Paste, and Save functionality. Maybe it was the last time you were working on a spreadsheet? Were you switching between mouse and keyboard input to get things done as efficiently as possible? You probably didn’t give that behavior a second thought, but it’s a great example of switching input on the fly to best accomplish a goal. Heck, maybe you even took some "me time" during this thankless task to poke the Like button on Facebook on your smartphone.

If you have trouble using your hands, other options are available: Wands, sticks, switches, sip and puff devices, voice recognition, and eye tracking technology can all create input in a digital system. These devices will identify a content area and activate it. This is similar to how you can hit the tab key on a keyboard and the next cell in a spreadsheet will be highlighted, indicating that it has been moved to and is ready to be edited.

In this video, video editor and accessibility consultant Christopher Hills demonstrates the capabilities of Switch Control, software that helps people experiencing motor control impairments use hardware switches to operate their computing devices.

It’s worth pointing out that you could be relying on this technology one day, even if it’s only for a little bit. Maybe you broke both of your arms in an unfortunate mountain biking accident, and want to order some self-pity takeout while you recuperate. Maybe you’re driving and want to text your family safely. Or maybe you’ll just get old. It’s not difficult to think of other examples, it’s just not a concept people like to dwell on.

If it’s interactive, it needs a focus style

We can’t always know who is visiting our websites and web apps, why they’re visiting, what they’re going to do when they get there, what conditions they are experiencing, what emotions they’re feeling, or what input they may use. Analytics might provide some insight, but does not paint a full picture. It’d be foolish to have the tail wag the dog and optimize the entire experience based on this snapshot of limited information.

It’s also important to know that not everyone who uses assistive technology wants to be identified as an assistive technology user. Nor should they be forced to disclose this. Power users—people who leverage keyboard shortcuts, specialized software, and browser extensions—may appear to navigate like a user of assistive technology, yet may not be experiencing any disability conditions. Again, people are complicated!

What we can do is preemptively provide an experience that works for everyone, regardless of ability or circumstance.

Identify and activate :focus

With these alternate forms of input, how do we identify something to show it can be activated? Fortunately, CSS has this problem handled—we use the :focus and :active selectors.

The grammar is straightforward. Want to outline a link in orange when a user focuses on it? Here’s how to describe it:

a:focus { outline: 3px solid orange; }

This outline will appear when someone navigates to the link, be it by clicking or tapping, tabbing to it via keyboard input, or using switch input to highlight it.

A common misconception is that the focus style can only use the outline property. It’s worth noting that :focus is a selector like any other, meaning that it accepts the full range of CSS properties. I like to play with background color, underlining, and other techniques that don’t adjust the component’s current size, so as to not shift page layout when the selector is activated.

Then say we want to remove the link’s underline when activated to communicate a shift in state. Remember: links use underlines!

a:active { text-decoration: none; }

It’s important to make sure the state changes, from resting to focused to activated, are distinct. This means that each transition should be unique when compared to the component’s other states, allowing the user to understand that a change has occurred.

We also want to make sure these state changes don’t rely on color alone, to best accommodate people experiencing color blindness and/or low vision. Here’s how a color-only state change might look to a person with Deuteranopia, commonly known as Red-Green colorblindness:

I purposely removed the underline and the browser’s native focus ring from the link in the video to better illustrate the issue of discoverability. When trying to tab around the page to determine what is interactive, it isn’t immediately obvious that there is a link present. If colorblindness is also a factor, the state change when hovered won’t be apparent—this is even more apparent with the addition of cataracts.


:focus-within—a focus-related pseudo class selector with a very Zen-sounding name—can apply styling to a parent element when one of its children receives focus. The focus event bubbles out until it encounters a CSS rule asking it to apply its styling instructions.

A common use case for this selector would be to apply styling to an entire form when one of its input elements receives focus. In the example below, I’m scaling up the size of the entire form slightly, unless the user has expressed a desire for a reduced animation experience:

See the Pen :focus-within Demo by Eric Bailey (@ericwbailey) on CodePen.

The selector is still relatively new, so I’m sure we’ll get more clever applications as time goes on.


People also have opinions. Unfortunately, sometimes these opinions are uninformed. Outside the practice of accessibility there’s the prevalent notion that focus styles are "ugly" and many designers and developers remove them for the sake of perceived aesthetics. Sometimes they’re not even aware they’re propagating someone else’s opinion—many CSS resets include a blanket removal of focus styles and are incorporated as a foundational project dependency with no questions asked.

This decision excludes people. Websites and web apps aren’t close-cropped trophies to be displayed without context on a dribbble profile, nor are they static screenshots on a slick corporate sales deck. They exist to be read and acted upon, and there’s rules that help ensure that the largest possible amount of people can do exactly that.


The fact of the matter is that sometimes people will insist on removing focus styles, and have enough clout to force their cohorts to carry out their vision. This flies in the face of rules that stipulate that focus mechanisms must be visible for websites to be truly accessible. To get around this, we have the :focus-visible pseudo-selector.

:focus-visible pseudo-selector styling kicks in when the browser determines that a focus event occurred, and User Agent heuristics inform it that non-pointer input is being used. That’s a fancy way of saying it shows focus styling when activated via input via other than mouse cursor or finger tap.

The video of this CodePen demonstrates how different styling is applied based on the kind of input the link receives. When a link is hovered and clicked on via mouse input, its underline is removed and shifts down slightly. When tabbed to via keyboard input, :focus-visible applies a stark background color to the link instead.

Chromium has recently announced its intent to implement :focus-visible. Although browser support is currently extremely limited, a polyfill is available. Both it and :focus-within are in the Selectors Level 4 Editor’s Draft, and therefore likely to have native support in the major browsers sooner than later.

You may know :focus-visible by its other name, :-moz-focusring. This vendor prefixed pseudo-selector is Mozilla’s implementation of the idea, predating the :focus-visible proposal by seven years. Unlike other vendor prefixed CSS, we’re not going to have to worry about autoprefixing support! Firefox honors a :focus-visible declaration as well as :-moz-focusring, ensuring there will be parity for our selector names between the two browsers.

One step forward, one step back

Browser support is a bit of a rub—the web is more than just Chrome and Firefox. While the polyfill may provide support where there is none natively, it’s extra data to download, extra complexity to maintain, and extra fragility added to your payload.

There’s also the fact that devices are far less binary about their input types than they used to be. The Surface, Microsoft’s flagship computer, offers keyboard, trackpad, stylus, camera, voice, and touch capability out of the box. WebAIM’s 2017 Screen Reader Survey revealed that mobile devices may be augmented by keyboard input more than you may think. Heuristics are nice, but like analytics, may not paint a complete picture.

Another point to consider is that focus styles can be desirable for mouse users. Their presence is a clear and unambiguous indication of interactivity, which is a great affordance for people with low vision conditions, cognitive concerns, and people who are less technologically adept. Extraordinarily technologically adept people, ones who grok that screen readers and keyboard shortcuts are essentially Vim for a GUI, will want the focus state to be apparent as they use the keyboard to dance across the screen.

Part of building a robust, resilient web involves building a strong core experience that works in every browser. The vanilla :focus selector enjoys both wide and deep support to the degree that it’s a safe bet that even exotic browsers will honor it.

The world is full of things that some people may see as ugly, while others find them to be beautiful. Personally, I don’t see focus styles as an eyesore. As a designer, I think that it’s a foundational part of creating a mature design system. As a developer, describing state is just business as usual. As a person, I enjoy helping to keep the web open and accessible, as it was intended to be.

If you’d like to learn more about the subject, UX Designer Caitlin Geier has a great writeup on focus indicators.

The post Focusing on Focus Styles appeared first on CSS-Tricks.

The revolutionary project management tool

Css Tricks - Thu, 03/29/2018 - 7:13am

(This is a sponsored post.)

monday.com is a project management tool your team will actually enjoy using. It makes it fun and easy for everyone to collaborate, focus on what's important, and get more done at work. It's a visual project management tool that’ll help you and your team collaborate and achieve more together.

With monday.com you can manage projects and tasks in a single board, move through the timeline visually and intuitively and communicate with your teammates in the context of each task. Plus, it connects with all the apps you already use and love like Dropbox, Google Drive, and Zapier.

Start free trial.

Direct Link to ArticlePermalink

The post The revolutionary project management tool appeared first on CSS-Tricks.

The UX Logout Lapse

Usability Geek - Wed, 03/28/2018 - 9:34am
The logout experience is oft-overlooked in our increasingly logged in lives. Typically (and perhaps understandably), greater UX focus is placed on getting users in than ushering them out....
Categories: Web Standards

Quick Reminder that Details/Summary is the Easiest Way Ever to Make an Accordion

Css Tricks - Wed, 03/28/2018 - 8:18am

Gosh bless the <details> element. Toss some content inside it and you have an accessible expand-for-more interaction with just about zero work.

See the Pen Simple details. by Chris Coyier (@chriscoyier) on CodePen.

Toss a <summary> in there to customize what the expander text says.

See the Pen Multiple Details/Summary by Chris Coyier (@chriscoyier) on CodePen.

Works great for FAQs.

There is really no limit to how you can style them. If you don't like the default focus ring, you can remove that, but make sure to put some kind of styling back.

Here I've used a header element for each expandable section, which has a focus state that mimics other interactive elements on the page.

The only browser that doesn't support this are the Microsoft ones (and Opera Mini which makes sense—it doesn't really do interactive).

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari121549NoNo6Mobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox6.0-6.137No46457

But even then, it's just like all the sections are opened, so it's not a huge deal:

Wanna style that default triangle? Strangely enough, the standard way to do that is through the list-style properties. But Blink-based browsers haven't caught up to that yet, so they have a proprietary way to do it. They can be combined though. Here's an example of replacing it with an image:

summary { list-style-image: url(right-arrow.svg); } summary::-webkit-details-marker { background: url(right-arrow.svg); color: transparent; }

See the Pen Custom Markers on Details/Summary by Chris Coyier (@chriscoyier) on CodePen.

Unfortunately, they don't turn, and there is no way to animate the default triangle either. One idea might be to target the :focus state and swap backgrounds:

See the Pen Custom Markers on Details/Summary by Geoff Graham (@geoffgraham) on CodePen.

But that seems to be limited to WebKit and Blink and, even then, the arrow will return once the item is out of focus even if the item is still expanded.

The post Quick Reminder that Details/Summary is the Easiest Way Ever to Make an Accordion appeared first on CSS-Tricks.

React’s New Context API Explained

Css Tricks - Wed, 03/28/2018 - 8:17am

In this video tutorial, Wes Bos looks into the new context API and the problem that it’s trying to solve:

React 16.3 has a new Context API which makes accessing data and functions anywhere in your application a snap. If you ever find yourself passing data down via props 4-5 levels deep, context might be what you are looking for.

Don’t forget about Neal Fennimore’s recent post on putting things into context. It covers the concept in great detail and provides some workarounds for the quirks you might encounter when using it.

Direct Link to ArticlePermalink

The post React’s New Context API Explained appeared first on CSS-Tricks.

Syndicate content
©2003 - Present Akamai Design & Development.