Front End Web Development

How to Disable Code: The Developer’s Production Kill Switch

Css Tricks - Thu, 06/25/2020 - 4:59am

The following is a guest post written by Carlos Schults.

Being able to disable code in production is a power that many developers aren’t aware of. And that’s a shame. The ability to switch off some portions—or even complete features—of the codebase can dramatically improve the software development process by allowing best practices that can shorten feedback cycles and increase the overall quality.

So, that’s what this post will cover: the mechanisms you can use to perform this switching off, why they’re useful and how to get started. Let’s dig in.

Why Would You Want to Disable Code?

Before we take a deep dive into feature flags, explaining what they are and how they’re implemented, you might be asking: Why would people want to switch off some parts of their codebase? What’s the benefit of doing that?

To answer these questions, we need to go back in time to take a look at how software was developed a couple of decades ago. Time for a history lesson!

The Dark Ages: Integration Hell

Historically, integration has been one of the toughest challenges for teams trying to develop software together. 

Picture several teams inside an organization, working separately for several months, each one developing its own feature. While the teams were working in complete isolation, their versions of the application were evolving in different directions. Now they need to converge again into a single, non conflicting version. This is a Herculean task. 

That’s what “integration hell” means: the struggle to merge versions of the same application that have been allowed to diverge for too long. 

Enter the Solution: Continuous Integration

“If it hurts, do it more often.” What this saying means is that there are problems we postpone solving because doing so is hard. What you often find with these kinds of problems is that solving them more frequently, before they accumulate, is way less painful—or even trivial.

So, how can you make integrations less painful? Integrate more often.

That’s continuous integration (CI) in a nutshell: Have your developers integrate their work with a public shared repository, at the very least once a day. Have a server trigger a build and run the automated test suite every time someone integrates their work. That way, if there are problems, they’re exposed sooner rather than later.

How to Handle Partially Completed Features

One challenge that many teams struggle with in CI is how to deal with features that aren’t complete. If developers are merging their code to the mainline, that means that any developments that take more than one day to complete will have to be split into several parts. 

How can you avoid the customer accessing unfinished functionality? There are some trivial scenarios with similarly trivial solutions, but harder scenarios call for a different approach: the ability to switch off a part of the code completely.

Feature Flags to the Rescue Defining Feature Flags

There are many names for the mechanisms that allow developers to switch a portion of their code off and on. Some call them “feature toggles” or “kill switches.” But “feature flags” is the most popular name, so that’s what we’ll use for the remainder of this post. So, what are feature flags?

Put simply, feature flags are techniques that allow teams to change the behavior of an application without modifying the code. In general, flags are used to prevent users from accessing and using the changes introduced by some piece of code, because they’re not adequate for production yet for a number of reasons.

Disable Code: What Are the Use Cases?

We’ll now cover some of the most common use cases for disabling code in production.

Switching Off Unfinished Features

As you’ve seen, one of the main use cases for feature flags is preventing users from accessing features that aren’t ready for use yet.

That way, programmers developing features that are more complex and take a longer time to complete aren’t prevented from integrating their work often and benefiting from it.

Enabling A/B Testing

The adoption of feature flags enables the use of several valuable practices in the software development process, one of which is A/B testing

A/B testing is a user experience research technique that consists of comparing two versions of a website or application to decide which one to keep. It entails randomly splitting users into two groups, A and B, and then delivering a different version of the application to each group. One group might receive the current production version, which we call the “control,” whereas the second group would receive the candidate for the new version, called the “treatment.” 

The testers then monitor the behavior of both groups and determine which of the versions achieved better results. 

Feature flags are a practical way to enable A/B testing because they allow you to quickly and conveniently change between the control and treatment versions of your application.

Enabling Canary Releases

If you deliver the new version of your app to your entire userbase at once, 100 percent of your users will be impacted if the release is bad in some way. What if you could gradually roll out the new version instead? You’d first deploy to a small subset of users, monitoring that group to detect issues. If something went wrong, you could roll it back. If everything looked fine, you could then gradually release the version for larger groups. That’s a canary release in a nutshell. It’s another powerful technique that feature flags might help with.

Customizing Features According to Users’ Preferences

It’s not uncommon to have to customize your application according to the needs of specific users, and there are several ways in which software teams can accomplish that—some more efficient, and others less so (companies that create separate branches or entire repositories for each client come to mind).

This is another area where feature flags could help, allowing teams to dynamically switch between different versions of the same functionality.

Disable Code in Production 101

How do you go about disabling code? That’s what we’re going to see now, in three increasingly sophisticated phases.

First Stage: The Most Basic Approach

We start with an approach that’s so primitive, it maybe shouldn’t be considered a feature flag at all. Consider the pseudocode below:

calculateAdditionalWorkHours(Employee employee, Date start, Date end) { // return calculateAdditionalWorkHoursSameOldWay(employee, start, end); return calculateAdditionalWorkHoursImproved(employee, start, end); }

In the code above, we’re just commenting out the old version of some method and replacing it with a new version. When we want the older version to be used, we just do the opposite. (Well, I said it was primitive.) This approach lacks one of the most fundamental properties of a feature flag—the ability to change how the application behaves without changing its code.

However, it plants the seed for more sophisticated approaches.

Second Stage: Taking the Decision Out of the Code

The previous approach didn’t allow developers to select the desired version of the feature without changing the code. Fortunately, that’s not so hard to do. First, we introduce a logical variable to determine which version we’re going to use:

calculateAdditionalWorkHours(Employee employee, Date start, Date end) { var result = useNewCalculation ? calculateAdditionalWorkHoursImproved(employee, start, end) : calculateAdditionalWorkHoursSameOldWay(employee, start, end); return result; }

Then, we use some mechanism to be able to assign the value to the variable from an external source. We could use a configuration file:

var useNewCalculation = config[newCalculation];

Passing arguments to the application might be another option. What matters is that we now have the ability to modify how the app behaves from the outside, which is a great step toward “true” feature flagging.

Keep in mind that the code examples you see are all pseudocode. Using your favorite programming language, there’s nothing stopping you from starting with this approach and taking it up a notch. You could, for instance, use classes to represent the features and design patterns (e.g., factories) to avoid if statements.

Stage 3: Full-Fledged Feature Flag Management

The previous approach might be enough when your application has only a small number of flags. But as that number grows, things start to become messy.

First, you have the issue of technical debt. Manually implemented feature flags can create terribly confusing conditional flows in your codebase. That only grows worse with new flags being introduced each day. Additionally, they might make the code harder to understand and navigate, especially for more junior developers, which is an invitation for bugs.

Another problem is that as the number of flags grows, it becomes more and more common to forget to delete old, obsolete ones.

The main problem of a homegrown approach is that it doesn’t give you an easy way to see and manage all of your flags at once. That’s why our third and final stage is a single piece of advice: Instead of rolling out your own feature flags approach, adopt a third-party feature flag management system.

Feature Flags Are a CI/CD Enabler

We’ve covered the mechanisms developers can use to disable portions of their codebase in production without having to touch the code. This capability is powerful and enables techniques such as A/B testing and canary releases, which are all hallmarks of a modern, agile-based software development process.

The names for the techniques might vary—feature flags, feature toggles, feature flipper, and so on. The way in which the techniques are implemented can also vary—from a humble if statement to sophisticated cloud-based solutions.

But no matter what you call them, you can’t overstate the benefit these mechanisms offer. They’re an enabler of Continuous Integration, which is essential for any modern software organization that wants to stay afloat.

The post How to Disable Code: The Developer’s Production Kill Switch appeared first on CSS-Tricks.

Hide Scrollbars During an Animation

Css Tricks - Wed, 06/24/2020 - 11:33am

CSS still can’t animate to auto dimensions.

.dropdown { transition: 0.2s; height: 0; } .dropdown.open { /* the height will change, but it won't animate. */ height: auto; }

There is JavaScript trickery you can try. Brandon Smith outlined several techniques here a little while back. My mind always goes to this solution just because it’s so simple:

.dropdown { transition: 0.2s; max-height: 0; } .dropdown.open { /* 🎉 */ max-height: 400px; }

Now we have this 400px magic number which is really not ideal. But the fact that this works and is so simple makes it extremely appealing that I use it production all the time.

But the magic number isn’t the only problem. Another problem is scrollbars.

When we set max-height: 0;, we also need overflow: hidden; to make sure the dropdown is actually hidden when it is closed. When the dropdown is open, we should probably be using overflow: auto; so that we don’t accidentally cut off content in case the natural height of the dropdown is taller than the max-height after it expands. The use of overflow: auto; solves that problem while introducing another: during the expansion, our dropdown will always have scrollbars for at least part of the expansion, even if the final expansion height doesn’t need them. That’s awkward!

CSS trickery to the rescue.

We can still use overflow: auto; on the expanded state — we’ll just override it during the animation. As we learned in the great CSS specificity battle, @keyframes have an amazing ability to override anything while they are active. Let’s use them not to animate the opening, but just for this scrollbar-hiding functionality:

.dropdown { max-height: 0; overflow: hidden; transition: max-height 1.2s ease-in-out; } .dropdown.open { overflow: auto; max-height: 400px; animation: hide-scroll 1.2s backwards; @keyframes hide-scroll { from, to { overflow: hidden; } } }

That does the trick!

CodePen Embed Fallback

Try adjusting the height to something less to see how you don’t see scrollbars during the animation but only at the end when they are needed. That causes a little bit of jerkiness when the scrollbar pops in, but that was acceptable in my case as it’s rare that it happens at all. If you absolutely wanted to stop the jerkiness, you’d probably apply a (custom) scrollbar at all times to the dropdown and perhaps adjust the styling of the scrollbar during the animation, if needed.

Credit here to Mr. Stephen Shaw of the fancy @keyframers for this trick. I yanked him in to help me figure it out while I was working on it for something on CodePen. We decided to turn the trick into a video for the CodePen channel showcasing Collab Mode, which we used to figure out the problem/solution:

The post Hide Scrollbars During an Animation appeared first on CSS-Tricks.

WebP Image Support Coming to iOS 14

Css Tricks - Tue, 06/23/2020 - 1:23pm

Apple announced a ton of new updates at yesterday’s WWDC20 keynote address, from new hardware to updated applications. There’s lots to gawk at and enough device-envy to go around.

But there’s one little line in the Safari 14 Beta release notes that caught my eye:

Added WebP image support.

🎉🎉🎉

This excites me because WebP is a super progressive format that encodes images in lossless and lossy formats that we get with other image formats we already use, like JPEG, but at a fraction of the file size. We use WebP right here at CSS-Tricks, thanks to Jetpack and its Site Accelerator feature that serves WebP versions of the images we upload to browsers that support them. Jeremy Wagner has a great write-up on WebP and how to work with it, specifically for WordPress.

So, yes, this means WebP will be largely supported across the board (:IE-sad-trombone:) once Safari 14 ships.

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

DesktopChromeFirefoxIEEdgeSafari3265No1814Mobile / TabletAndroid ChromeAndroid FirefoxAndroidiOS Safari81684.2-4.314.0

Even with that great support, defining fallbacks with the <picture> element is still a good idea.

<picture> <source srcset="img/cat.webp" type="image/webp"> <source srcset="img/cat.jpg" type="image/jpeg"> <img src="img/cat.jpg" alt="Alt Text!"> </picture>

Oh, and not to be completely overshadowed, Safari 14 also squeezes in some CSS goodies, like the :is() and :where() pseudo class functions, which we linked up a couple of weeks ago. Jen Simmons picked out other key features we should be excited about.

Safari 14 Beta Release Notes
• Added WebP
• Changed to derive <img> aspect ratio from size attributes
• Added :is()
• Added :where()
• Safari no longer supports Flash
• Added Safari Web Extensions
• Added Webpage Translation (Beta)

& much more: https://t.co/qO2Cy7rK4A

— Jen Simmons (@jensimmons) June 22, 2020

Direct Link to ArticlePermalink

The post WebP Image Support Coming to iOS 14 appeared first on CSS-Tricks.

Linkbait 45

QuirksBlog - Tue, 06/23/2020 - 3:18am

Cleaning up my tabs.

  • So a performance.now() sponsor asked if there was any performance-centric publication. I did not know, asked around, and found that just about the only one is the perf email newsletter. So just so you know; it’s supposed to be worth the subscription.
    (BTW: we postponed performance.now() to 2021. This year it’s just not possible to run physical events.)
  • Speaking of events, Benedict Evans wrote an excellent article on the future of events. His experience is more with the huge trade shows than with our focused events, but he makes a few cogent points. Online events are quite different from physical ones (I already figured that out), but nobody yet knows how to do them properly. Instead of doing something truly online, most events just copy physical events while pointing a camera at the speaker and providing. That’s not the way forward. See also the early web that copied print. We slowly learned that it’s something quite different.
    Regardless, Krijn and I are not going to try online events. Instead we’ll wait until we can hold physical ones again; that’s where our strength lies.
    One more excellent point from the article: expensive, or even not-cheap, tickets, as well as organising and paying for your flight and hotel, serves as a selection filter, so that you end up with people who really value physical events.
    There is a lot of pent-up demand for phyiscal events, and that won’t go away, so physical events will return. Still, new forms of online events might also come out of this crisis.
  • A while ago I considered writing an article about the Apple/Google initiative for somewhat-privacy-protecting Covid-tracking, and I gathered some sources. I never wrote the article, but here are the sources anyway:
    • The press release
    • Google’s simple overview
    • Specifications
    • Initial Cnet overview article
    • A rather critical look at the privacy implications. I had the idea the author was too negative, or made some assumption somewhere that was not entirely warranted, but I never actually figured out what sort of problem I felt this article had.
    • A more moderate Wired article that acknowledges possible privacy problems, and gives practical examples, one creepy neighbour and one creepy ad firm, and runs through some other problems as well. As I see it, these problems are inherent to any form of smartphone-based mass surveillance scheme.
    (To be honest, to me contact tracing apps are a sneaky way to avoid the much more expensive contact tracing by actual humans, which I suspect works much better. Also, politicians desperately want to be seen to be tech-literate, so we need an app. Absolutely, positively need an app. I mean, it’s technology, you know ...)
  • A nice line of CSS Grid for you to study. I found out about auto-fill here.
  • Lea takes a look at hybrid positioning (ie. switching from a fixed-like to an absolute-like positioning) in CSS, and as usual I learned a lot here as well. I had this effect on my site since 2004 or so, and I switch from fixed to absolute with JavaScript, because that was the only possibility back then. Meanwhile it turns out you can do this mostly in CSS as well. Also teaches you how to change CSS custom properties in JavaScript.
    I’ve been thinking about it, and I don’t see a way of doing this in pure CSS, because at some point you have to switch from fixed to absolute, and that cannot be done in CSS alone.
  • Speaking of CSS custom properties, Lea’s article and this one taught me that they in fact contain strings that do not have to be valid CSS. It’s only interpreted when it’s actually used in a CSS expression. See also this conversation with Lea and Tab, as well as this article by Jeremy that actually pushed me in to this particular rabbit hole. Thing learned!
  • The Chrome team is preparing to do something about ultra-heavy ads; overview, technical details. Curious what comes of this. Something must be done on the browser side of things to clamp down on online junk; this may be a step in the right direction. Supposed to land somewhere in August.
  • I am probably going to write more about monetization of resources such as this one, or front-end tools, and had a good Twitter conversation (yes! they still exist!) with Scott Wilson in particular. I gathered a few articles, but an incident with my computer made me lose most of them. Here are the two surviving ones:
    • An excellent overview of OSS business models (which I think we should take as a template for web dev monetization)
    • A more critical look at several options. Money quote (pun not intended):

      We should remember that a big part of innovation comes from developers working at organizations adopting open source software [...]. It’s these organizations that should be tasked to sustain open source software [...], especially since they depend on open source software to survive as a business.

  • Very nice online presentation of excerpts from the diaries of captain DaCosta, a 16th century black Portuguese sea captain who ended up in Japan. Contains interesting details. The only thing I’m missing is bibliographical information about the full diary. If it’s translated into a language I can read I might actually pick it up.
  • Have a tip for the next Linkbait? Or a comment on this one? Let me know (or here or here).

An Overview of Scroll Technologies

Css Tricks - Mon, 06/22/2020 - 11:52am

Scroll-related animations have been used on the web for years. In recent years, they’ve started to become more common, perhaps in part due to devices being higher-performing and thus able to handle more animation. 

There are a number of scroll related technologies out there, so this article’s aim is to provide an overview of them and tools to help choose the one that’s right for you. I’d argue that these technologies can be broken down into two broad categories: ones for specific scroll-related behaviors and ones for more generic scroll-related behaviors.

Technologies for specific scroll-related behaviors

There are a few simple native CSS scroll effects that are supported by modern browsers. In some limited use cases they can be sufficient for your scroll animation needs.

position: sticky;

If all you need is for an element to stay in the same place on scroll for a portion of the page, using position: sticky is a good option. It’s straightforward and built into modern browsers. That said, a polyfill is required for IE support and some mobile browsers. For a solid overview, check out this article by Preethi.

CodePen Embed Fallback CSS parallax

This isn’t a technology as much as a technique, but it’s pretty handy for simple parallax effects where you want different pieces of the page to move at different speeds on scroll. There’s a good write up of the technique on Alligator.io and a bunch of examples on CodePen, like this Firewatch header. The biggest downside for me is that it’s difficult to understand what values to use to set the perspective and transforms in order to get the parallax effect exactly right.

CodePen Embed Fallback CSS scroll snap points

Scroll snap points allow the browser to snap to particular scroll positions that you set after a user is done with their normal scrolling. This can be helpful for keeping certain elements in view. However, the API is still in flux so be careful to use the most up to date API and be careful about relying on it in production. This CSS-Tricks article by Max Kohler is a good place to learn about it right now.

CodePen Embed Fallback Smooth scrolling

Smooth scrolling is supported natively when jumping from section to section within a page using window.scrollTo() in JavaScript or even the scroll-behavior property in CSS. Generic smooth scrolling that smooths out mouse wheel actions is not supported natively in all browsers at this time. There are various JavaScript libraries that attempt to add smooth scroll support for the mousewheel action, but I’ve yet to find one that is bug-free and plays nicely with all other scroll technologies. Plus, smooth scrolling isn’t always good in the first place.

Technologies for generic scroll behaviors

Currently, there is no way to create or fire generic animations based on the scroll position using just CSS (though there is a proposal that could support some form of generic scroll based animations in CSS in the distant future) or to scrub through part of an animation. As such, if you want to animate elements on scroll, you’ll need to use at least some JavaScript to create the effect you want. There are two broad methods of using JavaScript to fire animations on scroll: using intersection observers and using the scroll event.

IntersectionObserver

Intersection observers are great if all you need for your animation is information related to whether or not and how much of an element is visible in the viewport. This makes them a good option for reveal animations. Even then, some things are difficult (though not impossible) using intersection observers, such as firing different animations depending on the direction an element enters the viewport. Intersection observers also aren’t very helpful if you want to do any scroll animations when an element is in between and not overlapping with the start and end points. 

Using the scroll event

Using the scroll event will give you the most freedom in controlling animations on scroll. It allows you to affect an element on scroll no matter where it is in terms of the viewport and set up starting and ending points exactly as you need for your project. 

With that being said, it can also be intense on performance if it isn’t throttled correctly and doesn’t have a convenient API to create particular behaviors. This is why it’s oftentimes helpful to use a good scrolling library that can handle the throttling for you and give you a more handy API to work with. Some can even handle a lot of the resizing issues for you!

Tools to create generic scroll behaviors

There are a few holistic scrolling libraries that attempt to give you full control over animations on scroll without you having to perform all of the calculations yourself. 

ScrollMagic

ScrollMagic provides a relatively simple API to create various effects on scroll and can be hooked into different animation libraries like GSAP and Velocity.js. However, it has become less maintained over the past few years, which lead to the creation of ScrollScene.

ScrollScene

ScrollScene is essentially a wrapper to try and make ScrollMagic and/or the intersection observer more usable. It uses a custom, more maintained version of ScrollMagic and adds additional features like video playback, scene init breakpoints, and scene duration breakpoints. It also makes use of GSAP

ScrollTrigger

ScrollTrigger is an official GreenSock plugin for GSAP. It has a long list of features and has the most easy to use API of any scroll library (at least to me). Using it, you can have complete control to define where your scroll animations start and end, animate anything (WebGL, canvas, SVG, DOM, whatever) on scroll, pin elements in place while the animation is running, and more. Plus it has the support of GreenSock and the GreenSock forums

Notable mention: Locomotive Scroll

While it doesn’t attempt to be as comprehensive of a scrolling library as the other libraries mentioned above, Locomotive Scroll is focused on providing custom smooth scrolling. You can also animate certain properties of DOM objects by adding data attributes or hook into the onscroll event to animate other types of objects. 

In summary

For some particular scroll animation effects, like sticky positioning and parallax, CSS technologies may be sufficient, at least when using a polyfill for browsers that don’t support those properties.

I generally recommend using GSAP’s ScrollTrigger because it can do everything that CSS properties can do, plus much more. ScrollTrigger will handle the browser support and calculations so that you can focus on animating!

Here’s a table covering which tools you can use to create particular effects:

ScrollTriggerLocomotive ScrollScrollSceneScrollMagicIntersection observersSmooth ScrollingCSS scroll snap pointsCSS parallaxposition: stickyPinning✅⚪️✅✅❌❌❌❌✅Parallax effects✅✅✅✅❌❌❌✅❌Scrubbing through animation with easing✅⚪️⚪️⚪️⚪️❌❌⚪️❌Snaps scroll position✅⚪️⚪️⚪️⚪️❌✅❌❌Dynamic Batching / Staggering✅❌✅❌✅❌❌❌❌Supports horizontal scroll effects✅✅✅✅✅✅✅✅✅

Here’s a table comparing various other aspects of scroll technology:

ScrollTriggerLocomotive ScrollScrollSceneScrollMagicIntersection observersSmooth scrollingCSS scroll snap pointsCSS parallaxposition: stickyUsable in production (good browser support)✅⚪️✅✅⚪️⚪️⚪️✅⚪️Complete freedom in animation✅⚪️✅✅❌❌❌❌❌Maintained✅✅✅❌n/an/an/an/an/aWorks with DOM, Canvas, WebGl, SVG✅⚪️✅✅✅❌❌❌❌Works easily with resizing✅✅✅⚪️✅✅✅✅✅Restricts animation to relevant section✅❌⚪️⚪️✅✅✅❌✅Directionally aware✅⚪️✅✅⚪️❌❌❌❌Native technology❌❌❌❌✅✅✅✅✅✅ = Yes
⚪️ = Partial support
❌ = No

The post An Overview of Scroll Technologies appeared first on CSS-Tricks.

Rough Notation

Css Tricks - Mon, 06/22/2020 - 11:51am

This is a neat little library. It uses SVG to insert hand-drawn looking annotations to elements (probably text), like underlines and box highlights (there are 6 design options, all configurable). Super clever.

Here’s a little demo:

CodePen Embed Fallback

Aside from it just being cool, I really like how it was released. You can use it from npm. It’s ready to be used via ES6 imports. You can just use it as a <script src>. Then, if you happen to be using a JavaScript framework, there are wrappers for React, Vue, Svelte, Angular, and Web Components. Nice.

Not all projects take that approach. Here’s another very cool project: gooey-react. It takes the gooey effect concept and essentially gives it an API via React/JSX.

Again, this is very cool and clever and I love it — but imagine another approach instead, perhaps an HTML wrapper with data-* attributes to control the effect. With that, wrappers could be (easily?) made in any JavaScript framework.

Direct Link to ArticlePermalink

The post Rough Notation appeared first on CSS-Tricks.

Using Custom Property “Stacks” to Tame the Cascade

Css Tricks - Mon, 06/22/2020 - 4:47am

Since the inception of CSS in 1994, the cascade and inheritance have defined how we design on the web. Both are powerful features but, as authors, we’ve had very little control over how they interact. Selector specificity and source order provide some minimal “layering” control, without a lot of nuance — and inheritance requires an unbroken lineage. Now, CSS Custom Properties allow us to manage and control both cascade and inheritance in new ways.

I want to show you how I’ve used Custom Property “stacks” to solve some of the common issues people face in the cascade: from scoped component styles, to more explicit layering of intents.

A quick intro to Custom Properties

The same way browsers have defined new properties using a vendor prefix like -webkit- or -moz-, we can define our own Custom Properties with an “empty” -- prefix. Like variables in Sass or JavaScript, we can use them to name, store, and retrieve values — but like other properties in CSS, they cascade and inherit with the DOM.

/* Define a custom property */ html { --brand-color: rebeccapurple; }

In order to access those captured values, we use the var() function. It has two parts: first the name of our custom property, and then a fallback in case that property is undefined:

button { /* use the --brand-color if available, or fall back to deeppink */ background: var(--brand-color, deeppink); }

This is not a support fallback for old browsers. If a browser doesn’t understand custom properties, it will ignore the entire var() declaration. Instead, this is a built-in way of handling undefined variables, similar to a font stack defining fallback font families when one is unavailable. If we don’t provide a fallback, the default is unset.

Building variable “stacks”

This ability to define a fallback is similar to “font stacks” used on the font-family property. If the first family is unavailable, the second will be used, and so on. The var() function only accepts a single fallback, but we can nest var() functions to create custom-property fallback “stacks” of any size:

button { /* try Consolas, then Menlo, then Monaco, and finally monospace */ font-family: Consolas, Menlo, Monaco, monospace; /* try --state, then --button-color, then --brand-color, and finally deeppink */ background: var(--state, var(--button-color, var(--brand-color, deeppink))); }

If that nested syntax for stacked properties looks bulky, you can use a pre-processor like Sass to make it more compact.

CodePen Embed Fallback

That single-fallback limitation is required to support fallbacks with a comma inside them — like font stacks or layered background images:

html { /* The fallback value is "Helvetica, Arial, sans-serif" */ font-family: var(--my-font, Helvetica, Arial, sans-serif); } Defining “scope”

CSS selectors allow us to drill down into the HTML DOM tree, and style elements anywhere on the page, or elements in a particular nested context.

/* all links */ a { color: slateblue; } /* only links inside a section */ section a { color: rebeccapurple; } /* only links inside an article */ article a { color: deeppink; }

That’s useful, but it doesn’t capture the reality of “modular” object-oriented or component-driven styles. We might have multiple articles and asides, nested in various configurations. We need a way to clarify which context, or scope, should take precedence when they overlap.

Proximity scopes

Let’s say we have a .light theme and a .dark theme. We can use those classes on the root <html> element to define a page-wide default, but we can also apply them to specific components, nested in various ways:

CodePen Embed Fallback

Each time we apply one of our color-mode classes, the background and color properties are reset, then inherited by nested headings and paragraphs. In our main context, colors inherit from the .light class, while the nested heading and paragraph inherit from the .dark class. Inheritance is based on direct lineage, so the nearest ancestor with a defined value will take precedence. We call that proximity.

Proximity matters for inheritance, but it has no impact on selectors, which rely on specificity. That becomes a problem if we want to style something inside the dark or light containers.

Here I’ve attempted to define both light and dark button variants. Light mode buttons should be rebeccapurple with white text so they stand out, and dark mode buttons should be plum with black text. We’re selecting the buttons directly based on a light and dark context, but it doesn’t work:

CodePen Embed Fallback

Some of the buttons are in both contexts, with both .light and .dark ancestors. What we want in that case is for the closest theme to take over (inheritance proximity behavior), but what we get instead is the second selector overriding the first (cascade behavior). Since the two selectors have the same specificity, source order determines the winner.

Custom Properties and proximity

What we need here is a way to inherit these properties from the theme, but only apply them to specific children. Custom Properties make that possible! We can define values on the light and dark containers, while only using their inherited values on nested elements, like our buttons.

We’ll start by setting up the buttons to use custom properties, with a fallback “default” value, in case those properties are undefined:

button { background: var(--btn-color, rebeccapurple); color: var(--btn-contrast, white); }

Now we can set those values based on context, and they will scope to the appropriate ancestor based on proximity and inheritance:

.dark { --btn-color: plum; --btn-contrast: black; } .light { --btn-color: rebeccapurple; --btn-contrast: white; }

As an added bonus, we’re using less code overall, and one unified button definition:

CodePen Embed Fallback

I think of this as creating an API of available parameters for the button component. Sara Soueidan and Lea Verou have both covered this well in recent articles.

Component ownership

Sometimes proximity isn’t enough to define scope. When JavaScript frameworks generate “scoped styles” they are establishing specific object-element ownership. A “tab layout” component owns the tabs themselves, but not the content behind each tab. This is also what the BEM convention attempts to capture in complex .block__element class names.

Nicole Sullivan coined the term “donut scope” to talk about this problem back in 2011. While I’m sure she has more recent thoughts on the issue, the fundamental problem hasn’t changed. Selectors and specificity are great for describing how we build detailed styles over top of broad patterns, but they don’t convey a clear sense of ownership.

We can use custom property stacks to help solve this problem. We’ll start by creating “global” properties on the <html> element that are for our default colors:

html { --background--global: white; --color--global: black; --btn-color--global: rebeccapurple; --btn-contrast--global: white; }

That default global theme is now available anywhere we want to refer to it. We’ll do that with a data-theme attribute that applies our foreground and background colors. We want the global values to provide a default fallback, but we also want the option to override with a specific theme. That’s where “stacks” come in:

[data-theme] { /* If there's no component value, use the global value */ background: var(--background--component, var(--background--global)); color: var(--color--component, var(--color--global)); }

Now we can define an inverted component by setting the *--component properties as a reverse of the global properties:

[data-theme='invert'] { --background--component: var(--color--global); --color--component: var(--background--global); }

But we don’t want those settings to inherit beyond the donut of ownership, so we reset those values to initial (undefined) on every theme. We’ll want to do this at a lower specificity, or earlier in the source order, so it provides a default that each theme can override:

[data-theme] { --background--component: initial; --color--component: initial; }

The initial keyword has a special meaning when used on custom properties, reverting them to a Guaranteed-Invalid state. That means rather than being passed along to set background: initial or color: initial, the custom property becomes undefined, and we fallback to the next value in our stack, the global settings.

We can do the same thing with our buttons, and then make sure to apply data-theme to each component. If no specific theme is given, each component will default to the global theme:

CodePen Embed Fallback Defining “origins”

The CSS cascade is a series of filtering layers used to determine what value should take precedence when multiple values are defined on the same property. We most often interact with the specificity layers, or the final layering based on source-order — but the first layer of cascade is the “origin” of a style. The origin describes where a style came from — often the browser (defaults), the user (preferences), or the author (that’s us).

By default, author styles override user preferences, which override browser defaults. That changes when anyone applies `!important` to a style, and the origins reverse: browser `!important` styles have the highest origin, then important user preferences, then our author important styles, above all the normal layers. There are a few additional origins, but we won’t go into them here.

When we create custom property “stacks,” we’re building a very similar behavior. If we wanted to represent existing origins as a stack of custom properties, it would look something like this:

.origins-as-custom-properties { color: var(--browser-important, var(--user-important, var(--author-important, var(--author, var(--user, var(--browser)))))); }

Those layers already exist, so there’s no reason to recreate them. But we’re doing something very similar when we layer our “global” and “component” styles above — creating a “component” origin layer that overrides our “global” layer. That same approach can be used to solve various layering issues in CSS, which can’t always be described by specificity:

  • Override » Component » Theme » Default
  • Theme » Design system or framework
  • State » Type » Default

Let’s look at some buttons again. We’ll need a default button style, a disabled state, and various button “types,” like danger, primary and secondary. We wan’t the disabled state to always override the type variations, but selectors don’t capture that distinction:

CodePen Embed Fallback

But we can define a stack that provides both “type” and “state” layers in the order that we want them prioritized:

button { background: var(--btn-state, var(--btn-type, var(--btn-default))); }

Now when we set both variables, the state will always take precedence:

CodePen Embed Fallback

I’ve used this technique to create a Cascading Colors framework that allows custom theming based on layering:

  • Pre-defined theme attributes in the HTML
  • User color preferences
  • Light and dark modes
  • Global theme defaults
Mix and match

These approaches can be taken to an extreme, but most day-to-day use-cases can be handled with two or three values in a stack, often using a combination of the techniques above:

  • A variable stack to define the layers
  • Inheritance to set them based on proximity and scope
  • Careful application of the `initial` value to remove nested elements from a scope

We’ve been using these custom property “stacks” on our projects at OddBird. We’re still discovering as we go, but they’ve already been helpful in solving problems that were difficult using only selectors and specificity. With custom properties, we don’t have to fight the cascade or inheritance. We can capture and leverage them, as-intended, with more control over how they should apply in each instance. To me, that’s a big win for CSS — especially when developing style frameworks, tools, and systems.

The post Using Custom Property “Stacks” to Tame the Cascade appeared first on CSS-Tricks.

Patternico

Css Tricks - Sat, 06/20/2020 - 3:50am

I remember searching for tutorials for making seamless patterns in Photoshop¹ all the time back in the day.

It’s fun to see this little website for building repeating patterns as its one job. It does everything you’d expect: pick a background, drag some decorations onto it and position them (overlapping an edge is fine, which is the hard part, and makes the designs look less griddy), color them, and away you go.

  1. The trick is to make a square with a design in it, then Filter > Other > Offset of half the width/height to make the seamless repeating edges work, then add a bit more in gaps.

Direct Link to ArticlePermalink

The post Patternico appeared first on CSS-Tricks.

Just another +1 for subgrid

Css Tricks - Fri, 06/19/2020 - 4:30am

I’d say 85% of my grid usage is in one of these two categories…

  1. I just need some pretty basic (probably equal width) columns that ends up being something like like grid-template-columns: repeat(3, minmax(0, 1fr)); to be safe.
  2. Actually doing some real layout where five minutes in I realize I’d really like subgrid.

Subgrid? It’s a nice intuitive way to have a child element on the grid inherit relevant grid lines from the parent grid.

Here’s a great recent video from Rachel Andrew covering it. Last year, we linked up her talk on the same! It’s such a clutch feature and I wish we could rely on it cross-browser. Right now, Firefox is the only one that has it. (Chrome issue, Safari issue)

In my recent video, right about at 20 minutes, I realize subgrid would make even a fairly simple layout much nicer, like removing the need for variables or resorting to magic numbers.

The post Just another +1 for subgrid appeared first on CSS-Tricks.

Where Do You Learn HTML & CSS in 2020?

Css Tricks - Fri, 06/19/2020 - 3:10am

The question of how and where to learn HTML & CSS is a highly reasonable thing to ask. The answer depends on all sorts of things: how serious you are, your current foundation, what other resources are available to you, what you hope to do with what you learn, and how much time you have, among probably a zillion other things.

Let’s look at a bunch of options and you can choose the ones that feel right to you.

You could read a book.

There are a ton of books out there that cover HTML and CSS (and often together). They probably all do a fine job. There’s no need to chronicle all the choices here. These two are my personal recommendations. You probably don’t even need both.

HTML and CSS: Design and Build Websites

Jon Duckett’s is incredibly well-designed and approachable:

Learning Web Design: A Beginner’s Guide to HTML, CSS, JavaScript, and Web Graphics

Jennifer Robbins’ covers a bit more ground and is designed to be useful for either personal reading or as a classroom textbook.

You could go through a free online course or guide. Frontend Masters

Frontend Masters has a very in-depth bootcamp they give away for free. It’s 21 hours of high-quality video learning! If it clicks with you, you can sign up for the more advanced paid courses.

freeCodeCamp

freeCodeCamp is also (wait for it) free and has a step-by-step process to it where you don’t just watch, there are tasks for you to complete.

Khan Academy

Khan Academy has an Intro to HTML/CSS: Making webpages course that’s packaged in a super cool format. It’s like video in that you get to hear the instructor talk you through the learning, but what you see is a real live text editor and real-live output. Sometimes the teacher is controlling the code, and then sometimes it breaks for challenges in which you take over and edit the code yourself.

Don’t Fear the Internet

Jessica Hische and Russ Maschmeyer’s Don’t Fear the Internet is an eight-part series that gets you going with HTML & CSS — it even delves into the all-important topic of typography.

Through short tutorial videos, you’ll learn how to take a basic WordPress blog and manipulate the CSS, HTML (and even some PHP!) to match your aesthetic. 

Interneting is hard

Oliver James has a wonderful online course called Internetting is Hard (But it doesn’t have to be).

We designed HTML & CSS Is Hard to be the only introduction to HTML and CSS that you’ll ever need. If you put in the effort to read every section and write every code snippet, this tutorial has the potential to replace hundreds or even thousand of dollars worth of online courses and live training.

Scrimba / Intro to HTML

Eric Tirado has an Intro to HTML course on Scrimba, which is also a neat platform in that Eric’s voice guides you through the course, but visually it’s a combination of slides with a real code editor and preview.

You could read through all the posts in our Beginner’s Guide.

We have a guide (a collection of articles, videos, and links) called Just Starting Out with CSS & HTML. I hope there is stuff in there that can help kickstart or augment your early learning because that’s the intent.

You could find and take a paid online course.

I often join gyms because the accountability of paying for something gets me to do it. I know I can do situps, pushups, and go for a jog for free, but the gym membership makes a thing of it. Well, same could be said about paying for a course on HTML and CSS.

These are broad generalizations, but good places to start:

You could go to an in-person code school or coding bootcamp Photo by ThisisEngineering RAEng on Unsplash

If you wanna put even more skin in the game, you could consider literally going to school. If you don’t have a college degree, that’s an option, although you’ll be looking at a broad education rather than a ticket to leveling up your web design and development skills alone. I’m a fan of that just for the general mind-broadening it involves.

But assuming you’re going to go to a coding-specific school…

There are probably dozens — if not hundreds — more, so this is more to inform you of the possibility of schooling. You don’t even have to go to a physical school since plenty of these offer online courses, too (but with the advantage of live instruction and cohorts). For example, LambdaSchool has the novelty of being free to start and paid later in the form of letting them take a portion of your salary after you get a job in the industry.

You could practice on CodePen.

Not every second of your learning should be strictly following some course laid out by a book, class, or teacher. It wouldn’t even be that way if you tried. You might as well embrace that. If something tickles your muse, go play!

I hope CodePen is a rewarding place to do that, making it both easy and useful, while providing a place to connect with other folks in the field.

You could build a personal site and learn what you need to get it done.

That’s how absolutely countless developers have cut their teeth, including me. I wanted a personal website years ago, and I struggled through getting a self-hosted WordPress site online so I could have full control over everything and bend it to my will. Once you have an actual website online, and you know at least some people are seeing it, it gives you all the motivation in the world to keep going and evolve further.

Equally as common: build a website for your band. Or a friend, friend-of-a-friend, or the business of your mother’s business partner’s sister. When you have a real project (a real website on the live internet) you have that feet-in-the-fire feeling that you’re responsible for something real that real people are going to see and you have to get it done and do a good job. That works tremendously well for some people.

You will actually learn by doing a combination of all this stuff.

People are obsessed with asking musicians if they’re “self-taught”. Like, if they are, their amazingness triples because it means their creative genius was delivered by a lightning bolt at birth. They don’t need anyone else to learn; they merely look at those guitar strings or piano keys and know what to do.

And if they were taught by a teacher, then, well, that’s all out the door. If they are good at all, then it’s because the teacher delivered that to them.

Total nonsense.

People learn anything — music and web development included — inside a hurricane of influences. Let’s stick with music for a second. Learning to play comes in many forms. You learn by listening to music an awful lot. You can do fundamental practice, like finger exercises and going up and down scales. You can learn to transpose chords on a chalkboard. You can watch YouTube all day and night. You can sign up for online courses. You can go to local jams to watch and play along. You can join a band. You can take lessons from someone advertising on Craigslist. You can go to a local music school. You can read books about music.

You get the idea.

You can and will do all of that. With learning web design and development, getting anywhere will involve all sorts of ways. There’s no silver bullet. It takes bashing on it lots of different ways. There’s no requirement to sprinkle money on it, but you do need multiple angles, time, and motivation.

Go forth and build websites, the ol’ ShopTalk mantra!

The post Where Do You Learn HTML & CSS in 2020? appeared first on CSS-Tricks.

Building a hexagonal grid using CSS grid

Css Tricks - Thu, 06/18/2020 - 4:42am

I think of grids as arrangements of rectangles with vertical and horizontal lines running through. And they are, but that doesn’t mean we can’t still do clever things in how we place things on those grids and what we do with the elements afterwards.

In this demo by Jesse Breneman, a grid of hexagons is created by setting up the grid columns with math such that each block can span over three columns and two rows so that the blocks overlap in a way that allows a clip-path to be applied around them. This carves a block into a hexagon that is evenly spaced with the others. Very clever.

And, ha, that’s a hell of a domain name Jesse. Personally, I don’t know anything about blogging about CSS at a super cheesy domain name.

Direct Link to ArticlePermalink

The post Building a hexagonal grid using CSS grid appeared first on CSS-Tricks.

The Writing Mistress

Typography - Thu, 06/18/2020 - 3:28am

From around the beginning of the 1600s, there was a renewed interest in calligraphy. At the same time, women, known as writing mistresses, begin to teach handwriting and calligraphy to young women. Maria Strick in the Netherlands and Marie Pavie, perhaps from France, are the first two women to have their calligraphy copybooks published in print.

The post The Writing Mistress appeared first on I Love Typography.

Advice for Complex CSS Illustrations

Css Tricks - Wed, 06/17/2020 - 9:14am

If you were to ask me what question I hear most about front-end development, I’d say it’s“How do I get better at CSS?”. That question usually comes up after sharing a CSS illustration I have made. It’s something I love to do over on CodePen.

To many, CSS is this mythical beast that can’t be tamed. This tweet from Chris made me chuckle because, although ironic, there’s a lot of truth to it. That said, what if I told you that you were only a few properties and techniques away from creating anything you wanted? The truth is that you are indeed that close.

I’ve been wanting to compose an article like this for some time, but it’s a hard topic to cover because there are so many possibilities and so many techniques that there’s often more than one way to accomplish the same thing. The same is true with CSS illustrations. There’s no right or wrong way to do it. We’re all using the same canvas. There are simply so many different tools to get those pixels on the page.

While there is no “one size fits all” approach to CSS illustration, what I can offer is a set of techniques that might help you on your journey.

CodePen Embed Fallback Time and practice

CSS illustration takes lots of time and practice. The more accurate you want to be and the more complicated the illustration, the longer it’s going to take. The time-consuming part isn’t usually deciding on which properties to use and how, but the tinkering of getting things to look right. Be prepared to get very familiar with the styles inspector in your browser dev tools! I also recommend trying out VisBug if you haven’t.

Two fantastic CSS artists are Ben Evans and Diana Smith. Both have recently talked about time consumption when referring to CSS illustration.

Diana’s PureCSS Gaze took her two long weekends to complete. She talks about some of her techniques here and here. “If you have the time, patience, and drive, it is certainly possible,” she says.

I posted a meme-like picture about a cup and Ben’s response summed things up perfectly:

I was tempted to create this in CSS when I first saw the tweet but then thought my reply would take about a month.

It takes time!

CSS Illustration pic.twitter.com/vqpQLKTte5

— Jhey &#x1f6e0; (@jh3yy) May 10, 2020> Tracing is perfectly acceptable

We often have an idea of what it is that we want to illustrate. This article isn’t about design, after all.; it’s about taking an image and rendering it with the DOM and CSS. I’m pretty sure this technique has been around since the dawn of time. But, it’s one I’ve been sharing the last few months.

  • Find or create an image of what it is you want to illustrate.
  • Pull it into your HTML with an <img> tag.
  • Position it in a way that it will sit underneath your illustration.
  • Reduce the image opacity so that it’s still visible but not too overpowering.
  • Trace it with the DOM.

To my surprise, this technique isn’t common knowledge. But it’s invaluable for creating accurate CSS illustrations.

See this trick in action here:

Here’s a timelapse of creating that CSS @eggheadio &#x1f60e;

Tweaked the shadows with clip-path after &#x1f6e0;️

&#x1f4bb; https://t.co/XhDRspwwFg via @CodePen #webdev #coding #CSS #animation #webdesign #design #creative #100DaysOfCode #HTML #Timelapse https://t.co/ZQ1hyzcoSA pic.twitter.com/iPf7ksYCGX

— Jhey &#x1f6e0; (@jh3yy) May 1, 2020

And try it out here:

CodePen Embed Fallback Pay attention to responsiveness

If there are two takeaway techniques to take from this article, let it be the “Tracing” one above and this next one. 

There are some fantastic examples of CSS illustration out there. But the one unfortunate thing about some of them is that they aren’t styled — or even viewable — on small screens. We live in an age where first impressions with tech are important. Consider the example of a keyboard illustrated with CSS. Someone comes across your work, opens it up on their smartphone, and they’re greeted with only half the illustration or a small section of it. They probably missed the coolest parts of the demo!

Here’s my trick: leverage viewport units for your illustrations and create your own scaled unit. 

For sizing and positioning, you either have the option of using a scaled unit or percentage. This is particularly useful when you need to use a box shadow because the property accepts viewport units but not percentages.

Consider the CSS egghead.io logo I created above. I found the image I wanted to use and popped it in the DOM with an img tag.

<image src='egghead.png'/> img {   height: 50vmin;   left: 50%;   opacity: 0.25;   position: fixed;   top: 50%;   transform: translate(-50%, -50%); }

The height, 50vmin, is the desired size of the CSS illustration. The reduced opacity allows us to “trace” the illustration clearly as we progress.

Then, we create our scaled unit.

/**   * image dimensions are 742 x 769   * width is 742   * height is 769   * my desired size is 50vmin */ :root {   --size: 50;   --unit: calc((var(--size) / 769) * 1vmin); }

With the image dimensions in place, we can create a uniform unit that’s going to scale with our image. We know the height is the largest unit, so we use that as a base to create a fractional unit.

We get something like this:

--unit: 0.06501950585vmin;

That looks awkward but, trust me, it’s fine. We can use this to size our illustration’s container using calc().

.egg {   height: calc(769 * var(--unit));   position: relative;   width: calc(742 * var(--unit));   z-index: 2; }

If we use either percentages or our new --unit custom property to style elements within the container of our CSS illustration, we will get responsive CSS illustrations… and all it took was a few lines of math using CSS variables!

Resize this demo and you’ll see that everything stay in proportion always using 50vmin as the sizing constraint.

CodePen Embed Fallback Measure twice, cut once

Another tip is to measure things. Heck, you van even grab a tape measure if you’re working with a physical object!

CodePen Embed Fallback

This may look a little funky but I measured this scene. It’s the TV combo unit I have in my lounge. Those measurements equate to centimeters. I used those to get a responsive unit based on the actual height of the TV. We can give that number — and all others — a name that makes it easy to remember what it’s for, thanks to custom properties.

:root {   --light-switch: 15;   --light-switch-border: 10;   --light-switch-top: 15;   --light-switch-bottom: 25;   --tv-bezel: 15;   --tv-unit-bezel: 4;   --desired-height: 25vmin;   --one-cm: calc(var(--desired-height) / var(--tv-height));   --tv-width: 158.1;   --tv-height: 89.4;   --unit-height: 42;   --unit-width: 180;   --unit-top: 78.7;   --tv-bottom: 114.3;   --scaled-tv-width: calc(var(--tv-width) * var(--one-cm));   --scaled-tv-height: calc(var(--tv-height) * var(--one-cm));   --scaled-unit-width: calc(var(--unit-width) * var(--one-cm));   --scaled-unit-height: calc(var(--unit-height) * var(--one-cm)); }

As soon as we calculate a variable, we can use it everywhere. I know my TV is 158.1cm wide and 89.4cm tall. I checked the manual. But in my CSS illustration, it will always scale to 25vmin.

Use absolute positioning on all the things

This one will save you a few keystrokes. More often than not, you’ll be looking to absolutely position elements. Save yourself and put this rule somewhere.

/* Your class name may vary */ .css-illustration *, .css-illustration *:after, .css-illustration *:before, .css-illustration:after, .css-illustration:before {   box-sizing: border-box;   position: absolute; }

Your keyboard will thank you!

Positioning is a tricky concept in CSS. You can read up on it in the CSS Almanac for more information on how to use it.

Or, have a play with this little positioning playground:

CodePen Embed Fallback Stick to an approach

This is by far the hardest thing to do. How do you approach a CSS illustration? Where do you even start? Should you start with the outermost part and work your way in? That doesn’t work so well.

Odds are that you’ll try some approaches and find a better way to go about it. You’ll certainly do a little back-and-forth but, the more you practice, the better you’ll get at spotting patterns and developing an approach that works best for you.

I tend to relate my approach to how you’d go about creating a vector image where illustrations are made up of layers. Split it up and sketch it on paper if you need to. But, start from the bottom and work your way up. This tends to mean larger shapes first, and finer details later. You can always tinker with the stacking index when you need to move elements around.

Maintain a solid structure for your styles

That leads us to the structure. Try to avoid a flat DOM structure for your illustration. Keeping things atomic makes it easier to move parts of your illustration. It will also makes it much easier to show and hide parts of the illustration or even animate them later. Consider the CSS Snorlax demo. The arms, feet, head, etc. are separate elements. That made animating the arm a lot easier than if I had tried to keep things together since I could simply apply the animation to the .snorlax__arm-left class.

CodePen Embed Fallback

Here’s a timelapse shot of me creating the demo:

Attempted to put together a timelapse of the CSS Snorlax we built last night &#x1f605;

Amusing watching it back!

&#x1f4bb; https://t.co/vbVYmFUN5V via @CodePen#webdev #coding #HTML #CSS #webdesign #100DaysOfCode #creative #design #animation pic.twitter.com/0mJtLPRQfP

— Jhey &#x1f6e0; (@jh3yy) April 28, 2020 Handling awkward shapes

There’s a pretty good article right here on CSS-Tricks for creating shapes with CSS. But what about more “awkward” shapes, like a long curve or even an outer curve? In these scenarios, we need to think outside the box. Properties such as overflow, border-radius, and clip-path are big helpers.

Consider this CSS Jigglypuff demo. Toggle the checkbox.

CodePen Embed Fallback

That’s the key for creating curved shapes! We have an element much larger than the body with a border-radius applied. We then apply overflow: hidden to the body to cut that part off.

How might we create an outer curve? This one’s a little tricky. But a trick I like to use is a transparent element with a thick border. Then apply a border-radius and clip the excess, if required.

CodePen Embed Fallback

If you hit the toggle, it reveals the element we are using to go across that corner. Another trick might be to overlay a circle that matches the background color. This is fine until we need to change the background color. It’s OK if you have a variable or something in place for that color. But, it could make things a little harder to maintain.

clip-path is your friend

You might have noticed a couple of interesting CSS properties in that last demo, including clip-path. You’ll most likely need clip-path if you want to create complex CSS shapes. It’s especially handy for cutting off bits of elements when hiding parent box overflow doesn’t do.

Here’s a little demo I built some time ago that showcases different clip-path possibilities.

CodePen Embed Fallback

There’s also this demo that takes ideas from the “Shapes of CSS” article and re-created with clip-path.

CodePen Embed Fallback border-radius is your other friend

You’re going to need border-radius to create curves. One uncommon trick is to use a “double” syntax. This allows you to create a horizontal and vertical radius for each corner.

Play with this demo to really appreciate the power of border-radius. I advocate using percentages across the board in order keep things responsive.

CodePen Embed Fallback Shading techniques

You’ve got all the shapes, everything is nicely laid out, and all the right colors are in place… but something still looks off. Odds are that it’s a lack of shading.

Shading adds depth and create a realistic feel. Consider this ecreation of a Gal Shir illustration. Gal is fantastic at using shades and gradients to make beautiful illustrations. I thought it would be fun to do a recreate it and include a switch that toggles the shading to see just what a difference it makes.

CodePen Embed Fallback

Shading effects are often created with a box-shadow and background-image combination.

The key thing with these properties is that we can stack them in a comma-separated list. For example, the cauldron in the demo has a list of gradients that are being used across the body.

.cauldron {   background:     radial-gradient(25% 25% at 25% 55%, var(--rim-color), transparent),     radial-gradient(100% 100% at -2% 50%, transparent, transparent 92%, var(--cauldron-color)),     radial-gradient(100% 100% at -5% 50%, transparent, transparent 80%, var(--darkness)),     linear-gradient(310deg, var(--inner-rim-color) 25%, transparent), var(--cauldron-color); }

Note that radial-gradient() and a linear-gradient() are being used here and not always with perfectly round numeric values. Again, those numbers are just fine. In fact, you’ll spend a lot of time tweaking and tinkering with things in the style inspector.

It’s generally the same working with box-shadow. However, with that, we can also use the inset value to create tricky borders and additional depth.

.cauldron__opening {   box-shadow:     0 0px calc(var(--size) * 0.05px) calc(var(--size) * 0.005px) var(--rim-color) inset,     0 calc(var(--size) * 0.025px) 0 calc(var(--size) * 0.025px) var(--inner-rim-color) inset,     0 10px 20px 0px var(--darkness), 0 10px 20px -10px var(--inner-rim-color); }

There are certainly times where it will make more sense to go with filter: drop-shadow() instead to get the effect you want.

Lynn Fisher’s a.singlediv.com is a brilliant example of these properties in action. Have a poke around on that site and inspect some of the illustrations for great ways to use box-shadow and background-image in illustrations.

box-shadow is so powerful that you could create your entire illustration with it. I once joked about creating a CSS illustration of a dollar.

In CSS right? &#x1f605;#webdev #CSS #animation #webdesign #coding #100DaysOfCode #HTML https://t.co/VmyeySsK83

— Jhey &#x1f6e0; (@jh3yy) April 22, 2020

I used a generator to create the illustration with a single div. But Alvaro Montoro took it a little further and wrote a generator that does it with box-shadow instead.

Preprocessors are super helpful

While they aren’t required, using preprocessors can help keep your code neat and tidy. For example, Pug makes writing HTML faster, especially when it comes to using loops for dealing with a bunch of repeating elements. From there, we can scope CSS custom properties in a way that we only need to define styles once, then overwrite them where needed.

CodePen Embed Fallback

Here’s another example that demonstrates a DRY structure. The flowers are constructed with the same markup, but each has its own index class that is used to apply scoped CSS properties.

CodePen Embed Fallback

The first flower has these properties:

.flower--1 {   --hue: 190;   --x: 0;   --y: 0;   --size: 125;   --r: 0; }

It’s the first one, so all the others are based off it. Notice how the second flower is off to the right and up slightly. All that takes is assigning different values to the same custom properties:

.flower--2 {   --hue: 320;   --x: 140;   --y: -75;   --size: 75;   --r: 40; }

Animated responsive CSS Leif features in the latest CodePen Spark! ✨

For those who don’t know Animal Crossing, Leif is a green-thumbed Sloth who visits your island &#x1f33b;

Here’s a timelapse! &#x1f4f9;

&#x1f4bb; https://t.co/tkHX4nWXp7 via @CodePen pic.twitter.com/naJIrsSlYM

— Jhey &#x1f6e0; (@jh3yy) May 19, 2020 That’s it!

Go forth, use these tips, come up with your own, share them, and share your CSS masterpieces! And hey, if you have your own advice, please share that too! This is definitely the sort of thing that is learned through lots of trial and error — what works for me may look different from what works for you and we can learn from those different approaches

The post Advice for Complex CSS Illustrations appeared first on CSS-Tricks.

Web Engine Diversity and Ecosystem Health

Css Tricks - Tue, 06/16/2020 - 5:46am

As front-end developers, our job is working with browsers. Knowing how many we have and the health of them is always of great interest. As far as numbers go, we have fewer recently than we have in the past. It’s only this month that Edge is starting to auto-update browsers to the Chromium version, yet another notable milestone in the shrinking number of browsers.

A few years back, Rachel Nabors likened the situation to a biological ecosystem and how diversity means health:

If we lose one of those browser engines, we lose its lineage, every permutation of that engine that would follow, and the unique takes on the Web it could allow for.

And it’s not likely to be replaced.

A huge consideration in all this is the open-source nature of what we have left. Remember that Microsoft’s browser technologies were not open-source. Brian Kardell:

In important ways, we are a more diverse, efficient and healthier ecosystem with the three multi-os, open-source engines we have left (Blink, Gecko, and WebKit) than when we had had more and were dominated by projects that weren’t that at all.

As a followup Stuart Langridge touches on another kind of diversity:

What’s really important is diversity of influence: who has the ability to make decisions which shape the web in particular ways, and do they make those decisions for good reasons or not so good?

Here’s hoping that the browsers we have left will continue to evolve, perhaps even fork, and find ways to compete on anything except standards. While the current situation isn’t as bad as perhaps some folks were worried about with the loss of Microsoft’s engines (and maybe it’s even a good thing), it would certainly be bad news if we lost even more browsers [nervously glancing at Firefox], both in shrinking numbers and shrinking diversity of influence.

Direct Link to ArticlePermalink

The post Web Engine Diversity and Ecosystem Health appeared first on CSS-Tricks.

What is Developer Experience (DX)?

Css Tricks - Mon, 06/15/2020 - 1:31pm

Developer Experience¹ is a term² with a self-declaring meaning — the experience of developers — but it eludes definition in the sense that people invoke it at different times for different reasons referring to different things. For instance, our own Sarah Drasner’s current job title is “VP of Developer Experience” at Netlify, so it’s a very real thing. But a job title is just one way the term is used. Let’s dig in a bit and apply it to the different ways people think about and use the term.

People think of specific companies.

I hear DX and Stripe together a lot. That makes sense. Stripe is a payment gateway company almost exclusively for developers. They are serious about providing a good experience for their customers (developers), hence “developer experience.” Just listen to Suz Hinton talk about “friction journals”, which is the idea of sitting down to use a product (like Stripe) and noting down every single little WTF moment, confusion, and frustration so that improvements can be made:

Netlify is like Stripe in this way, as is Heroku, CodePen, and any number of companies where the entire customer base is developers. For companies like this, it’s almost like DX is what UX (User Experience) is for any other company.

People think of specific technologies.

It’s common to hear DX invoked when comparing technologies. For instance, some people will say that Vue offers a better developer experience than React. (I’m not trying to start anything, I don’t even have much of an opinion on this.) They are talking about things like APIs. Perhaps the state is more intuitive to manage in one vs. the other. Or they are talking about features. I know Vue and Svelte have animation helpers built-in while React does not. But React has hooks and people generally like those. These are aspects of the DX of these technologies.

Or they might be speaking about the feeling around the tools surrounding the core technology. I know create-react-app is widely beloved, but so is the Vue CLI. React Router is hugely popular, but Vue has a router that is blessed (and maintained) by the core team which offers a certain feeling of trust.

> vue create hello-world > npx create-react-app my-app

I’m not using JavaScript frameworks/libraries as just any random example. I hear people talk about DX as it relates to JavaScript more than anything else — which could be due to the people in my circles, but it feels notable.

People think of the world around the technology.

Everybody thinks good docs are important. There is no such thing as a technology that is better than another but has much worse docs. The one with the better docs is better overall because it has better docs. That’s not the technology itself; that’s the world around it.

Have you ever seen a developer product with an API, and when you view the docs for the API while logged in, it uses API keys and data and settings from your own account to demonstrate? That’s extraordinary to me. That feels like DX to me.

Airtable docs showing me API usage with my own data.

“Make the right thing easy,” notes Jake Dohm.

That word, easy, feels highly related to DX. Technologies that make things easy are technologies with good DX. In usage as well as in understanding. How easily (and quickly) can I understand what your technology does and what I can do with it?

What the technology does is often only half of the story. The happy path might be great, but what happens when it breaks or errors? How is the error reporting and logging? I think of Apollo and GraphQL here in my own experience. It’s such a great technology, but the error reporting feels horrendous in that it’s very difficult to track down even stuff like typos triggering errors in development.

What is the debugging story like? Are there special tools for it? The same goes for testing. These things are fundamental DX issues.

People think of technology offerings.

For instance, a technology might be “good” already. Say it has an API that developers like. Then it starts offering a CLI. That’s (generally) a DX improvement, because it opens up doors for developers who prefer working in that world and who build processes around it.

I think of things like Netlify Dev here. They already have this great platform and then say, here, you can run it all on your own machine too. That’s taking DX seriously.

One aspect of Netlify Dev that is nice: The terminal command to start my local dev environment across all my sites on Netlify, regardless of what technology powers them, is the same: netlify dev

Having a dedicated CLI is almost always a good DX step, assuming it is well done and maintained. I remember WordPress before WP-CLI, and now lots of documentation just assumes you’re using it. I wasn’t even aware Cloudinary had a CLI until the other day when I needed it and was pleasantly surprised that it was there. I remember when npm scripts started taking over the world. (What would npm be without a CLI?) We used to have a variety of different task runners, but now it’s largely assumed a project has run commands built into the package.json that you use to do anything the project needs to do.

Melanie Sumner thinks of CLIs immediately as core DX.

People think of the literal experience of coding.

There is nothing more directly DX than the experience of typing code into code editing software and running it. That’s what “coding” is and that’s what developers do. It’s no wonder that developers take that experience seriously and are constantly trying to improve it for themselves and their teams. I think of things like VS Code in how it’s essentially the DX of it that has made it so dominant in the code editing space in such a short time. VS Code does all kinds of things that developers like, does them well, does them fast, and allows for a very wide degree of customization.

TypeScript keeps growing in popularity no doubt in part due to the experience it offers within VS Code. TypeScript literally helps you code better by showing you, for example, what functions need as parameters, and making it hard to do the wrong thing.

Then there is the experience outside the editor, which in the browser itself. Years ago, I wrote Style Injection is for Winners where my point was, as a CSS developer, the experience of saving CSS code and seeing the changes instantly in the browser is a DX you definitely want to have. That concept continues to live on, growing up to JavaScript as well, where “hot reloading” is goosebump-worthy.

The difference between a poor developer environment (no IDE help, slow saves, manual refreshes, slow pipelines) and a great developer environment (fancy editor assistance, hot reloading, fast everything) is startling. A good developer environment, good DX, makes you a better and more productive programmer.

People compare it to user experience (UX).

There is a strong negative connotation to DX sometimes. It happens when people blame it for it existing at the cost of user experience.

I think of things like client-side developer-only libraries. Think of the classic library that everyone loves to dunk: Moment.js. Moment allows you to manipulate dates in JavaScript, and is often used client-side to do that. Users don’t care if you have a fancy API available to manipulate dates. That is entirely a developer convenience. So, you ship this library for yourself (good DX) at the cost of slowing down the website (bad UX). Most client-side JavaScript is in this category.

Equally as often, people connect developer experience and user experience. If developers are empowered and effective, that will “trickle down” to produce good software, the theory goes.

Worst case, we’re in a situation where UX and DX are on a teeter totter. Pile on some DX and UX suffers on the other side. Best case, we find ways to disentangle DX and UX entirely, finding value in both and taking both seriously. Although if one has to win, certainly it should be the users. Like the HTML spec says:

In case of conflict, consider users over authors over implementors over specifiers over theoretical purity. People think about time.

How long does a technology take to adopt? Good DX considers this. Can I take advantage of it without rewriting everything? How quickly can I spin it up? How well does it play with other technologies I use? What is my time investment?

This kind of thing makes me think of some recent experience with Cloudflare Workers. It’s really cool technology that we don’t have time to get all into right here, but suffice to say it gives you control over a website at a high level that we often don’t think about. Like what if you could manipulate a network request before it even gets to your web server? You don’t have to use it, but because of the level it operates on, new doors open up without caring about or interfering with whatever technologies you are using.

Not only does the technology itself position itself well, the DX of using it, while there are some rough edges, is at least well-considered, providing a browser-based testing environment.

A powerful tool with a high investment cost, eh, that’s cool. But a powerful tool with low investment cost is good DX.

People don’t want to think about it.

They say the best typography goes unnoticed because all you see is the what the words are telling you, not the typography itself. That can be true of developer experience. The best DX is that you never notice the tools or the technology because they just work.

Good DX is just being able to do your job rather than fight with tools. The tools could be your developer environment, it could be build tooling, it could be hosting stuff, or it could even be whatever APIs you are interfacing with. Is the API intuitive and helpful, or obtuse and tricky?

Feel free to keep going on this in the comments. What is DX to you?

  1. Are we capitalizing Developer Experience? I’m just gonna go for it.
  2. Looks like Michael Mahemoff has a decent claim on coining the term.

The post What is Developer Experience (DX)? appeared first on CSS-Tricks.

My Flywheel Landing Page

Css Tricks - Mon, 06/15/2020 - 5:14am

Flywheel is my WordPress hosting partner here. I use Local every day for my WordPress local development environment and use their hosting for all my WordPress sites as part of my whole flow, so I’m glad they aren’t just a sponsor but a product I use and like.

Last November some of their crew came out and shot some photos and video with me, which was cool and fun and made me feel famous lolll.

They ultimately built a landing page from it, which is super well done!

Just look at me being all famous.

Check out some photos that Kimberly Bailey took while the gang was here.

And the video!

https://twitter.com/HeyFlywheel/status/1263189100456218630

Anyway feel free to check out that landing page and if your company is headed to make a WordPress hosting decision soon, might as well use my referral link ;)

The post My Flywheel Landing Page appeared first on CSS-Tricks.

Striking a Balance Between Native and Custom Select Elements

Css Tricks - Fri, 06/12/2020 - 4:43am

Here’s the plan! We’re going to build a styled select element. Not just the outside, but the inside too. Total styling control. Plus we’re going to make it accessible. We’re not going to try to replicate everything that the browser does by default with a native <select> element. We’re going to literally use a <select> element when any assistive tech is used. But when a mouse is being used, we’ll show the styled version and make it function as a select element.

That’s what I mean by “hybrid” selects: they are both a native <select> and a styled alternate select in one design pattern.

Custom selects (left) are often used in place of native selects (right) for aesthetics and design consistency. Select, dropdown, navigation, menu… the name matters

While doing the research for this article, I thought about many names that get tossed around when talking about selects, the most common of which are “dropdown” and “menu.” There are two types of naming mistakes we could make: giving the same name to different things, or giving different names to the same thing. A select can suffer from both mistakes.

Before we move ahead, let me try to add clarity around using “dropdown” as a term. Here’s how I define the meaning of dropdown:

Dropdown: An interactive component that consists of a button that shows and hides a list of items, typically on mouse hover, click or tap. The list is not visible by default until the interaction starts. The list usually displays a block of content (i.e. options) on top of other content.

A lot of interfaces can look like a dropdown. But simply calling an element a “dropdown” is like using “fish” to describe an animal. What type of fish it is? A clownfish is not the same as a shark. The same goes for dropdowns.

Like there are different types of fish in the sea, there are different types of components that we might be talking about when we toss the word “dropdown” around:

  • Menu: A list of commands or actions that the user can perform within the page content.
  • Navigation: A list of links used for navigating through a website.
  • Select: A form control (<select>) that displays a list of options for the user to select within a form.

Deciding what type of dropdown we’re talking about can be a foggy task. Here are some examples from around the web that match how I would classify those three different types. This is based on my research and sometimes, when I can’t find a proper answer, intuition based on my experience.

Dropdown-land: Five scenarios where different dropdowns are used across the internet. Read the table below for a detailed description. Diagram LabelScenarioDropdown Type1The dropdown expects a selected option to be submitted within a form context (e.g. Select Age)Select2The dropdown does not need an active option (e.g. A list of actions: copy, paste and cut)Menu3The selected option influences the content. (e.g. sorting list)Menu or Select (more about it later)4The dropdown contains links to other pages. (e.g. A “meganav” with websites links)Disclosure Navigation5The dropdown has content that is not a list. (e.g. a date picker)Something else that should not be called dropdown

Not everyone perceives and interacts with the internet in the same way. Naming user interfaces and defining design patterns is a fundamental process, though one with a lot of room for personal interpretation. All of that variation is what drives the population of dropdown-land. 

There is a dropdown type that is clearly a menu. Its usage is a hot topic in conversations about accessibility. I won’t talk much about it here, but let me just reinforce that the <menu> element is deprecated and no longer recommended. And here’s a detailed explanation about inclusive menus and menus buttons, including why ARIA menu role should not be used for site navigation.

We haven’t even touched on other elements that fall into a rather gray area that makes classifying dropdowns even murkier because of a lack of practical uses cases from the WCAG community.

Uff… that was a lot. Let’s forget about this dropdown-land mess and focus exclusively on the dropdown type that is clearly a <select> element.

Let’s talk about <select>

Styling form controls is an interesting journey. As MDN puts it, there’s the good, the bad, and the ugly. Good is stuff like <form> which is just a block-level element to style. Bad is stuff like checkboxes, which can be done but is somewhat cumbersome. <select> is definitely in ugly terrain.

A lot of articles have been written about it and, even in 2020, it’s still a challenge to create custom selects and some users still prefer the simple native ones

Among developers, the <select> is the most frustrating form control by far, mainly because of its lack of styling support. The UX struggle behind it is so big that we look for other alternatives. Well, I guess the first rule of <select> is similar to ARIA: avoid using it if you can.

I could finish the article right here with “Don’t use <select>, period.” But let’s face reality: a select is still our best solution in a number of circumstances. That might include scenarios where we’re working with a list that contains a lot of options, layouts that are tight on space, or simply a lack of time or budget to design and implement a great custom interactive component from scratch.

Custom <select> requirements

When we make the decision to create a custom select — even if it’s just a “simple” one — these are the requirements we generally have to work with:

  • There is a button that contains the current selected option.
  • Clicking the box toggles the visibility of the options list (also called listbox).
  • Clicking an option in the listbox updates the selected value. The button text changes and the listbox is closed.
  • Clicking outside the component closes the listbox.
  • The trigger contains a small triangle icon pointing downward to indicate there are options.

Something like this:

CodePen Embed Fallback

Some of you may be thinking this works and is good to go. But wait… does it work for everyone?  Not everyone uses a mouse (or touch screen). Plus, a native <select> element comes with more features we get for free and aren’t included in those requirements, such as:

  • The checked option is perceivable for all users regardless of their visual abilities.
  • The component can interact with a keyboard in a predictable way across all browsers (e.g. using arrow keys to navigate, Enter to select, Esc to cancel, etc.).
  • Assistive technologies (e.g. screen readers) announce the element clearly to users, including its role, name and state.
  • The listbox position is adjusted. (i.e. does not get cut off of the screen).
  • The element respects the user’s operating system preferences (e.g high contrast, color scheme, motion, etc.).

This is where the majority of the custom selects fail in some way. Take a look at some of the major UI components libraries. I won’t mention any because the web is ephemeral, but go give it a try. You’ll likely notice that the select component in one framework behaves differently from another. 

Here are additional characteristics to watch for:

  • Is a listbox option immediately activated on focus when navigating with a keyboard?
  • Can you use Enter and/or Space to select an option?
  • Does the Tab key jump go to the next option in the listbox, or jump to the next form control?
  • What happens when you reach the last option in the listbox using arrow keys? Does it simply stay at the last item, does it go back to the first option, or worst of all, does focus move to the next form control? 
  • Is it possible to jump directly to the last item in the listbox using the Page Down key?
  • Is it possible to scroll through the listbox items if there are more than what is currently in view?

This is a small sample of the features included in a native <select> element.

Once we decide to create our own custom select, we are forcing people to use it in a certain way that may not be what they expect.

But it gets worse. Even the native <select> behaves differently across browsers and screen readers. Once we decide to create our own custom select, we are forcing people to use it in a certain way that may not be what they expect. That’s a dangerous decision and it’s in those details where the devil lives.

Building a “hybrid” select

When we build a simple custom select, we are making a trade-off without noticing it. Specifically, we sacrifice functionality to aesthetics. It should be the other way around.

What if we instead deliver a native select by default and replace it with a more aesthetically pleasing one if possible? That’s where the “hybrid” select idea comes into action. It’s “hybrid” because it consists of two selects, showing the appropriate one at the right moment:

  • A native select, visible and accessible by default
  • A custom select, hidden until it’s safe to be interacted with a mouse

Let’s start with markup. First, we’ll add a native <select> with <option> items before the custom selector for this to work. (I’ll explain why in just a bit.)

Any form control must have a descriptive label. We could use <label>, but that would focus the native select when the label is clicked. To prevent that behavior, we’ll use a <span> and connect it to the select using aria-labelledby.

Finally, we need to tell Assistive Technologies to ignore the custom select, using aria-hidden="true". That way, only the native select is announced by them, no matter what.

<span class="selectLabel" id="jobLabel">Main job role</span> <div class="selectWrapper">   <select class="selectNative js-selectNative" aria-labelledby="jobLabel">     <!-- options -->     <option></option>   </select>   <div class="selectCustom js-selectCustom" aria-hidden="true">      <!-- The beautiful custom select -->   </div> </div>

This takes us to styling, where we not only make things look pretty, but where we handle the switch from one select to the other. We need just a few new declarations to make all the magic happen.

First, both native and custom selects must have the same width and height. This ensures people don’t see major differences in the layout when a switch happens.

.selectNative, .selectCustom {   position: relative;   width: 22rem;   height: 4rem; }

There are two selects, but only one can dictate the space that holds them. The other needs to be absolutely positioned to take it out of the document flow. Let’s do that to the custom select because it’s the “replacement” that’s used only if it can be. We’ll hide it by default so it can’t be reached by anyone just yet.

.selectCustom {   position: absolute;   top: 0;   left: 0;   display: none; }

Here comes the “funny” part. We need to detect if someone is using a device where hover is part of the primary input, like a computer with a mouse. While we typically think of media queries for responsive breakpoints or checking feature support, we can use it to detect hover support too using @media query (hover :hover), which is supported by all major browsers. So, let’s use it to show the custom select only on devices that have hover:

@media (hover: hover) {   .selectCustom {     display: block;   } }

Great, but what about people who use a keyboard to navigate even in devices that have hover? What we’ll do is hide the custom select when the native select is in focus. We can reach for an adjacent Sibling combinatioron (+). When the native select is in focus, hide the custom select next to it in the DOM order. (This is why the native select should be placed before the custom one.)

@media (hover: hover) {   .selectNative:focus + .selectCustom {     display: none;   } }

That’s it! The trick to switch between both selects is done! There are other CSS ways to do it, of course, but this works nicely.

Last, we need a sprinkle of JavaScript. Let’s add some event listeners:

  • One for click events that trigger the custom select to open and reveal the options
  • One to sync both selects values. When one select value is changed, the other select value updates as well
  • One for basic keyboard navigation controls, like navigation with Up and Down keys, selecting options with the Enter or Space keys, and closing the select with Esc
CodePen Embed Fallback Usability testing

I conducted a very small usability test where I asked a few people with disabilities to try the hybrid select component. The following devices and tools were tested using the latest versions of Chrome (81), Firefox (76) and Safari (13):

  • Desktop device using mouse only
  • Desktop device using keyboard only
  • VoiceOver on MacOS using keyboard
  • NVDA on Windows using keyboard
  • VoiceOver on iPhone and iPad using Safari

All these tests worked as expected, but I believe this could have even more usability tests with more diverse people and tools. If you have access to other devices or tools — such as JAWS, Dragon, etc. — please tell me how the test goes.

An issue was found during testing. Specifically, the issue was with the VoiceOver setting “Mouse pointers: Moves Voice Over cursor.” If the user opens the select with a mouse, the custom select will be opened (instead of the native) and the user won’t experience the native select.

What I most like about this approach is how it uses the best of both worlds without compromising the core functionality:

  • Users on mobile and tablets get the native select, which generally offers a better user experience than a custom select, including performance benefits.
  • Keyboard users get to interact with the native select the way they would expect.
  • Assistive Technologies can interact with the native select like normal.
  • Mouse users get to interact with the enhanced custom select.

This approach provides essential native functionality for everyone without the extra huge code effort to implement all the native features.

Don’t get me wrong. This technique is not a one-size-fits-all solution. It may work for simple selects but probably won’t work for cases that involve complex interactions. In those cases, we’d need to use ARIA and JavaScript to complement the gaps and create a truly accessible custom select.

A note about selects that look like menus

Let’s take a look back at the third Dropdown-land scenario. If you recall, it’s  a dropdown that always has a checked option (e.g. sorting some content). I classified it in the gray area, as either a menu or a select. 

Here’s my line of thought: Years ago, this type of dropdown was implemented mostly using a native <select>. Nowadays, it is common to see it implemented from scratch with custom styles (accessible or not). What we end up with is a select element that looks like a menu. 

A <select>  is a type of menu. Both have similar semantics and behavior, especially in a scenario that involves a list of options where one is always checked.  Now, let me mention the WCAG 3.2.2 On Input (Level A) criterion:

Changing the setting of any user interface component should not automatically cause a change of context unless the user has been advised of the behavior before using the component.

Let’s put this in practice. Imagine a sortable list of students. Visually, it may be obvious that sorting is immediate, but that’s not necessarily true for everyone. So, when using <select>, we risk failing the WCAG guideline because the page content changed, and ignificantly re-arranging the content of a page is considered a change of context.

To ensure the criterion success, we must warn the user about the action before they interact with the element, or include a <button> immediately after the select to confirm the change.

<label for="sortStudents">   Sort students   <!-- Warn the user about the change when a confirmation button is not present. -->   <span class="visually-hidden">(Immediate effect upon selection)</span> </label> <select id="sortStudents"> ... </select>

That said, using a <select> or building a custom menu are both good approaches when it comes to simple menus that change the page content. Just remember that your decision will dictate the amount of work required to make the component fully accessible. This is a scenario where the hybrid select approach could be used.

Final words

This whole idea started as an innocent CSS trick but, after all of this research, I was reminded once more that creating unique experiences without compromising accessibility is not an easy task.

Building truly accessible select components (or any kind of dropdown) is harder than it looks. WCAG provides excellent guidance and best practices, but without specific examples and diverse practical uses cases, the guidelines are mostly aspirational. That’s not to mention the fact that ARIA support is tepid and that native <select> elements look and behave differently across browsers.

The “hybrid” select is just another attempt to create a good looking select while getting as many native features as possible. Don’t look at this technique experiment as an excuse to downplay accessibility, but rather as an attempt to serve both worlds. If you have the resources, time and the needed skills, please do it right and make sure to test it with different users before shipping your component to the world.

P.S. Remember to use a proper name when making a “dropdown” component. &#x1f609;

The post Striking a Balance Between Native and Custom Select Elements appeared first on CSS-Tricks.

Learn Z-Index Using a Visualization Tool

Css Tricks - Fri, 06/12/2020 - 4:43am

There are some neat interactive demos in here from Thiru Manikandan. There are a couple of very tricky things with z-index that never fail to confuse. In addition to things like requiring positioning and source order, the trickiest are the stacking contexts and parent/child relationships. z-index isn’t a flat playing field. Even if you put z-index: 2147483644¹ on an element, it’s possible nothing will happen because that element might be inside a parent element with its own stacking context and a lower z-index than a sibling or some higher-up level DOM element.

  1. Just three shy of the maximum 2147483647. LOLZ. Hat tip to Dan Danney who mentioned seeing that in the wild recently.

Direct Link to ArticlePermalink

The post Learn Z-Index Using a Visualization Tool appeared first on CSS-Tricks.

CUBE CSS

Css Tricks - Thu, 06/11/2020 - 10:59am

A CSS methodology from Andy Bell:

The most important part of this methodology is the language itself: CSS. It’s key to note its existence in the name because some alternative approaches, such as BEM—which I have enjoyed for many years—can veer very far away from Cascading Style Sheets. I love CSS, though and think that its core capabilities are actually key to scalable CSS.

A favorite bit…

[…] a design system doesn’t just make you think at a micro-level, but also at a macro-level, because you have to make not just decisions about pixels, but also high-level organisation decisions which the design system helps to solve. Design system work is actually diplomacy work, a lot of the time.

This is often where I see narrow, component-only tunnel vision fall short and really, these approaches are less design systems, but more component libraries that solve a much narrower cohort of problems.

I like the idea of approaching CSS both from an inside-out philosophy — focusing on styling very small specific things then grouping them together to grow bigger thing — and from an outside-in philosophy — not forgetting that components need to be composed together sensibly.

Direct Link to ArticlePermalink

The post CUBE CSS appeared first on CSS-Tricks.

How to Reverse CSS Custom Counters

Css Tricks - Thu, 06/11/2020 - 4:42am

I needed a numbered list of blog posts to be listed with the last/high first and going down from there. Like this:

5. Post Title 4. Post Title 3. Post Title 2. Post Title 1. Post Title

But the above is just text. I wanted to do this with a semantic <ol> element.

The easy way

This can be done using HTML’ s reversed property on the <ol>:

<ol reversed>   <li>This</li>   <li>List</li>   <li>Will Be</li>   <li>Numbered In</li>   <li>Reverse</li> </ol>

For most people, this would be enough. Job done. 

But I needed custom styles for the counters. 

Let it be known that custom list number styles can be done with the ::marker pseudo-element, but that isn’t yet supported by Chrome (although I hear it’s coming soon).

Because I wanted fully cross-browser compatible custom number styles, I went with custom counters. 

Adding and styling a custom counter

Styling the counters of an ordered list differently from the rest of the list requires disabling the default counters and creating and show our own using CSS Counters. Chris shared a few recipes a while back that are worth checking out.

Assuming we have the following HTML:

<ol class="fancy-numbered">   <li>Item 1</li>   <li>Item 2</li>   <li>Item 3</li> </ol>

…we first need to disable the default counters that come with all ordered lists by setting the CSS property list-style-type to none like so:

ol.fancy-numbered {   list-style-type: none; }

That takes out all the default numbering. Next, we create a counter in CSS to track the number of items in the list.

ol.fancy-numbered {   list-style-type: none;   counter-reset: a; }

This gives us a counter named “a” but it can be called it whatever you like. Let’s display our counter using the ::before pseudo-element on the list item (<li>).

ol.fancy-numbered li::before {   content: counter(a)'.'; }

This will set the content of the pseudo-element to the value of our counter. Right now, that will print 1’s next to your list item.

We need to tell the CSS counter how to increment.

ol.fancy-numbered li::before {   content: counter(a)'.';   counter-increment: a; }

The starting value of “a” is zero, which seems weird, but the default increment is 1, meaning that becomes the actual starting point.  Incrementing up by 1 just happens to be the default, but we can change that as we’ll soon see.

We can now proceed to apply any custom styles we want to the counter, because the counter is just a text pseudo-element that is wide open to styling:

ol.fancy-numbered li::before {   content: counter(a)'.';   counter-increment: a;      position: absolute;      left: 0;      color: blue;      font-size: 4rem; }

For example, here, we’ve made the counter color blue and increased the font size. These are things that we couldn’t do using the default counter.

Reversing custom counters

If we add the reversed property to the <ol> element like we did before, we will observe no effect because we disabled the default numbering. That’s just what this property does.

<ol class="fancy-numbered" reversed>   <li>Item 1</li>   <li>Item 2</li>   <li>Item 3</li> </ol>

The code above has no effect on our custom numbering. It’s still probably a good idea to leave it on there, since our intention is to reverse the list. This keeps things semantically accurate.

To reverse the visual order of our counter-based numbering, we need to know the total number of items in the list and instruct the counter to start from that number and then decrement from there.

ol.fancy-numbered {   counter-reset: a 4;   list-style-type: none; }

Here, we’re setting counter-reset to 4. In other words, we’re telling the browser to start the count at 4 instead of 1. We use 4 instead of 3, again, because the counter() rule is applied to the first item on the list, which is 0. But, in the case where we’re counting backwards, 4 becomes our 0. If we started from 3 and decremented, wind up at 0 instead of 1.

Next, we alter our counter-increment rule to decrease by 1 rather than increase, by making it a negative integer.

ol.fancy-numbered li:before {   content: counter(a)'.';   counter-increment: a -1;   position: absolute;      left: 0;      color: blue;      font-size: 4rem; }

And that’s it! Now the world is your oyster for stuff like step trackers:

CodePen Embed Fallback

Or how about a timeline:

CodePen Embed Fallback

Maybe a business plan?

CodePen Embed Fallback

The post How to Reverse CSS Custom Counters appeared first on CSS-Tricks.

Syndicate content
©2003 - Present Akamai Design & Development.