Skip to main content

Tagged “tip”

Saving CSS changes in DevTools without leaving the browser

Scott Jehl recently tweeted:

Browser devtools have made redesigning a site such a pleasure. I love writing and adjusting a CSS file right in the sources panel and seeing design changes happen as I type, and saving it back to the file. (…) Designing against live HTML allows happy accidents and discoveries to happen that I wouldn't think of in an unconstrained design mockup

I feel very late to the party here. I tend to tinker in the DevTools Element Styles panel rather than save changes. So, inspired by Scott, I’ve just tried this out on my personal website. Here’s what I did.

  1. started up my 11ty-based site locally which launches a localhost URL for viewing it in the browser;
  2. opened Chrome’s DevTools at Sources;
  3. checked the box “Enable local overrides” then followed the prompts to allow access to the folder containing my SCSS files;
  4. opened an SCSS file in the Sources tab for editing side-by-side with my site in the browser;
  5. made a change, hit Cmd-S to save and marvelled at the fact that this updated that file, as confirmed by a quick git status check.
  6. switched to the Elements panel, opened its Styles subpanel, made an element style change there too, then confirmed that this alternative approach also saves changes to a file.

This is a really interesting and efficient way of working in the browser and I can see me using it.

There are also a couple of challenges which I’ll probably want to consider. Right now when I make a change to a Sass file, the browser takes a while to reflect that change, which diminishes the benefit of this approach. My site is set up such that Eleventy watches for changes to the sass folder as a trigger for rebuilding the static site. This is because for optimal performance I’m purging the compiled and combined CSS and inlining that into the <head> of every file… which unfortunately means that when the CSS is changed, every file needs rebuilt. So I need to wait for Eleventy to do its build thing until the page I’m viewing shows my CSS change.

To allow my SCSS changes to be built and reflected faster I might consider no longer inlining CSS, or only inlining a small amount of critical stuff… or maybe (as best of all worlds) only do the inlining for production builds but not in development. Yeah, I like that latter idea. Food for thought!

Practical front-end performance tips

I’ve been really interested in the subject of Web Performance since I read Steve Souders’ book High Performance Websites back in 2007. Although some of the principles in that book are still relevant, it’s also fair to say that a lot has changed since then so I decided to pull together some current tips. Disclaimer: This is a living document which I’ll expand over time. Also: I’m a performance enthusiast but not an expert. If I have anything wrong, please let me know.

Inlining CSS and or JavaScript

The first thing to know is that both CSS and JavaScript are (by default) render-blocking, meaning that when a browser encounters a standard .css or .js file in the HTML, it waits until that file has finished downloading before rendering anything else.

The second thing to know is that there is a “magic file size” when it comes to HTTP requests. File data is transferred in small chunks of about 14 kb. So if a file is larger than 14 kb, it requires multiple roundtrips.

If you have a lean page and minimal CSS and or JavaScript to the extent that the page in combination with the (minified) CSS/JS content would weigh 14 kb or less after minifying and gzipping, you can achieve better performance by inlining your CSS and or JavaScript into the HTML. This is because there’d be only one request, thereby allowing the browser to get everything it needs to start rendering the page from that single request. So your page is gonna be fast.

If your page including CSS/JS is over 14 kb after minifying and gzipping then you’d be better off not inlining those assets. It’d be better for performance to link to external assets and let them be cached rather than having a bloated HTML file that requires multiple roundtrips and doesn’t get the benefit of static asset caching.

Avoid CSS @import

CSS @import is really slow!

JavaScript modules in the head

Native JavaScript modules are included on a page using the following:

<script type="module" src="main.js"></script>

Unlike standard <script> elements, module scripts are deferred (non render-blocking) by default. Rather than placing them before the closing </body> tag I place them in the <head> so as to allow the script to be downloaded early and in parallel with the DOM being processed. That way, the JavaScript is already available as soon as the DOM is ready.

Background images

Sometimes developers implement an image as a CSS background image rather than a “content image”, either because they feel it’ll be easier to manipulate that way—a typical example being a responsive hero banner with overlaid text—or simply because it’s decorative rather than meaningful. However it’s worth being aware of how that impacts the way that image loads.

Outgoing requests for images defined in CSS rather than HTML won’t start until the browser has created the Render Tree. The browser must first download and parse the CSS then construct the CSSOM before it knows that “Element X” should be visible and has a background image specified, in order to then decide to download that image. For important images, that might feel too late.

As Harry Roberts explains it’s worth considering whether the need might be served as well or better by a content image, since by comparison that allows the browser to discover and request the image nice and early.

By moving the images to <img> elements… the browser can discover them far sooner—as they become exposed to the browser’s preload scanner—and dispatch their requests before (or in parallel to) CSSOM completion

However if still makes sense to use a background image and performance is important Harry recommends including an accompanying hidden image inline or preloading it in the <head> via link rel=preload.

Preload

From MDN’s preload docs, preload allows:

specifying resources that your page will need very soon, which you want to start loading early in the page lifecycle, before browsers' main rendering machinery kicks in. This ensures they are available earlier and are less likely to block the page's render, improving performance.

The benefits are most clearly seen on large and late-discovered resources. For example:

  • Resources that are pointed to from inside CSS, like fonts or images.
  • Resources that JavaScript can request such as JSON and imported scripts.
  • Larger images and videos.

I’ve recently used the following to assist performance of a large CSS background image:

<link rel="preload" href="bg-illustration.svg" as="image" media="(min-width: 60em)">

Self-host your assets

Using third-party hosting services for fonts or other assets no longer offers the previously-touted benefit of the asset potentially already being in the user’s browser cache. Cross domain caching has been disabled in all major browsers.

You can still take advantage of the benefits of CDNs for reducing network latency, but preferably as part of your own infrastructure.

Miscellaneous

Critical CSS is often a wasted effort due to CSS not being a bottleneck, so is generally not worth doing.

References

Use CSS Clamp to create a more flexible wrapper utility (on Piccalilli)

Here’s Andy Bell recommending using CSS clamp() to control your wrapper/container width because it supports setting a preferred value in vw to ensure sensible gutters combined with a maximum tolerance in rem—all in a single line of code.

If we use clamp() to use a viewport unit as the ideal and use what we would previously use as the max-width as the clamp’s maximum value, we get a much more flexible setup.

The code looks like this:

.container {
  width: clamp(16rem, 90vw, 70rem);
  margin-left: auto;
  margin-right: auto;
}

This is pretty cool because I know from experience that coding responsive solutions for wrappers can be tricky and you can end up with a complex arrangement of max-width and media queries whilst still—as Andy highlights—not providing optimal readability for medium-sized viewports.

Using CSS Grid with minmax() is one possible approach to controlling wrappers however this article offers another (potentially better) tool for your kit.

It’s worth noting that Andy could probably have just used width: min(90vw, 70rem) here (as Christopher suggested) because setting the lower bound provided by clamp() is only necessary if your element is likely to shrink unexpectedly and a regular block-level element wouldn’t do that. The clamp approach might be handy for flex items, though.

(via @piccalilli_)

Use Mac Zoom to show the text a screen reader gets

I picked up a good accessibility testing tip from my work colleague Max today.

On a Mac, if you open System > Accessibility > Zoom, you can enable “hover text”. This allows you to hold down command (cmd) and then whatever is under the mouse will be shown. This shows the same text that a screen reader sees so it’s good for checking if bits of the page respond to a screen reader.

Using aria-current is a win-win situation

The HTML attribute aria-current allows us to indicate the currently active element in a sequence. It’s not only great for accessibility but also doubles as a hook to style that element individually.

By using [aria-current] as your CSS selector (rather than a .current class) this also neatly binds and syncs the way you cater to the visual experience and the screen reader experience, reducing the ability for the latter to be forgotten about.

As Léonie Watson explains, according to WAI-ARIA 1.1 there are a number of useful values that the aria-current attribute can take:

  • page to indicate the current page within a navigation menu or pagination section;
  • step for the current step in a step-based process;
  • date for the current date.
  • time for the current time.

I’ve been using the aria-current="page" technique on a couple of navigation menus recently and it’s working well.

Also: my thanks go to Ethan Marcotte, David Kennedy and Lindsey. Ethan recently suggested that the industry should try harder regarding accessibility and recommended subscribing to David Kennedy’s a11y Weekly newsletter. I duly subscribed (it’s great!) and one of the issues linked to Lindsey’s article An Introduction to ARIA states in which I learned about aria-current.

Box Shadow around the full box

Sometimes when coding a UI element you want a shadow around the whole box. However, most CSS box-shadow examples/tutorials tend to show inset box-shadows or ones that otherwise sit off to the side.

Here’s how to apply box-shadow to the whole box for a simple but nice effect.

.box-with-shadow {
  box-shadow: 0 0 4px #ccc;
}

And here’s how it looks:

Lorem ipsum

See all tags.

External Link Bookmark Note Entry Search