Tag: Styles

Having a Little Fun With Custom Focus Styles

Every front-end developer has dealt or will deal with this scenario: your boss, client or designer thinks the outline applied by browsers on focused elements does not match the UI, and asks you to remove it. Or you might even be looking to remove it yourself.

So you do a little research and find out that this is strongly discouraged, because the focus outline is there for a reason: it provides visual feedback for keyboard navigation (using the Tab key), letting users who can’t use a mouse or have a visual impairment know where they are on the screen.

This button shows a focus state with Chrome’s default outline style.

That doesn’t mean you’re stuck with this outline, though. Instead of removing it, you can simply replace it with something else. That way, you’ll keep your interface accessible and get more flexibility on how it looks, so you can better match your UI.

You can start by removing the default browser outline by selecting the focused state of the element and applying outline: none. Then, you may choose from each of the options ahead to replace it:

Change the background color

This works best for elements that can be filled, such as buttons. Select the focused state of the element and apply a contrasting background color to it. The higher the contrast the better because subtle changes may not be strong enough visual cues, particularly in cases where with color blindness and low-vision.

In the example below, both background and border color change; you may pick either or both.

Click or focus with the Tab key to view how this state looks.

See the Pen
Elements replacing native outline focus with background color
by Lari (@larimaza)
on CodePen.

Change the text color

If the element has any text, you can select the focused state and change its color. This also works for icons applied with mask-image; you can select the icon as a descendant of the focused element and change its background color, like the example button below.

See the Pen
Elements replacing native outline focus with text and icon color
by Lari (@larimaza)
on CodePen.

Again, contrast is key. You may also consider using an underline on text links and making it part of the changed state because, as the Web Content Accessibility Guidelines state:

Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element. (Level A)
Understanding Success Criterion 1.4.1

Apply a box shadow

The box-shadow property can do exactly the same job as the outline, except it’s much more powerful — you can now control its color, opacity, offset, blur radius and spread radius. And if a border-radius is specified, the box shadow follows the same rounded corners.

See the Pen
Elements replacing native outline focus with box shadow
by Lari (@larimaza)
on CodePen.

You can get really creative with this technique (seriously though, don’t do this):

See the Pen
Elements replacing native outline focus with insane box shadow
by Lari (@larimaza)
on CodePen.

This works for virtually any type of focusable element, like toggles, checkboxes, radio buttons and slides.

See the Pen
Toggle and radio button replacing native outline focus with box shadow
by Lari (@larimaza)
on CodePen.

Increase the element’s size

As an alternative to color change, you may also resort to subtle size modification as focus feedback. In this example, we’re using transform: scale.

See the Pen
Elements replacing native outline focus with transform scale
by Lari (@larimaza)
on CodePen.

The key here is subtlety. Extreme size changes may cause content reflow, not to mention a poor experience for those who prefer reduced motion.

Replicate existing hover styles

If the element already has a contrasting hover style, you can simply take that style and apply it for the focused state as well. This is a rather elegant solution, as you don’t have to add any new colors or outlines to the interface.

Here’s an example where both the focus and hover states adopt a high contrast to the background of an element’s default style:

See the Pen
Elements replacing native outline focus with hover styles
by Lari (@larimaza)
on CodePen.

Bonus: Customize the default outline

Everything we’ve looked at so far takes the assumption that we want to remove the focus outline altogether. We don’t have to! In fact, it’s a border that we can customize.

button:focus {   outline: 3px dashed orange; }

That’s shorthand and could have been written this way if we want to fine-tune the styles:

button:focus {   outline-width: 3px;   outline-style: dashed;   outline-color: orange; }

One additional superpower we have is the outline-offset property, which is separate from the outline shorthand property but can be used alongside it to change the position of the focus ring:

button:focus {   outline: 3px dashed orange;   outline-offset: 10px; }

Conclusion

You can mix and match all of these options to get custom styles that look appropriate for each component type within your interface.

And it’s worth repeating: Don’t forget to use stark color contrasts and other visual cues in addition to color when adopting custom focus states. Sure, we all want an experience that aligns with our designs, but we can adhere to good accessibility practices in the process. The W3C recommends this tool to test the contrast of colors values against the WCAG guidelines.

The post Having a Little Fun With Custom Focus Styles appeared first on CSS-Tricks.

CSS-Tricks

, , , ,

What I Like About Writing Styles with Svelte

There’s been a lot of well-deserved hype around Svelte recently, with the project accumulating over 24,000 GitHub stars. Arguably the simplest JavaScript framework out there, Svelte was written by Rich Harris, the developer behind Rollup. There’s a lot to like about Svelte (performance, built-in state management, writing proper markup rather than JSX), but the big draw for me has been its approach to CSS.

Single file components

​​

React does not have an opinion about how styles are defined
—React Documentation

​​​​

A UI framework that doesn’t have a built-in way to add styles to your components is unfinished.
—Rich Harris, creator of Svelte

In Svelte, you can write CSS in a stylesheet like you normally would on a typical project. You can also use CSS-in-JS solutions, like styled-components and Emotion, if you’d like. It’s become increasingly common to divide code into components, rather than by file type. React, for example, allows for the collocation of a components markup and JavaScript. In Svelte, this is taken one logical step further: the Javascript, markup and styling for a component can all exist together in a single `.svelte`​ file. If you’ve ever used single file components in Vue, then Svelte will look familiar.

// button.svelte <style>   button {     border-radius: 0;     background-color: aqua;   } </style>  <button>   <slot/> </button>

Styles are scoped by default

By default, styles defined within a Svelte file are scoped. Like CSS-in-JS libraries or CSS Modules, Svelte generates unique class names when it compiles to make sure the styles for one element never conflict with styles from another.

That means you can use simple element selectors like div and button in a Svelte component file without needing to work with class names. If we go back to the button styles in our earlier example, we know that a ruleset for <button> will only be applied to our <Button> component — not to any other HTML button elements within the page. If you were to have multiple buttons within a component and wanted to style them differently, you’d still need classes. Classes will also be scoped by Svelte.

The classes that Svelte generates look like gibberish because they are based on a hash of the component styles (e.g. svelte-433xyz). This is far easier than a naming convention like BEM. Admittedly though, the experience of looking at styles in DevTools is slightly worse as the class names lack meaning.

The markup of a Svelte component in DevTools.

It’s not an either/or situation. You can use Svelte’s scoped styling along with a regular stylesheet. I personally write component specific styles within .svelte files, but make use of utility classes defined in a stylesheet. For global styles to be available across an entire app — CSS custom properties, reusable CSS animations, utility classes, any ‘reset’ styles, or a CSS framework like Bootstrap — I suggest putting them in a stylesheet linked in the head of your HTML document.

It lets us create global styles

As we’ve just seen, you can use a regular stylesheet to define global styles. Should you need to define any global styles from within a Svelte component, you can do that too by using :global. This is essentially a way to opt out of scoping when and where you need to.

For example, a modal component may want to toggle a class to style the body element:

<style> :global(.noscroll) {   overflow: hidden; } </style>

Unused styles are flagged

Another benefit of Svelte is that it will alert you about any unused styles during compilation. In other words, it searches for places where styles are defined but never used in the markup.

Conditional classes are terse and effortless

If the JavaScript variable name and the class name is the same, the syntax is incredibly terse. In this example, I’m creating modifier props for a full-width button and a ghost button.

<script>   export let big = false;   export let ghost = false; </script>  <style>   .big {     font-size: 20px;     display: block;     width: 100%;   }      .ghost {     background-color: transparent;     border: solid currentColor 2px;   } </style>          <button class:big class:ghost>   <slot/> </button>

A class of ghost will be applied to the element when a ghost prop is used, and a class of big is applied when a big prop is used.

<script>   import Button from './Button.svelte'; </script>  <Button big ghost>Click Me</Button>

Svelte doesn’t require class names and prop names to be identical.

<script>   export let primary = false;   export let secondary = false; </script>  <button   class:c-btn--primary={primary}   class:c-btn--secondary={secondary}   class="c-btn">   <slot></slot> </button>

The above button component will always have a c-btn class but will include modifier classes only when the relevant prop is passed in, like this:

<Button primary>Click Me</Button>

That will generate this markup:

<button class="c-btn c-btn--primary">Click Me</button>

Any number of arbitrary classes can be passed to a component with a single prop:

<script> let class_name = ''; export { class_name as class }; </script>  <button class="c-btn {class_name}">   <slot /> </button>

Then, classes can be used much the same way you would with HTML markup:

<Button class="mt40">Click Me</Button>

From BEM to Svelte

Let’s see how much easier Svelte makes writing styles compared to a standard CSS naming convention. Here’s a simple component coded up using BEM.

.c-card {   border-radius: 3px;   border: solid 2px; }  .c-card__title {   text-transform: uppercase; }  .c-card__text {   color: gray; }  .c-card--featured {   border-color: gold; }

Using BEM, classes get long and ugly. In Svelte, things are a lot simpler.

<style> div {   border-radius: 3px;   border: solid 2px; }  h2 {   text-transform: uppercase; }  p {   color: gray; }  .featured {   border-color: gold; } </style>  <div class:featured>   <h2>What I Like About Writing Styles with Svelte</h2>   <p>     <slot />   </p> </div>

It plays well with preprocessors

CSS preprocessors feels a lot less necessary when working with Svelte, but they can work perfectly alongside one another by making use of a package called Svelte Preprocess. Support is available for Less, Stylus and PostCSS, but here we’ll look at Sass. The first thing we need to do is to install some dependencies:

npm install -D svelte-preprocess node-sass

Then we need to import autoPreprocess in rollup.config.js at the top of the file.

import autoPreprocess from 'svelte-preprocess';

Next, let’s find the plugins array and add preprocess: autoPreprocess() to Svelte:

export default {   plugins: [     svelte({       preprocess: autoPreprocess(),       ...other stuff

Then all we need to do is specify that we’re using Sass when we’re working in a component file, using type="text/scss" or lang="scss" to the style tag.

<style type="text/scss">   $ pink: rgb(200, 0, 220);   p {     color: black;     span {       color: $ pink;     }   } </style>

Dynamic values without a runtime

We’ve seen that Svelte comes with most of the benefits of CSS-in-JS out-of-the-box — but without external dependencies! However, there’s one thing that third-party libraries can do that Svelte simply can’t: use JavaScript variables in CSS.

The following code is not valid and will not work:

<script>   export let cols = 4; </script>  <style>   ul {     display: grid;     width: 100%;     grid-column-gap: 16px;     grid-row-gap: 16px;     grid-template-columns: repeat({cols}, 1fr);   } </style>  <ul>   <slot /> </ul>

We can, however, achieve similar functionality by using CSS variables.

<script>   export let cols = 4; </script>  <style>   ul {     display: grid;     width: 100%;     grid-column-gap: 16px;     grid-row-gap: 16px;     grid-template-columns: repeat(var(--columns), 1fr);   } </style>  <ul style="--columns:{cols}">   <slot /> </ul>

I’ve written CSS in all kinds of different ways over the years: Sass, Shadow DOM, CSS-in-JS, BEM, atomic CSS and PostCSS. Svelte offers the most intuitive, approachable and user-friendly styling API. If you want to read more about this topic then check out the aptly titled The Zen of Just Writing CSS by Rich Harris.

The post What I Like About Writing Styles with Svelte appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Weekly Platform News: Preventing Image Loads with the Picture Element, the Web We Want, Svg Styles Are Not Scoped

In this week’s week roundup of browser news, a trick for loading images conditionally using the picture element, your chance to tell bowser vendors about the web you want, and the styles applied to inline SVG elements are, well, not scoped only to that SVG.

Let’s turn to the headlines…

Preventing image loads with the picture element

You can use the <picture> element to prevent an image from loading if a specific media query matches the user’s environment (e.g., if the viewport width is larger or smaller than a certain length value). [Try out the demo:

See the Pen
voZENR
by Šime Vidas (@simevidas)
on CodePen.

<picture>   <!-- show 1⨯1 transparent image if viewport width ≤ 40em -->   <source     media="(max-width: 40em)"     srcset="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"   />    <!-- load only image if viewport width > 40em -->   <img src="product-large-screen.png" /> </picture>

(via Scott Jehl)

The Web We Want

The Web We Want (webwewant.fyi) is a new collaboration between browser vendors that aims to collect feedback from web developers about the current state of the web. You can submit a feature request on the website (“What do you want?””) and get a chance to present it at an event (An Event Apart, Smashing Conference, etc.).

(via Aaron Gustafson)

In other news

  • Firefox supports a non-standard Boolean parameter for the location.reload method that can be used to hard-reload the page (bypassing the browser’s HTTP cache) [via Wilson Page]
  • If you use inline <svg> elements that itself have inline CSS code (in <style> elements), be aware that those styles are not scoped to the SVG element but global, so they affect other SVG elements as well [via Sara Soueidan]
  • XSS Auditor, a Chrome feature that detects cross-site scripting vulnerabilities, has been deemed ineffective and will be removed from Chrome in a future version. You may still want to set the HTTP X-Xss-Protection: 1; mode=block header for legacy browsers [via Scott Helme]

Read more news in my new, weekly Sunday issue. Visit webplatform.news for more information.

The post Weekly Platform News: Preventing Image Loads with the Picture Element, the Web We Want, Svg Styles Are Not Scoped appeared first on CSS-Tricks.

CSS-Tricks

, , , , , , , , , ,
[Top]

Keyboard-Only Focus Styles

Like Eric Bailey says, if it’s interactive, it needs a focus style. Perhaps your best bet? Don’t remove the dang outlines that focusable elements have by default. If you’re going to rock a button { outline: 0; }, for example, then you’d better do a button:focus { /* something else very obvious visually */ }. I handled a ticket just today where a missing focus style was harming a user who relies on visual focus styles to navigate the web.

But those focus styles are most useful when tabbing or otherwise navigating with a keyboard, and less so when they are triggered by a mouse click. Now we’ve got :focus-visible! Nelo writes:

TLDR; :focus-visible is the keyboard-only version of :focus.

Also, the W3C proposal mentions that :focus-visible should be preferred over :focus except on elements that expect a keyboard input (e.g. text field, contenteditable).

(Also see his article for a good demo on why mouse clicking and focus styles can be at odds, beyond a general dislike of fuzzy blue outlines.)

Browser support for :focus-visible is pretty rough:

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

Desktop

Chrome Opera Firefox IE Edge Safari
No No 4* No No No

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
No No No No No 62*

But it does have Firefox support, and as Lea Verou says:

… once Chrome ships its implementation it will explode in a matter of 1-2 months.

That’s generally how things go these days. Once two major browsers have support — and one of them is Chrome — that’s a huge enough slice of the web that can start using it. Especially when it can be done as safely as this property.

Safely, as in, there is an official polyfill, meaning you can nuke default focus styles and just use :focus-visible styles:

/* Remove outline for non-keyboard :focus */ *:focus:not(.focus-visible) {   outline: none; }  /* Optional: Customize .focus-visible */ .focus-visible {   outline: lightgreen solid 2px; }

But, as Patrick H. Lauke documented, you can do it even without the polyfill, using careful selector usage and un-doing styles as needed:

button:focus { /* Some exciting button focus styles */ } button:focus:not(:focus-visible) {   /* Undo all the above focused button styles      if the button has focus but the browser wouldn't normally      show default focus styles */ } button:focus-visible { /* Some even *more* exciting button focus styles */ }

Seems like a nice improvement for the web.

The post Keyboard-Only Focus Styles appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]