15

Bonus Techniques and Parting Advice

In my favorite stories and films, there’s usually a scene where a mentor passes on valuable advice and some magical items to the hero. You know those items will prove useful; you just don’t know when or how.

Well, I’d like to assume the role of mentor in this final chapter—besides, my hair has waned, and I don’t have the looks for the hero role. I would like you, my fine apprentice, to spare me just a few more moments of your time while I offer up some final words of advice before you set forth on your responsive quest.

This chapter will be half philosophical musings and guidance, and half a grab-bag of unrelated tips and techniques. I hope, at some point in your responsive adventures, these tips will prove useful.

Here’s the grab-bag of tips we’ll cover:

  • Truncating text; single-line and multi-line
  • Creating horizontal scrolling panels
  • Customizing scrollbars
  • Using CSS Scroll Snap
  • Smooth scrolling with CSS scroll-behavior

And here are the topics I will suggest guidance on:

  • Getting designs in the browser
  • Testing on real devices
  • Embracing progressive enhancement
  • Defining a browser support matrix
  • Avoiding CSS frameworks in production
  • Hiding, showing, and loading content at different viewports
  • Validators and linting tools
  • Performance
  • The next big things

Right, now pay attention, 007...

In my day-to-day work, I’ve found that I use some CSS features constantly and others hardly ever. I thought it might be useful to share those I’ve used most often, especially those that pop up time and again with responsive projects.

These are in no particular order. None are more important than any other. Just dip in if and when you need them.

Truncating text

Sometimes, you encounter a situation where space is limited and you would prefer to see text truncated rather than wrapped. We’ve been trained to spot truncated text on websites for years with the ellipsis symbol “...”.

Single-line truncation

This is straightforward in CSS. Consider this markup (you can view this example in example_15-01):

<p class="truncate">
  OK, listen up, I've figured out the key to eternal happiness. All you
  need to do is eat lots of scones.
</p>

However, we actually want to truncate the text at 530 px wide, so it looks like this:

Figure 15.1: Truncation is handy when keeping dimensions constant is of paramount importance

Here is the CSS to make that happen:

.truncate {
  width: 530px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

Each one of those properties is needed to make the truncation occur.

You can read the specification for the text-overflow property here: https://drafts.csswg.org/css-overflow-3/#text-overflow.

Whenever the width of the content exceeds the width defined, it will be truncated. The width can just as happily be set as a percentage, such as 100% if it’s inside a flexible container.

We set overflow: hidden to ensure that anything that overruns the box is hidden.

When the content does overrun, text-overflow: ellipsis creates the ellipsis symbol in the correct place to indicate the overrunning content. This could be set to clip if preferred. In that instance, the content just gets clipped where it overflows, possibly mid-character.

The white-space: nowrap property/value pair is needed to ensure that the content doesn’t wrap inside the surrounding element, which is what it would do by default.

Multi-line truncation

There still isn’t a perfect way to do multi-line truncation despite there being a specification: https://drafts.csswg.org/css-overflow-3/#propdef--webkit-line-clamp.

This is based on a proprietary WebKit way of doing things that has been around for so long now that browser providers have actually implemented it in their own browsers, with -webkit- prefix and all!

Right now, you can use -webkit-line-clamp like this, which you can view in example_15-02:

.multi-line-truncate {
    width: 250px;
    text-overflow: ellipsis;
    overflow: hidden;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    display: -webkit-box;
}

And that produces an effect like this:

Figure 15.2: Multi-line truncation is possible with caveats

This seems like exactly what we want. However, be advised that the implementation is brittle. Here are some reasons why. Firstly, if you happen to omit the overflow: hidden declaration, you still get the ellipsis at the line length you specified, but the text continues. Worse, even with those declarations all added, if you happen to add padding inside the box you get a similar effect of an ellipsis at the specified line but with additional text still visible.

It can certainly help you out in a pinch, but be aware of the caveats.

Creating horizontal scrolling panels

When I say horizontal scrolling panel, hopefully you know the kind of thing I mean.

Horizontal scrolling panels are common on the iOS App Store and Google Play Store for showing panels of related content (movies, albums, and more). Where there is enough horizontal space, all of the items are viewable. However, when space is limited (think mobile devices), the panel is scrollable from side to side.

We made a horizontal scrolling panel together in example_05-10 from Chapter 5, Layout with CSS Grid. That will be the start for the finished example_15-03, which we are going to move toward in the next sections. It was already perfectly functional, but there are some new, scrolling-related, treats we can add with CSS that will really elevate the experience of using it.

Our horizontal slider looks like this on an iPhone 13 mini, running iOS 15.5:

Figure 15.3: A horizontal scrolling panel

The markup pattern looks like this; note that I’m just showing the first item in the list for brevity:

<div class="Scroll_Wrapper">
<figure class="Item">
<img src="Sun.jpg" alt="Our Sun in space" />
    <figcaption class="Caption">The Sun</figcaption>
        <p>
            The Sun ...
        </p>
</figure>

To get the scrolling working, we just need a wrapper that is narrower than the sum of its contents and to set it to overflow automatically in the x axis. That way, it won’t scroll if there is enough space, but it will if there isn’t.

With Grid, the main scroller is set like this:

.Scroll_Wrapper {
    display: grid;
    width: 100%;
    overflow-y: hidden;
    overflow-x: auto;
    gap: 0 20px;
    grid-template-rows: auto auto;
    grid-auto-columns: auto;
    grid-auto-flow: column;
}

No matter how many items are added to the grid, it will continue to add them as columns. Skip back to Chapter 5, Layout with CSS Grid, if you need a refresher on any of the properties and values used.

One thing you might not be very happy about is the default scrollbar. This is typically quite elegant on touch devices but a little more unrefined on desktop.

Here it is on Chrome:

Figure 15.4: Default scrollbars in Chrome

And here it is in Firefox (both browsers on macOS):

Figure 15.5: Default scrollbar on Firefox (macOS)

I actually think the default appearance on Firefox is very nice and I’m not sure I would do much to change it. However, the Chrome one could maybe do with a little work.

Styling scrollbars

Nowadays, we can make visual changes to the way scrollbars look. Safari and Chrome use a non-standard approach, while good old Firefox, which steadfastly refused to allow its scrollbars to be changed (since the year 2000!) until there was a specification, now follows the CSS Scrollbars Styling Module Level 1: https://www.w3.org/TR/css-scrollbars-1/.

Let’s start with the specification and see what that gives us. It’s important to note that the specification is purposefully more limiting than some of the non-standard scrollbar controls. This is because it is not possible to know exactly what constituent parts a scrollbar will have on any given system. As such, the specification limits us to the color of the scroll track and thumb (that’s the term for the part you click/touch and drag), and the width of the scrollbar itself. Here it is applied:

.Scroll_Wrapper {
    display: grid;
    width: 100%;
    overflow-y: hidden;
    overflow-x: scroll;
    gap: 0 20px;
    grid-template-rows: auto auto;
    grid-auto-columns: auto;
    grid-auto-flow: column;
    /* standards way, currently only implemented by Firefox */
    scrollbar-color: #b5b5b5 #616161;
    scrollbar-width: thin;
}

With scrollbar-color, you give it two values; the first the color for the scrollbar “thumb,” the second for the track of the scrollbar. For scrollbar-width, you have only three choices: auto, thin, or none. I’ve opted for thin, but as you can see in my case, in Firefox, that has made very little difference:

Figure 15.6: scrollbar-width has a vague effect in Firefox (macOS)

Now, here comes the real problem with the official way of doing things. It has not yet been implemented in Chromium or WebKit browsers.

If, by some cruel twist of fate, you find yourself needing to style scrollbars for the much older legacy browser Internet Explorer, be aware it has its own -ms- prefixed rules for styling and removing the scrollbar.

It’s unsurprising then, that most people turn to using the non-standards way of styling them, as that typically covers the overwhelming majority of users.

However, before we get into the non-standards, proprietary way that Safari and Chrome-based browsers use, an important point. If you are going down the route of altering scrollbars in any significant manner, ensure you consider accessibility. In the example above, I went for a 3:1 color contrast ratio of track to background, and thumb to track. That should be the minimum you opt for, despite the fact that, often, the host operating system’s own scrollbars do not adhere to those contrast ratios!

If you want a deeper dive into the considerations when styling scrollbars, I recommend the following: https://adrianroselli.com/2019/01/baseline-rules-for-scrollbar-usability.html.

Here is what I have added to deal with WebKit and Chrome browsers:

.Scroll_Wrapper::-webkit-scrollbar {
    width: 25px;
    background-color: #616161;
}
.Scroll_Wrapper::-webkit-scrollbar-thumb {
    background-color: #b5b5b5;
    border-radius: 12px;
}

And in Chrome, this is the effect that has:

Figure 15.7: Using non-standards scrollbar styling in Chrome

There are other -webkit- prefixed scrollbar properties; the aim here is merely to get us some equivalence to the “official” declarations we set. Remember, regardless of what you set, mobile browsers tend to do their own things.

For desktop browsers, you could also opt to only show the scrollbar when the parent element is hovered over. However, remember that if you stray from the standard scrollbars, you are liable to make all the accessibility considerations and affordances needed for them to be usable.

Well, with these minor tweaks, our example is in decent shape and fairly consistent. We have a nice simple grid layout, with subgrid in there for browsers that support it, and some custom scrollbar work in there too. Now I want to show you another lovely little scrolling-based extra that is simple to add but produces a very polished result.

CSS Scroll Snap

CSS Scroll Snap snaps the scrolling of content to predefined points in the container. Again, it is a user interface pattern that is commonplace in the interfaces of native applications, app stores, and things like carousels. However, historically, such functionality required JavaScript to implement to get anything approaching a near comparable experience.

You can read the official specification for CSS Scroll Snap at https://www.w3.org/TR/css-scroll-snap-1/.

Let’s use CSS Scroll Snap to add scroll snap functionality to our horizontal “Solar System” container.

The scroll-snap-type property

First of all, we define the scroll-snap-type for our scrolling container. This is where we can decide whether we want the container to scroll snap in the x, y, or both, axes.

This property also allows us to define the strictness of the scroll snapping that is applied. The mandatory value is the one I always opt for unless I’m resetting scroll snapping, at which point you can use none. none will revert scroll snap to behave like a standard scroll container.

What mandatory does is ensure that if an item is partially scrolled within the container (for example, the left-hand side is off the viewport by a certain amount), then it will be “snapped” into or out of view.

There is also a proximity value. What this does is leave the snapping to the discretion of the browser.

It is important to understand why you may occasionally want and need to use proximity. Suppose you had items in a carousel that were always bigger than the viewport. Because, with mandatory, it would always snap, you may have trouble advancing the scroll panel. Setting it to proximity means that content will remain accessible as the browser will determine how much room should be left to accommodate scrolling.

Despite that, in our instance, since we know the width of our cells won’t exceed the width of the viewport, we will apply mandatory for a consistent experience.

So, our container will be amended with this extra line:

.Scroll_Wrapper {
    /* other styles */    
    scroll-snap-type: x mandatory;
}

Now, if you refresh the browser and try the scroll panel, you will likely be disappointed. That, by itself, doesn’t do anything. We now need to apply the scroll-snap-align property to the child items.

The scroll-snap-align property

The scroll-snap-align property controls where an item inside a scroll-snap container will snap to. The options are:

  • none to reset an item.
  • start to snap the item to the beginning of a scroll snap area.
  • end to snap the item to the end of a scroll snap area.
  • center to snap the item to the center of the scroll snap area.

So, let’s add .Item and set it to snap to the start:

.Item {
    /* other styles */
    scroll-snap-align: start;
}

Now, if you scroll, you’ll see that the items snap within their container.

The scroll-snap-stop property

By default, an excessive scroll action can send several items past the scroll snap point. With scroll-snap-stop, it is possible to make the browser stop at each snap point with each scroll action. There are just two values to choose from:

  • normal, which is what the browser does by default; or
  • always, which ensures that no scroll snap points are skipped.

You add this declaration onto the items inside the scroll container.

The only slight annoyance is that, as I write this, scroll-snap-stop is not supported in Firefox. However, if this is functionality you want, there is no need to add a fallback; Firefox will skip over it and the browsers that understand it will make use of it.

CSS Scroll Snap is a hugely satisfying piece of functionality to use! In just a few lines, we are able to achieve in CSS what used to take whole libraries of JavaScript to achieve. All this talk of scrolling brings me to another, simple but effective, feature I need to relate.

Smooth scrolling with CSS scroll-behavior

One of the oldest capabilities of HTML is the ability to anchor to different points in a document. You set a link on the page, and rather than it sending the user to another webpage, the user is instead instantly taken to a different point on the same page.

Typically, such functionality is in the y axis, or down a page. However, it works just as well horizontally in the x axis.

Historically, jumping to an anchor link has always been a little jarring. As the user is instantly transported to the new point on the page, there is no affordance to communicate to the user what just occurred. People have solved this common issue over the years with the help of JavaScript, by effectively animating the scroll action.

Now the Web Platform has provided us with a simple API to achieve this effect, which can be used by either JavaScript or CSS. For CSS, it is the scroll-behavior property.

I’m going to add “start” and “end” anchor points to each end of the scroll panel we just made and add two links below the scrolling panel.

So, on the first scrolling item we add this id:

<figure id="start" class="Item">

And on the last this:

<figure id="end" class="Item">

And our two links look like this:

<a class="ScrollBtn" href="#start">Start</a>
<a class="ScrollBtn" href="#end">End</a>

Now, our mechanism is set up as traditional anchor points: as you might imagine, by default, clicking on End instantly scrolls the panel to the end. However, if we add scroll-behavior: smooth to our scroll panel, we get a silky-smooth scroll behavior instead:

.Scroll_Wrapper {
    display: grid;
    width: 100%;
    overflow-y: hidden;
    overflow-x: scroll;
    gap: 0 20px;
    grid-template-rows: auto auto;
    grid-auto-columns: auto;
    grid-auto-flow: column;
    /* standards way, currently only implemented by Firefox */
    scrollbar-color: #b5b5b5 #616161;
    scrollbar-width: thin;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
}

Nice! Sadly, this is something that images just don’t convey. However, if you open example_15-03, then you can have a play with it for yourself.

We’ve taken a basic scrolling panel and, with some choice CSS, managed to add custom-colored scrollbars, smooth scrolling, and snap points for a very impressive and robust user experience.

We’ve reached the end of the bonus techniques section. Hopefully, you have a few more handy tricks in your arsenal for the next project you embark on.

Parting advice

All that is left, in the remainder of the chapter, and indeed the book (please, don’t cry—you’ll start me off), is for me to offer what I feel are the most important considerations for any responsive web project. Here goes.

Getting designs in the browser as soon as possible

The more responsive web work I have done, the more important I have found it to get designs up and running in a browser environment as soon as possible. If you are a designer as well as a developer, then that simplifies matters. As soon as you have enough of a feel, visually, for what you need, you can get it prototyped and develop the idea further in a browser environment.

If you are primarily a developer, then this can aid the design process hugely in order to get the design living and breathing in the browser. Without fail, every project that I work on gets revised in some way as a result of the designs being built in the browser. That isn’t a failure of the original flat designs; it’s a consequence of realizing that the design is just a step towards realizing an idea. And seeing it working in a browser is one step closer.

There is a slew of problems that can only be solved by seeing the design in a browser. What about all those device and browser window sizes? What about the interactivity that occurs when the user opens a menu? How long should that introductory animation run for? And is it too much anyway? These are the kind of design decisions that can only be made when the design is realized in a browser.

Testing on real devices

If you can, start to build up a “device lab” of older devices (phones/tablets) to view your work on. Having a number of varied devices is hugely beneficial. Not only does it let you feel how a design actually works across different devices, but it also exposes layout/rendering peculiarities earlier in the process. After all, no one enjoys believing that they have finished a project only to be told it doesn’t work properly in a certain environment. Test early, and test often! Buying extra devices need not cost the earth. For example, you can pick up older phone and tablet models on eBay, or buy them from friends/relatives as they upgrade.

Embracing progressive enhancement

In previous chapters, we have considered the notion of progressive enhancement. It’s an approach to development that I have found so useful in practice that I think it bears repeating.

The fundamental idea of progressive enhancement is that you begin all your frontend code (HTML, CSS, or JavaScript) with the lowest common denominator in mind. Then, you progressively enhance the code for more capable devices and browsers. That may seem simplistic, and it is, but if you are used to working the other way around, then by designing the optimum experience and then figuring out a way of making that thing work on lesser devices/browsers, you’ll find progressive enhancement an easier approach.

Imagine a low-powered, poorly featured device. It has no JavaScript, no Grid support—the most basic of devices you can imagine. In that scenario, what can you do to provide a usable experience? Most importantly, you should write meaningful HTML5 markup that accurately describes the content. This is an easier task if you’re building text- and content-based websites. In that instance, concentrate on using elements like main, header, footer, article, section, and aside correctly. Not only will it help you discern different sections of your code, but it will also provide greater accessibility for your users at no extra cost.

If you’re building something like a web-based application or visual UI components (carousels, tabs, accordions, and the like), you’ll need to think about how to distill the visual pattern down into accessible markup.

The reason good markup is so crucial is that it provides a base-level experience for all users. The more you can achieve with HTML, the less you have to do in CSS and JavaScript to support older browsers. And nobody, and I really mean nobody, likes writing the code to support older browsers.

It’s by no means a simple feat to think in this manner. However, it is an approach that is likely to serve you well in your quest to do as little as possible to support ailing browsers. Now, about those browsers…

Defining a browser support matrix

Knowing the browsers and devices a web project needs to support upfront can be crucial to developing a successful responsive web design. We’ve already considered why progressive enhancement is so useful in this respect. If done correctly, it means that the vast majority of your site will be functional on even the oldest browsers.

However, there may also be times when you need to start your experience with a higher set of prerequisites. Perhaps you are working on a project where JavaScript is essential, which is not an uncommon scenario. In that instance, you can still progressively enhance, but you are merely enhancing from a different starting point.

Whatever your scenario, the key thing is to establish what your starting point is. Then, and only then, can you define and agree on what visual and functional experiences the different browsers and devices that you intend to support will get.

Functional parity, not visual parity

It’s both unrealistic and undesirable to get any website looking and working the same in every browser. Besides quirks that are specific to certain browsers, there are essential functional considerations. For example, we have to consider things like touch targets for buttons and links on touchscreens that aren’t relevant to mouse-based devices.

Therefore, some part of your role as a responsive web developer is to educate whoever you are answerable to (your boss, client, or shareholders) that “supporting older browsers” does not mean “looking the same in older browsers.” The line I tend to run with is that all browsers in the support matrix will get functional parity, not visual parity. This means that if you have a checkout to build, all users will be able to go through the checkout and purchase goods. There may be visual and interaction flourishes afforded to the users of more modern browsers, but the core task will be achievable by all.

Plus, we are in somewhat of a golden era when it comes to support for CSS features. There are still some features you can only get in one browser, but the overwhelming majority of important features nowadays enjoy broad support.

Browser vendors themselves have even had programs to ensure greater interoperability. Read more about that here: https://web.dev/interop-2022/.

Choosing the browsers to support

Typically, when we talk about which browsers to support, we’re talking about how far back we need to look. Here are a couple of possibilities to consider, depending on the situation.

If it’s an existing website, take a look at the visitor statistics (for example, Google Analytics or similar). Armed with some figures, you can do some rough calculations. For example, if the cost of supporting browser X is less than the value produced by supporting browser X, then support browser X!

Also, consider that if there are browsers in the statistics that represent less than 10% of users, look further back and consider any trends. How has usage changed over the last 3, 6, and 12 months? If it’s currently 6% and that value has halved over the last 12 months, then you have a more compelling argument to consider ruling that browser out for specific enhancements.

If it’s a new project and statistics are unavailable, I usually opt for a “previous 2” policy. This would be the current version, plus the previous two versions of each browser. For example, if Safari 16 was the current version, look to offer your enhancements for that version plus Safari 15 and Safari 14 (the previous two). This choice is easier with the “evergreen” browsers, which is the term given to browsers that continually update on a rapid release cycle (Firefox, Chrome, and Microsoft Edge, for example).

Tiering the user experience

Let’s assume your shareholders are educated and on board. Let’s also assume you have a clear set of browsers that you would like, and need, to add enhanced experiences for. We can now set about tiering the experience. I like to keep things simple, so, where possible, I opt to define a simple “base” tier and a more “enhanced” tier.

Here, the base experience is the minimum viable version of the site, and the enhanced version is the most fully featured and aesthetically pleasing version. You might need to accommodate more granularity in your tiers, but regardless of how the tiers are defined, ensure you define them and what you expect to deliver with each. Then you can go about coding those tiers. That’s where techniques like feature queries, which we covered in Chapter 6, CSS Selectors, Typography, and More, will come in handy.

Avoiding CSS frameworks in production

There are a plethora of free CSS frameworks available that aim to aid in the rapid prototyping and building of responsive websites. The two most common examples are Bootstrap (https://getbootstrap.com) and Foundation (https://get.foundation/). While they are great projects, particularly for learning how to build responsive visual patterns, I think they should be avoided in production.

I’ve spoken to plenty of developers who start all of their projects with one of these frameworks and then amend them to fit their needs. This approach can be incredibly advantageous for rapid prototyping (for example, to illustrate some interaction with clients), but I think it’s the wrong thing to do for projects you intend to take through to production.

Firstly, from a technical perspective, it’s likely that starting with a framework will result in your project having more code than it actually needs. Secondly, from an aesthetic perspective, due to the popularity of these frameworks, it’s likely your project will end up looking very similar to countless others.

Finally, if you only copy and paste code into your project and tweak it to your needs, you’re unlikely to fully appreciate what’s going on “under the hood.” It’s only by defining and solving the problems you have that you can master the code you place into your projects.

Hiding, showing, and loading content across viewports

One of the commonly touted maxims regarding responsive web design is that if you don’t have something on the screen in smaller viewports, you shouldn’t have it there in larger ones either.

This means users should be able to accomplish all the same goals (such as buying a product, reading an article, or accomplishing an interface task) at every viewport size. This is common sense. After all, as users ourselves, we’ve all felt the frustration of going to a website to accomplish a goal and being unable to, because we’re using a smaller screen.

This also means that as screen real estate is more plentiful, we shouldn’t feel compelled to add extra things just to fill the space (widgets, adverts, or links, for example). If the user could live without those extras on smaller screen sizes, they’ll manage just fine on bigger ones.

In broad terms, I think the preceding maxim is sound advice. If nothing else, it makes designers and developers question more thoroughly the content they display onscreen. However, as ever in web design, there will be exceptions.

As far as possible, I resist loading in new markup for different viewports, but, very occasionally, it’s a necessity. Some complex user interfaces might simply work better with different markup and designs at wider viewports. In that instance, JavaScript is typically used to replace one area of markup with another. It isn’t the ideal scenario, but it is sometimes the most pragmatic.

By the same token, I think it’s perfectly reasonable to have sections of markup hidden in CSS until they are appropriate. I’m thinking about things like headers. On more than one occasion, before Grid was well supported, I wasted an inordinate amount of time trying to figure out how to convert one header layout for mobile into a different layout for larger screens, all while using the same markup. It was folly! The pragmatic solution is to have both pieces of markup and just hide each as appropriate with a media query. When the difference is a handful of elements and the associated styles, there are almost always more sensible savings to make elsewhere.

These are the choices you will probably face as you code more and more complex responsive web designs, and you’ll need to use your own judgment as to what the best choice is in any given scenario. However, it’s not a cardinal sin if you toggle the visibility of the odd bit of markup with display: none to achieve your goal.

Validators and linting tools

Generally speaking, writing HTML and CSS is pretty forgiving. You can nest the odd thing incorrectly, miss the occasional quotation mark or self-closing tag, and not always notice a problem. Despite this, on an almost weekly basis, I manage to befuddle myself with incorrect markup. Sometimes, it’s a slip-up, like accidentally typing an errant character. Other times, it’s schoolboy errors like nesting a div inside a span (invalid markup as a span is an inline element and a div is a block-level element, which leads to unpredictable results).

Thankfully, there are great tools to help out. At worst, if you’re encountering a weird issue, head over to https://validator.w3.org/ and paste your markup in there. It will point out any errors along with line numbers, helping you to easily fix things up:

Figure 15.8: Skip the validation of HTML at your peril!

Better still, install and configure linting tools for your HTML, CSS, and JavaScript. Or, choose a text editor with some sanity checking built in. Then, problem areas are flagged up in your code as you go.

Here’s an example of a simple spelling error in CSS flagged up by the LSP (Language Server Protocol) in the Neovim editor:

Figure 15.9: Embrace tooling that saves you from basic mistakes

Like a clown, I’ve clumsily typed “marrgin” instead of “margin”. The editor has spotted this fact and pointed out the error of my ways. Embrace these tools where possible. There are better uses of your time than tracking down simple syntax errors in your code.

Performance

Considering the performance of your responsive web designs is as important as the aesthetics. However, performance presents something of a moving target. For example, browsers update and improve the way they handle assets, new techniques are discovered that supersede existing “best practices,” and technologies eventually get enough browser support that they become viable for widespread adoption. The list goes on.

There are, however, some basic implementation details that are pretty solid advice. These are:

  • Minimize the page weight. If you can compress images to a fraction of their original size, you should. This should always be your first task with optimizing. It’s possible to double the file size savings by compressing one image compared to compressing and minifying all of your CSS and JavaScript. We looked at image optimization more fully in Chapter 9, Responsive Images.
  • Defer non-essential assets. If you can load any additional CSS and JavaScript after the page has initially rendered, it can greatly reduce the perceived load time.
  • Ensure the page is usable as soon as possible, which is often a byproduct of doing all the preceding points.

Performance tools

There are great tools available to measure and optimize performance. My personal favorite is https://webpagetest.org. At its simplest, you can pick a URL and click on START TEST.

It will show you a complete analysis of the page, but even more usefully, if you choose the visual comparison option, it shows a “filmstrip” view of the loaded page, allowing you to concentrate on getting the rendered page completed sooner. Here’s an example of the “filmstrip” view of the previous version of the https://rwd.education home page:

Figure 15.10: Seeing the page load as a filmstrip can really tell the story of performance

Even the free tier of this service will offer practical advice on what to do to make your website load faster and be more accessible. I learn something new almost every time I test a site there!

There are also increasingly powerful performance tools built into browser developer tools. Although, you should be aware these can be a little intimidating at first use. It can feel a little like opening something like After Effects for the first time and wondering what on earth you are supposed to do!

Delving into the developer tools in any detail is beyond our discussion scope here, but let’s consider some of the kinds of information you can get at to improve the performance of your site.

If you’re working on something that uses a lot of JavaScript or video, which is sure to negatively affect the device battery, then the CPU timeline feature of Safari (macOS only, unfortunately) may be of interest: https://webkit.org/blog/8993/cpu-timeline-in-web-inspector/.

Firefox has the Profiler tool, which mercifully has a full guide here: https://profiler.firefox.com/docs/#/. It can give you incredibly detailed information, including the same kind of filmstrip feedback we saw in Web Page Test. I’ll confess to finding it a little unapproachable, especially when we are typically looking for the “low-hanging fruit” when it comes to fixing up our sites.

Figure 15.11: Firefox Profiler is powerful but perhaps overkill

Typically, I tend to use Lighthouse, which has its own tab in the Google Chrome developer tools. Point it at a site and it will give you a breakdown of where improvements can be made:

Figure 15.12: The Lighthouse tools not only tell you what you can improve, but they tell you how to do it

It’s such a great tool, as every piece of advice has links to additional documentation, so you read more about the problem and potential ways of addressing it.

If you are new to looking at the performance of the sites you are making, my advice would be to start with Lighthouse and go deeper only if you feel you need or want to. If you have four scores close to 100 in Lighthouse, you’ve done a decent job.

Whenever you try to optimize performance, ensure you take measurements before you begin (otherwise, you will not understand how effective your performance work has been). Then make amendments, test, and repeat.

The next big things

One of the interesting things about front-end web development is that things change rapidly. There is always something new to learn and the web community is always figuring out better, faster, and more effective ways of solving problems.

For example, when writing the first edition of this book, over ten years ago, responsive images (srcset and the picture element, which are detailed in Chapter 9, Responsive Images) simply didn’t exist. Back then, we had to use clever third-party workarounds to serve up more appropriate images to different viewport sizes. Now, that common need has been rationalized into a W3C standard, which has been implemented across browsers.

Similarly, only a few years ago, Flexbox was just a twinkle in a specification writer’s eyes. Even when the specification evolved, it was still difficult to implement until a super-smart developer called Andrey Sitnik, along with his colleagues at Evil Martians (https://evilmartians.com/) created Autoprefixer. This was a tool that allowed us to write a single syntax and have our CSS be processed into code that could work across multiple implementations as if by magic. Skip forward a few more years and prefixing CSS values is a practice few even need to concern themselves with.

Progress on the web shows little sign of abating. Even now, things like WebAssembly, or WASM, as it is often referred to, are gaining more and more traction. WebAssembly is a means of having web code that runs far more akin to the speed of a compiled language. In short, it will make things on the web feel a whole lot faster. Lin Clark, a developer at the browser-maker Mozilla, has a very accessible series on WebAssembly here: https://hacks.mozilla.org/2017/02/a-cartoon-intro-to-webassembly/. Design tools you may be familiar with, such as Figma, make extensive use of WebAssembly: https://www.figma.com/blog/webassembly-cut-figmas-load-time-by-3x/.

And due to the current infancy and few implementations, in this book, we didn’t even look at things like scroll-linked animations, @when/else for “logic” in CSS, scoped styles to isolate styles to a particular section of the DOM, or the @property CSS at-rule for creating your own properties.

In short – expect change, and embrace it!

Summary

As we reach the end of our time together, your humble author hopes to have related all the essential techniques and tools you’ll need to start building your next website or web application responsively.

It’s my conviction that, by approaching web projects with a little forethought, and by potentially making a few modifications to existing workflows and practices, it’s possible to embrace modern techniques that provide fast, flexible, accessible, and maintainable websites that can look incredible, regardless of the device used to visit them.

We’ve covered a wealth of information in our time together: techniques, technologies, performance optimizations, specifications, workflow, tooling, and more. I wouldn’t expect anybody to absorb it all in one read.

Therefore, the next time you need to remember this or that syntax, or to refresh your mind about one of the responsive-related subjects we’ve covered, I hope you’ll dip back into these pages; I’ll be right here waiting for you.

Until then, I wish you good fortune in your responsive web design quests.

See you again sometime.

Join our book’s Discord space

Before you embark on your responsive journey, join the book’s Discord workspace to discuss all your responsive web design concerns directly with the author and interact with other readers:

https://packt.link/RWD4e

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset