Jump to Navigation

Around The Web

Monthly Web Development Update 1/2019: Rethinking Habits And Finding Custom Solutions

Smashing Magazine - Fri, 01/18/2019 - 6:40am
Monthly Web Development Update 1/2019: Rethinking Habits And Finding Custom Solutions Monthly Web Development Update 1/2019: Rethinking Habits And Finding Custom Solutions Anselm Hannemann 2019-01-18T12:40:24+01:00 2019-01-18T21:18:05+00:00

What could be better than starting the new year with some new experiments? Today I figured it was time to rethink JavaScript tooling in one of my projects. And since we wrote everything in plain ECMAScript modules already, I thought it would be easy to serve them natively now and remove all the build and transpilation steps. Until I realized that — although we wrote most code ourselves — we have a couple of third-party dependencies in there and, of course, not all of them are ECMAScript modules. So for now, I have to give up my plans to remove all the build steps and continue to bundle and transpile things, but I’ll try to figure out a better solution to modernize and simplify our tooling setup while providing a smaller bundle to our users.

Another experiment: Just a few weeks ago I had to build a simple “go to the top of the page” button for a website. I used requestAnimationFrame and similar stuff to optimize event handling, but today I found a way nicer and more efficient solution that uses IntersectionObserver to toggle the button on the viewport. You will find that article in the JavaScript section below. The reason I wanted to share these little stories is because I believe that the most important thing is that we review our habits and current solutions and see whether there are better, newer, simpler ideas that could improve a product. Keep playing, keep researching, and be sure to rethink existing systems from time to time.

News UI/UX Web Performance JavaScript Passwordless authentication? The WebAuthn API makes it possible. (Image credit) CSS Una Kravet’s “super underline” example uses randomly generated underlines for each element. Made possible with Houdini and the Paint API. (Image credit) Work & Life
  • “Feeling a sense of accomplishment is an important part of our sense of self-worth. Beating up on yourself because you think you could have accomplished more can dent your confidence and self-esteem and leave you feeling depleted at the end of the day.” Lisa Evans shares what we can do to avoid falling into that trap.
  • Itamar Turner-Trauring shares his thoughts on how to get a job with a good work-life balance when you’re competing against people who are willing to work long hours.
  • Is it a good idea to provide healthcare and treatment based on digital products like apps? And if so, what are the requirements, the standards for this? How can we ensure this is done ethically correct? How do we set the limits, the privacy boundaries, how far do we allow companies to go with experiments here? Would personalized content be fine? Is it okay to share data collected from our devices with healthcare providers or insurances? These are questions we will have to ask ourselves and find an individual answer for.
  • This article about how Millenials became the burnout generation hit me hard this week. I see myself in this group of people described as “Millenials” (I do think it affects way more people than just the 20-year-olds) and I could relate to so many of the struggles mentioned in there that I now think that these problems are bigger than I ever imagined. They will affect society, politics, each individual on our planet. Given that fact, it’s crazy to hear that most people today will answer that they don’t have a friend they could talk to about their fears and anything else that disturbs them while two decades ago the average answer was still around five. Let’s assure our friends that we’re there for them and that they can talk to us about tough things. 2019 should be a year in which we — in our circle of influence — make it great to live in a human community where we can think with excitement and happiness about our friends, neighbors, and people we work with or talk to on the Internet.
  • We all try to accommodate so many things at the same time: being successful and productive at work, at home, with our children, in our relationships, doing sports, mastering our finances, and some hobbies. But we blindly ignore that it’s impossible to manage all that on the same level at the same time. We feel regret when we don’t get everything done in a specific timeframe such as at the end of a calendar year. Shawn Blanc argues that we should celebrate what we did do instead of feeling guilty for what we didn’t do.
Going Beyond…
  • There are words, and then there are words. Many of us know how harmful “just” can be as a word, how prescriptive, how passively aggressive it is. Tobias Tom challenges whether “should” is a useful word by examining the implicit and the result of using it in our daily language. Why “should” can be harmful to you and to what you want to achieve.
  • “We all know what we stand for. The trick is to state our values clearly — and to stand by them,” says Ben Werdmuller and points out how important it is to think about your very own red line that you don’t want to cross regardless of external pressure you might face or money you might get for it.
  • Exciting news for climate improvement this week: A team of arborists has successfully cloned and grown saplings from the stumps of some of the world’s oldest and largest coast redwoods, some of which were 3,000 years old and measured 35 feet in diameter when they were cut down in the 19th and 20th centuries. Earlier this month, 75 of the cloned saplings were planted at the Presidio National Park in San Francisco. What makes this so special is the fact that these ancient trees can sequester 250 tons of carbon dioxide from the atmosphere over their lives, compared to 1 ton for an average tree.
  • The ongoing technological development and strive to build new services that automate more and more things make it even more critical to emphasize human connection. Companies that show no effort in improving things for their clients, their employees, or the environment will begin to struggle soon, Ryan Paugh says.
  • We usually don’t expect much nice news about technology inventions from the car industry and their willingness to share it with others. But Toyota now has decided to share their automated safety system ‘Guardian’ with competitors. It uses self-driving technology to keep cars from crashing. “We will not keep it proprietary to ourselves only. But we will offer it in some way to others, whether that’s through licensing or actual whole systems,” says Gill Pratt from the company.

Thank you for reading! I’m happy to be back with this new edition of my Web Development Update in 2019 and grateful for all your ongoing support. It makes me happy to hear that so many people find this resource helpful. So if you enjoyed it, please feel free to share it with people you know, give me feedback, or support it with a small amount of money. —Anselm

(cm)
Categories: Around The Web

Grabbing Visual Attention With The Visual Cortex

Smashing Magazine - Thu, 01/17/2019 - 7:15am
Grabbing Visual Attention With The Visual Cortex Grabbing Visual Attention With The Visual Cortex Susan Weinschenk 2019-01-17T13:15:03+01:00 2019-01-18T21:18:05+00:00

(This is a sponsored post.) You are designing a landing page. The goal of the page is to get people to notice, and hopefully click on a button on the screen to subscribe to a monthly newsletter. “Make sure the button captures people’s attention” is the goal you’ve been given.

So how, exactly, do you do that?

Research on the visual cortex in the brain can give you some ideas. The visual cortex is the part of the brain that processes visual information. Each of the senses has an area of the brain where the signals for that sensory perception are usually sent and processed. The visual cortex is the largest of the sensory cortices because we are very visual animals.

Recommended reading: What Is The Role Of Creativity In UX Design?

The Pre-Attention Areas Of The Visual Cortex

There are special areas of the visual cortex that process visual information very quickly. These are called the “pre-attention” areas because they process information faster than someone may realize they’ve even noticed something visually.

Within the visual cortex are four areas called V1, V2, V3 and V4. These are the “pre-attention” areas of the visual cortex, and they are dedicated to very small and specific visual elements.

Let’s take a look at each one:

Orientation

If one item is oriented differently than others, then it is noticed right away:

(Large preview) Size And Shape

If one item is either a different size or shape than others then it is noticed right away:

(Large preview) Color

If one item is a different color than others around it then it is noticed right away:

(Large preview) Movement

If one item moves in quickly, especially if it zooms in from starting at a small size and then becoming larger quickly (think tiger running quickly towards you), that grabs attention.

But Only One At A Time

The interesting, not immediately obvious factor here is that if you use these factors together at the same time then nothing really attracts attention.

(Large preview)

If you want to capture attention then, pick one of the methods and use it only.

Take a look at the two designs presented below. Which one draws your attention to the idea that you should enroll?

(Large preview) (Large preview)

Obviously, the image that has just one color area draws your attention more, rather than the one area that is color.

The Fusiform Facial Area

The pre-attention areas of the visual cortex are not the only visual/brain connection to use. Another area of the brain you can tap to grab attention on a page could be the Fusiform Facial Area (or FFA).

The FFA is a special part of the brain that is sensitive to human faces. The FFA is located in the mid/social part of the brain near the amygdala which processes emotions. Faces grab attention because of the FFA.

(Large preview)

The FFA identifies:

  • Is this a face?
  • Someone I know?
  • Someone I know personally?
  • What are they feeling?

What stimulates the FFA?

  • Faces that look straight out stimulate the FFA.
  • Faces that are in profile may eventually stimulate the FFA, but not as quickly. In the example below the face is in profile and obscured by hair. It may not stimulate the FFA at all.
  • (Large preview)
  • Even inanimate objects like the picture of the car below may stimulate the FFA area if they have things that look like facial parts such as eyes and a mouth.
(Large preview) Looking Where The Face Looks?

You may have seen the heat maps that show that if you show a face and the face is looking at an object (for example, a button or a product) on the screen then the person looking at the page will also look at the same object. Here’s an example:

(Large preview)

The red areas show where people looked most. When the model looks at the shampoo bottle then people tend to look there too.

But be careful about drawing too many conclusions from this. Although the research shows that people’s eye gaze will follow the eye gaze of the photo, that doesn’t necessarily mean that people will take action. Highly emotional facial expressions lead to more action taking than just eye gaze.

Recommended reading: The Importance Of Macro And Micro-Moment Design

Takeaways

If you want to grab someone’s visual attention:

  • Use the pre-attention areas of the visual cortex: make everything on the page plain except for one element.

or

  • Show a large face, facing forward;
  • If you want to spur action have the face show a strong emotion;
  • Resist the urge to use many methods at once, such as a face, and color, and size, and shape, and orientation.

This article is part of the UX design series sponsored by Adobe. Adobe XD tool is made for a fast and fluid UX design process, as it lets you go from idea to prototype faster. Design, prototype and share — all in one app. You can check out more inspiring projects created with Adobe XD on Behance, and also sign up for the Adobe experience design newsletter to stay updated and informed on the latest trends and insights for UX/UI design.

(cm, ms, yk, il)
Categories: Around The Web

HTML5 Input Types: Where Are They Now?

Smashing Magazine - Wed, 01/16/2019 - 8:30am
HTML5 Input Types: Where Are They Now? HTML5 Input Types: Where Are They Now? Drew McLellan 2019-01-16T14:30:11+01:00 2019-01-18T21:18:05+00:00

One of the stand-out headline features of HTML5 for many designers and developers was the addition of a number of new types of form input that could be used. For years, we’d been confined to using single-line text inputs (type="text") and laying on JavaScript and user instructions to try an accurately capture valid data of different types through that one unsophisticated field.

HTML5 brought with it new values of the type attribute that enabled us to be much more specific about the types of data we needed to capture through the field, with the promise being that the browser would then provide the interface and validation required to coerce the user into completing the field accurately.

From URLs to emails, and from search fields to dates, the hope was that instead of needing to write cumbersome JavaScript to try and validate those fields, we could just leave it to the browser to do that hard work for us. What’s more, by adding what it knows about the user’s context (type of device, type of interaction, timezones, and so on) the browser would be able to do a much better job of tailoring the interface to meet the user’s needs that we ever could as page authors.

Recommended reading: UX And HTML5: Let’s Help Users Fill In Your Mobile Form

Having new items in a spec is one thing, but it doesn’t really mean too much unless the browsers our audience are using support those features. These new values of the type attribute had the big advantage of falling back to type="text" if the browser had no support, but this may have also come at the cost of removing the browsers makers’ imperative when it came to implementing those new types in their products.

It’s the start of 2019, and HTML5 has been the current version of HTML now for more than four years. Which of those new types have been implemented, which can we use, and are there any we should be avoiding?

  1. Search Fields
  2. Telephone Number Fields
  3. URL Fields
  4. Email Fields
  5. Number Fields
  6. Range Fields
  7. Color Fields
  8. Date Fields

Web forms are such an important part of the web, but we design them poorly all the time. The brand-new “Form Design Patterns” book is our new practical guide for people who design, prototype and build all sorts of forms for digital services, products and websites. The eBook is free for Smashing Members.

Check the table of contents ↬ 1. Search Fields

The type="search" input is intended to be used for search fields. Functionally, these are very the same as basic text fields, but having a dedicated type enables the browser to apply different styling. This is particularly useful if the user’s operating system has a set style for search fields, as this enables the browser to style the search fields on web pages to match.

The specification states that the difference between search and text is purely stylistic, so it may be best to avoid this if you intend to restyle the field with CSS anyway. There appears to be no semantic advantage to its use.

Can I Use input-search? Data on support for the input-search feature across the major browsers from caniuse.com.

Recommendation

Use type="search" if you intend to leave the styling of the search field up to the browser.

2. Telephone Number Fields

The type="tel" input is used for entering telephone numbers. These are like the unique usernames used by Whatsapp. If you’re unsure, ask your grandparents.

Internationally, telephone numbers take on lots of different formats, for both technical and localization reasons. Due to this, the tel input doesn’t attempt to validate the format of a phone number. You can make use of the associated validation tools such as the pattern attribute on the tag, or the setCustomValidity() JavaScript method to enforce a format if required.

On desktop browsers, the use of telephone fields seems to have little impact. On devices with virtual keyboards, however, they can be really useful. For example, on iOS, focusing input on a telephone field brings up a numeric keypad ready for keying in a number. In addition, the device’s autocomplete mechanisms kick in and suggest phone numbers that can be autofilled with a single tap.

Can I Use input-email-tel-url? Data on support for the input-email-tel-url feature across the major browsers from caniuse.com.

Recommendation

Use type="tel" for any phone number fields. It’s very useful where implemented, and comes at no cost when it’s not.

3. URL Fields

The type="url" field can be used for capturing URLs. You might use this when asking a user to input their website address for a business directory, for example. The curious thing about the URL field is that it takes only full, absolute URLs. There’s no option to be able to capture just a domain name, or just a path, for example. This does restrict its usefulness in some respects, as I imagine CMS and web app developers would have found lots of uses for a field that accepts and validates relative paths.

While this would be a valid absolute URL:

https://twitter.com/drewm

Both of these would not pass the field’s validation:

smashingmagazine.com /2019/01/css-multiple-column-layout-multicol/

It feels like a missed opportunity that different parts of a URL cannot be specified, but that’s what we have. Browser support is across the board pretty great, with virtual keyboard devices offering some customization for URL entry. iOS customizes its keyboard with ., / and an autocomplete button for common TLDs such as .com and for my locale, .co.uk. This is a good example of the browser being able to offer more intelligent choices than we can as web developers.

Can I Use input-email-tel-url? Data on support for the input-email-tel-url feature across the major browsers from caniuse.com.

Recommendation

Use type="url" whenever you need to collect a full, absolute URL. Browser support is great, but remember that it’s no good for individual URL components.

4. Email Fields

Possibly one of the most commonly used of the newer options is type="email" for email addresses. Much like we’ve seen with telephone numbers and URLs, devices with virtual keyboards customize the keys (to include things like @ buttons) and enable autofill from their contacts database.

Desktop browsers make use of this too, with Safari on macOS also enabling autofill for email fields, based on data in the system Contacts app.

Email addresses often seem like they follow a very simple format, but the variations actually make them quite complex. A naive attempt to validate email addresses can result in a perfectly good address being marked as invalid, so it’s great to be able to lean on the browser’s more sophisticated and well-tested validation methods to check the format.

Usefully, the multiple attribute can be added to email fields to collect a list of email addresses. In this case, each email address in the list is individually validated.

<input type="email" multiple>

Can I Use input-email-tel-url? Data on support for the input-email-tel-url feature across the major browsers from caniuse.com.

Recommendation

Use type="email" for email address fields whenever possible.

Safari on iOS shows custom keyboards for telephone, email and number fields, amongst others. (Large preview) 5. Number Fields

The type="number" field is designed for numerical values, and has some very useful attributes along with it in the shape of min, max and step. A valid value for a number field must be a floating point number between any minimum and maximum value specified by the min and max attributes.

If step is set, then a valid value is divisible by the step value.

<input type="number" min="10" max="30" step="5">

Valid input for the above field would be 10, 15, 20, 25 and 30, with any other value being rejected.

Browser support is broad, again with virtual keyboards often defaulting to a numeric input mode for keying in values.

Some desktop browsers (including Chrome, Firefox and Safari, but not Edge) add toggle buttons for nudging the values up and down by the value of step, or if no step is specified, the default step appears to be 1 in each implementation.

Can I Use input-number? Data on support for the input-number feature across the major browsers from caniuse.com.

Recommendation

Use type="number" for any floating point numbers, as it’s widely supported and can help prevent accidental input.

6. Range Fields

Less obvious in use that some of the other types, type="range" can be thought of as being an alternative for type="number" where the user doesn’t care about the exact value.

Range fields take, and will often use, the same min, max and step attributes as number fields, and browsers almost universally display this as a graphical slider. The user doesn’t necessarily get to see the exact value they’re setting.

Range fields might be useful for those sorts of questions on forms like “How likely are you to recommend this to a friend?” with “Likely” at one end and “Unlikely” at the other. The user could slide the slider to wherever they think represents their opinion, and under the hood that gets submitted as a numerical value that you can store and process.

Browser support is good, although the appearance varies between implementations.

Can I Use input-range? Data on support for the input-range feature across the major browsers from caniuse.com.

Recommendation

The uses for type="range" might be a bit niche, but support is good and the slider provides a user-friendly input method where appropriate.

7. Color Fields

The type="color" field is design for capturing RGB colors in hexadecimal notation, such as #aabbcc. The HTML specification calls this a “color well control”, with the intention that the browser should provide a user-friendly color picker of some sort.

Some browsers do provide this, notably Chrome and Firefox both providing access to the system color picker through a small color swatch.

Neither IE nor Safari provide any support here, leaving the user to figure out that they’re supposed to enter a 7-digit hex number all by themselves.

Color fields might find use in theming for personalization and in CMS use, but unless the users are sufficiently technical to deal with hex color codes, it may be better not to rely on the browser providing a nice UI for these.

Can I Use input-color? Data on support for the input-color feature across the major browsers from caniuse.com.

Recommendation

Unless you know your users will be happy to fall back to entering hexadecimal color codes, it’s best not to rely on browsers supporting type="color".

Range, color and date fields as displayed by Edge, Firefox and Chrome. (Large preview) 8. Date Fields

HTML5 introduced a number of different type values for creating inputs for dates and times. These included date, time, datetime-local, month and week.

At first glance, these appear to be heaven-sent, as collecting dates in a form is a difficult experience for both developer and user, and they’re needed pretty frequently.

The promise here is that the new field types enable the browser to provide a standardized, accessible and consistent user interface to capture dates and times from the user with ease. This is really important, as date and time formats vary world-over based on both language and locale, and so a friendly browser interface that translates an easy-to-use date selection into an unambiguous technical date format really does sound like the ideal solution.

As such, valid input for type="date" field is an unambiguous year-month-day value such as 2019-01-16. Developers like these, as they map pretty much to the ISO 8601 date format, which is used in most technical contexts. Unfortunately, few regular human beings use this date format and aren’t likely to reach for it when asked to provide a date in a single empty text field.

And, of course, a single empty text field is what the user is presented with if their browser does not provide a user interface for picking dates. In those cases, it then becomes very difficult for a user to enter a valid date value unless they happen to be familiar with the format required or the input is annotated with clear instructions.

Many browsers do provide a good user interface for picking dates, however. Firefox has a really excellent date picker, and Chrome and Edge also have pretty good interfaces. However, there’s no support in poor old IE and none in Safari, which could be an issue.

Can I Use input-datetime? Data on support for the input-datetime feature across the major browsers from caniuse.com.

Recommendation

While convenient where it works, the failure mode of type="date" and its associated date and time types is very poor. This makes it a risky choice that could leave users struggling to meet validation criteria.

Conclusion

A lot has changed in the browser landscape in the four years since the HTML5 specification became a recommendation. Support for the newer types of input is fairly strong — particularly in mobile devices with virtual keyboards such as tablets and phones. In most cases, these inputs are safe to use and provide some extra utility to the user.

There are a couple of notable exceptions, the worst of which being the date and time fields, which not only lack utility, but also have more patchy browsers support. When support isn’t available, the fallback mode of these fields is poor. In these cases, it might be best to stick to JavaScript-based solutions for progressively enhancing the basic type="text" input fields.

If you’d like to read more, I’d thoroughly recommend the MDN web docs on these field types, and as ever, the W3C specification.

(ra, il)
Categories: Around The Web

How Improving Website Performance Can Help Save The Planet

Smashing Magazine - Tue, 01/15/2019 - 7:30am
How Improving Website Performance Can Help Save The Planet How Improving Website Performance Can Help Save The Planet Jack Lenox 2019-01-15T13:30:32+01:00 2019-01-18T21:18:05+00:00

You may not think about it often, but the Internet uses a colossal amount of electricity. This electricity needs to be produced somewhere. In most countries, this means the burning of fossil fuels. This, in turn, means that the Internet’s carbon footprint has grown to the point where it may have eclipsed global air travel, and this makes the Internet the largest coal-fired machine on Earth.

The Mozilla Internet Health Report 2018 states that — especially as the Internet expands into new territory — “sustainability should be a bigger priority.” But as it stands, websites are growing ever more obese, which means that the energy demand of the Internet is continuing to grow exponentially.

All the while, the impacts of climate change grow worse and more numerous with each passing year. The vast majority of climate scientists attribute the increasing ferocity and frequency of extreme weather events around the world to climate change, which they largely attribute to human activity. While some question the science, even the world’s largest oil companies now accept it, and concede that their business models need to change.

Every country on Earth (with the exception of the US), is signed up to the Paris Climate Agreement. Although the US controversially pulled out, many of America’s most influential individuals, cities, states, and companies — representing more than half the US population and economy — have retained their commitment to the agreement by way of the America’s Pledge initiative.

Front-end is messy and complicated these days. That's why we publish articles, printed books and webinars with useful techniques to improve your work. Even better: Smashing Membership with a growing selection of front-end & UX goodies. So you get your work done, better and faster.

Explore Smashing Membership ↬

As web developers, it’s understandable to feel that this is not an issue over which we have any influence, but this isn’t true. Many efforts are afoot to improve the situation on the web. The Green Web Foundation maintains an ever-growing database of web hosts who are either wholly powered by renewable energy or are at least committed to being carbon neutral. In 2013, A List Apart published Sustainable Web Design by James Christie. For the last three years, the SustainableUX conference has seen experts in web sustainability sharing their knowledge across an array of web-based disciplines.

Since 2009, Greenpeace has been putting pressure on big Internet companies to clean up their energy mix by way of their Clicking Clean campaign. Partly as a result of this campaign, Google announced last year that for the first time it had purchased enough renewable energy to match 100% of its global consumption for operations.

So, apart from powering servers with renewable energy, what else can web developers do about climate change?

“You Can’t Manage What You Can’t Measure”

Perhaps the biggest win when it comes to making websites more sustainable is that performance, user experience and sustainability are all neatly intertwined. The key metric for measuring the sustainability of a digital product is its energy usage. This includes the work done by the server, the client and the intermediary communications networks that transmit data between the two.

With that in mind, perhaps the first thing to consider is how do we measure the energy usage of our website? This is actually a trickier undertaking than you might imagine, and it’s difficult to get precise data here. There are, however, some good fallbacks which we can use that demonstrate energy usage. These include data transfer (i.e. how much data does the browser have to download to display your website) and resource usage of the hardware serving and receiving the website. An obvious metric here is CPU usage, but memory usage and other forms of data storage also play their part.

Data transfer is one thing that we can measure quite easily. All of the major browsers provide developer tools that allow us to measure network activity. In this screenshot below, for example, we can see that loading the Smashing Magazine website for the first time incurs just under a megabyte of data transfer. Firefox’s developer tools actually provide us with two numbers: the first is the uncompressed size of the files that have been transferred, and the latter is the compressed size.

(Large preview)

The most common tool for compressing assets as they travel across the network is gzip, so the difference between those two numbers is typically a result of gzip’s work. This latter number represents how much data has actually been transmitted and is the one to keep an eye on.

Note: There are plenty of other tools that provide us with a metric for data transfer including the much revered WebPagetest.

For measuring CPU usage, Chrome provides us with a granular Task Manager that shows the memory footprint, CPU usage and network activity of individual tabs. For the more adventurous/technical, the top (table of processes) command provides similar metrics on most Unix-like operating systems such as macOS and Ubuntu. Generally speaking, we can also run the top command on any server to which we have shell access.

Fortunately, there are efforts such as WebsiteCarbon and Ecograder that seek to translate these metrics into a specific CO2 figure (in the case of WebsiteCarbon) or a score (in the case of Ecograder).

Sustainable Web Design

Now we know how to measure the impact of our site, it’s time to think about how we can optimize things to make it more sustainable, more performant, and generally a better experience to use.

There are some existing works we can draw on to help us here. In 2016, O’Reilly published “Designing For Sustainability” by Tim Frick. In this book, Tim takes us on a tour of the whys and hows of sustainable design. But we can also draw on a wealth of existing ideas, conference talks and articles which — while not having an explicit focus on sustainability — have a huge overlap with the philosophy of sustainable web design. Particularly good examples here are Brad Frost’s side-project, “Death To Bullshit”, Heydon Pickering’s articles and talks about writing less damn code, and Adam Silver’s blog post, “Designing For Actual Performance.”

If we’re doing a complete redesign of a website, or starting a new one from scratch, we can start with some really high-level questions here. For example, what actually deserves or needs to be on a homepage? And more specifically, what value does each element on a homepage bring? As Heydon Pickering puts it:

“The most performant, accessible and easily maintainable feature of a website is the one that you don’t make in the first place.”

I work on the WordPress.com VIP team, so in this vein, I decided to challenge myself by putting together a minimalist WordPress theme to see how far I could take the techniques of sustainable web design. The result is a theme called Susty, and it can be seen in action on the accompanying website I put together: sustywp.com. In that particular example, the website is delivered in just over 6KB of data transfer, which feels good given that the median website is about 1.5MB.

So, what did I do? Well, I’ll tell you.

Reduce Network Requests

As I have outlined above, network requests are something we can easily measure, so they make for a good starting point. In putting Susty together, I noticed there were a number of HTTP requests going on that didn’t appear to be necessary. For example, WordPress bundles some CSS and JavaScript that detects the usage of emojis and makes sure they don’t appear as illegal characters. There’s nothing inherently wrong with this, but if you aren’t planning to use emojis, or you’re happy and confident that the various system defaults will have you covered, you can prevent these from loading.

This represents a relatively meager saving, but by establishing a philosophy of pruning unwanted code and requests from our pages, we can make much more significant performance improvements. For example:

  • Are we loading the whole of jQuery for some basic DOM operations?
    Could we achieve the same ends with pure JavaScript? You can read about more advanced dead code elimination (aka tree shaking) in this post for Google by Jeremy Wagner.
  • Do we have a carousel of images?
    Do we really need all those images? Are they significantly enhancing the user experience? Or could we reduce it to just one, strong image? Or even randomly show one of a selection of images, to give a sense of dynamism to returning users? By the way, the research that has been done here shows that most users neither like nor engage with carousels.
  • If we are using a lot of images, would we benefit from providing our images using the WebP format for those browsers that support it?
    For the longest time, WebP’s support has been frustratingly limited. But with Firefox due to begin support for it in version 65 (due in January 2019), it’s only a matter of time before remaining stragglers like Safari catch up.
  • Are we loading hundreds of kilobytes of web fonts?
    Are we using all of the web fonts that we’re loading? Do we even need web fonts? Most devices these days have a stack of half-decent fonts, could we just specify a list of fonts we’d like to see arranged by preference? If we must use web fonts, we should make sure our fonts are as performant as is reasonably possible.
  • Are we embedding YouTube videos?
    An embedded YouTube video typically adds about a megabyte of data transfer before anyone even interacts with it. If only a fraction of our users are actually going to sit and watch the embedded video on our website, could we just link to it instead?
Scrutinise Everything

In this vein, we can also interrogate every aspect of our pages. What really deserves to be there? Does our sidebar add any real value, or have we just put one there because convention dictates that websites have sidebars? So, we’ve added one and filled it with crap.

With Susty, I’ve experimented with the somewhat unorthodox approach of relegating the navigation to its own page. This allows me to have pages that are stripped down to literally the bare essentials, with additional content only being loaded at the user’s explicit request. Susty is so lightweight and so fast that I realized through some user research (aka my partner) that the loading of the menu didn’t really feel like a new page, so I decided to make it look like an overlay, with a cross to dismiss that actually just takes you back to the previous page.

As well as helping me to create pleasingly lightweight pages, the relegated navigation also removes the need for any fancy hide/reveal code for showing it. At this point, I’d like to make it clear that Susty is an example of taking sustainable web design techniques to an extreme (I’m not suggesting it’s an archetype of a good website).

Write CSS Like Your Grandmother

When it comes to serious performance enhancement, we should bear in mind that literally every character of code counts. Every character represents a byte, and even after they’ve been compressed by gzip, they’re still taking up weight. CSS is a domain where we often see a lot of bloat. Fortunately, there are a growing number of increasingly complex tools that can help you weed out unused CSS. This fantastic post by Sarah Dayan outlines how she reduced her CSS bundle from 259KB to 9KB!

If we’re starting from scratch, perhaps we should think more deeply about how we write CSS in the first place. Heydon Pickering wrote an excellent post about how we can write CSS in a way that plays to the strengths of how the syntax was designed, and how this can help developers prevent repetition. Heydon also points out how much wastage goes on with excessive usage of divs and classes — both in HTML and CSS.

What Are You Analyzing?

It seems to have become more-or-less ubiquitous on the web for everyone to analyze what their website’s visitors do via tools like Google Analytics, KISSmetrics, Piwik, etc. While I have no doubt that there are legitimate use cases, do we really need analytics on every website? I, for one, have typically added Google Analytics to every site I manage as a matter of course. But it dawned on me relatively recently that for most of the websites in question, this has been an almost completely pointless endeavor: “Oh, six people came to this post via Facebook today.” Who cares?

Unless you really need it, and you’re going to analyze and act upon the data, just ditch analytics and find a better way to spend your time than gawping at the mundanity of how many people visited website X today.

As well as adding to your page weight, usage of something like Google Analytics raises ethical questions around the data you’re collecting on your users on Google’s behalf, i.e. there’s a reason Google provides you with Analytics for free.

Let’s Not Forget The Basics

There’s so much information around these days about the following, but we should never get complacent and forget about them. Alongside everything above, we absolutely should always minify HTML, CSS, and JavaScript, and concatenate where appropriate. We should also compress all images to ensure they are as small as possible, use the right formats in the right settings, and use progressive rendering.

Server-Side Performance

So far, our focus has been almost entirely on the front-end, but a lot of this is made irrelevant if we don’t also optimize things on the server-side. I’ve already mentioned it a couple of times, but we should absolutely enable gzip compression at all times.

We should make serving our website as easy for our server as possible. I predominantly use Nginx, and I have a particular fondness for FastCGI cache and have found it to be especially efficient. If you have shell access to your own server, here’s a post that explains how to configure it. There are less technical options if you don’t have (or don’t want) as much control over your server. A particular favorite in the WordPress space is WP Super Cache.

We should use HTTP2 over HTTPS. Using HTTPS opens up a world of new web technologies like service workers that allow us to treat the network itself as a nice-to-have. If you want to learn more about this, I highly recommend Jeremy Keith’s new book, “Going Offline.”

Note: You also may want to investigate Google’s PageSpeed Module, available for both Apache and Nginx.

Finally, the biggest impact we can have here is to host our websites in data centers powered by renewable energy. In the UK, I can highly recommend Krystal and Kualo in terms of companies with which I directly host my sites. (For a full directory of green web hosts, check out The Green Web Foundation.)

In Conclusion

I hope I have convinced you that it’s worth putting in the effort to make our websites more sustainable. Especially given that in the process we also make our websites:

  • More performant,
  • More user-friendly,
  • More accessible,
  • More server-friendly,
  • Better optimized for search engines.

A response that some people have to the idea of sustainable web design — which is not unreasonable — is that it seems to be a very small concession to the environmental cause. Of course, how much of an impact you can have depends on how busy the websites are that you work on. But as well as helping the web become a bit more environmentally friendly, sustainable web design is fundamentally best practice web design.

It’s also worth thinking about offsetting the carbon emissions that you can’t avoid. Carbon offsetting is sometimes derided, and with good cause. The main problem with offsetting is that typically the term over which carbon will be offset is quite long. For example, with tree planting, the figure given for an amount of carbon sequestering is typically based over a 100-year period. So, in terms of reducing carbon emissions now, it’s not really a solution. But it is better than nothing.

The motto of myclimate is to do your best, and offset the rest. I have written a blog post about rolling your own carbon offset scheme. I also highly recommend the 1% For The Planet initiative. Finally, if you are a business owner and would like to join an alliance of companies that want to see better social, environmental and economic justice, check out the Certified B Corporation scheme.

(ra, il)
Categories: Around The Web

Web Standards: The What, The Why, And The How

Smashing Magazine - Mon, 01/14/2019 - 8:00am
Web Standards: The What, The Why, And The How Web Standards: The What, The Why, And The How Amy Dickens 2019-01-14T14:00:17+01:00 2019-01-18T21:18:05+00:00

The World Wide Web is an interesting place.

As the Internet has grown and become more common place, it has become a gigantic instrument of change in terms of the way in which we interact with the world and each other.

Like many people, my intro to web development at school was kind of bleak. Our school ICT (Information Computing Technology) lessons taught us very little, using Dreamweaver (back when it was a Macromedia product) as a platform to visually edit a personal website with the biggest lesson being “what is a hyperlink”. We didn’t even view the HTML source of our own websites!

So my education around HTML and CSS came largely from messing around with the “view source” option in websites. I learned through copy-pasting bits and pieces together to create my own websites and downloading templates for bootstrap, before I knew what bootstrap actually was.

Why Am I Telling You This?

Having recently surveyed my Twitter followers (it’s an exact science

Categories: Around The Web

When And How To Use CSS Multi-Column Layout

Smashing Magazine - Fri, 01/11/2019 - 8:00am
When And How To Use CSS Multi-Column Layout When And How To Use CSS Multi-Column Layout Rachel Andrew 2019-01-11T15:00:30+02:00 2019-01-18T21:18:05+00:00

In all of the excitement about CSS Grid Layout and Flexbox, another layout method is often overlooked. In this article I’m going to take a look at Multi-column Layout — often referred to as multicol or sometimes “CSS Columns”. You’ll find out which tasks it is suited for, and some of the things to watch out for when making columns.

What Is Multicol?

The basic idea of multicol, is that you can take a chunk of content and flow it into multiple columns, as in a newspaper. You do this by using one of two properties. The column-count property specifies the number of columns that you would like the content to break into. The column-width property specifies the ideal width, leaving the browser to figure out how many columns will fit.

It doesn’t matter which elements are inside the content that you turn into a multicol container, everything remains in normal flow, but broken into columns. This makes multicol unlike other layout methods that we have in browsers today. Flexbox and Grid for example, take the child elements of the container and those items then participate in a flex or grid layout. With multicol, you still have normal flow, except inside a column.

In the below example I am using column-width, to display columns of at least 14em. Multicol assigns as many 14em columns as will fit and then shares out the remaining space between the columns. Columns will be at least 14em, unless we can only display one column in which case it may be smaller. Multicol was the first time that we saw this kind of behavior in CSS, columns being created which were essentialy responsive by default. You do not need to add Media Queries and change the number of columns for various breakpoints, instead we specify an optimal width and the browser will work it out.

See the Pen Smashing Multicol: column-width by Rachel Andrew (@rachelandrew) on CodePen.

Front-end is messy and complicated these days. That's why we publish articles, printed books and webinars with useful techniques to improve your work. Even better: Smashing Membership with a growing selection of front-end & UX goodies. So you get your work done, better and faster.

Explore Smashing Membership ↬ Styling Columns

The column boxes created when you use one of the column properties can’t be targeted. You can’t address them with JavaScript, nor can you style an individual box to give it a background color or adjust the padding and margins. All of the column boxes will be the same size. The only thing you can do is add a rule between columns, using the column-rule property, which acts like border. You can also control the gap between columns using the column-gap property, which has a default value of 1em however you can change it to any valid length unit.

See the Pen Smashing Multicol: column styling by Rachel Andrew (@rachelandrew) on CodePen.

That is the basic functionality of multicol. You can take a chunk of content and split it into columns. Content will fill the columns in turn, creating columns in the inline direction. You can control the gaps between columns and add a rule, with the same possible values as border. So far so good, and all of the above is very well supported in browsers and has been for a long time, making this spec very safe to use in terms of backwards compatibility.

There are some further things you might want to consider with your columns, and some potential issues to be aware of when using columns on the web.

Spanning Columns

Sometimes you might like to break some content into columns, but then cause one element to span across the column boxes. Applying the column-span property to a descendent of the multicol container achieves this.

In the example below, I have caused a <blockquote> element to span across my columns. Note that when you do this, the content breaks into a set of boxes above the span, then starts a new set of column boxes below. The content doesn’t jump across the spanned element.

The column-span property is currently being implemented in Firefox and is behind a feature flag.

See the Pen Smashing Multicol: column-span by Rachel Andrew (@rachelandrew) on CodePen.

Be aware that in the current spec, the values for column-span are either all or none. You can’t span just some of the columns, but you can get the kind of layout you might see in a newspaper by combining multicol with other layout methods. In this next example, I have a grid container with two column tracks. The left-hand track is 2fr, the right-hand track 1fr. The article in the left-hand track I have turned into a multicol container with two tracks, it also has a spanning element.

On the right, we have an aside which goes into the second Grid column track. By playing around with the various layout methods available to us, we can figure out exactly which layout method suits the job at hand — don’t be afraid to mix and match!

See the Pen Smashing Multicol: mixing layout methods by Rachel Andrew (@rachelandrew) on CodePen.

Controlling Content Breaks

If you have content containing headings, then you probably want to avoid the situation where a heading ends up as the last thing in a column with the content going into the next column. If you have images with captions then the ideal situation would be for the image and caption to stay as one unit, not becoming split across columns. To deal with these problems CSS has properties to control where the content breaks.

When you split your content into columns, you perform what is known as fragmentation. The same is true if you split your content between pages, such as when you create a stylesheet for a print context. Therefore, multicol is closest to Paged Media than it is to other layout methods on the web. Because of this, for several years the way to control breaks in the content has been to use the page-break- properties which were part of CSS2.1.

  • page-break-before
  • page-break-after
  • page-break-inside

More recently the CSS Fragmentation specification has defined properties for fragmentation which are designed for any fragmented context, the spec includes details for Paged Media, multicol and the stalled Regions spec; Regions also fragments a continuous piece of content. By making these properties generic they can apply to any future fragmented context to, in the same way that the alignment properties from Flexbox were moved into the Box Alignment spec in order that they could be used in Grid and Block layout.

  • break-before
  • break-after
  • break-inside

As an example, I have used break-inside avoid on the <figure> element, to prevent the caption being detached from the image. A supporting browser should keep the figure together even if that causes the columns to look unbalanced.

See the Pen Smashing Multicol: break-inside by Rachel Andrew (@rachelandrew) on CodePen.

Unfortunately, support for these properties in multicol is pretty patchy. Even where supported they should be seen as a suggestion due to the fact that it would be possible to make so many requests while trying to control breaking, that essentially the browser can’t really break anywhere. The spec does define priorities in this case, however it is probably more useful for you to control only the most important cases.

The Problem Of Columns On the Web

One reason why we don’t see multicol used much on the web is the fact that it would be very easy to end up with a reading experience which made the reader scroll in the block dimension. That would mean scrolling up and down vertically for those of us using English or another vertical writing mode. This is not a good reading experience!

If you fix the height of the container, for example by using the viewport unit vh, and there is too much content, then overflow will happen in the inline direction and so you get a horizontal scrollbar instead.

See the Pen Smashing Multicol: overflow columns by Rachel Andrew (@rachelandrew) on CodePen.

Neither of these things are ideal, and making use of multicol on the web is something we need to think about very carefully in terms of the amount of content we might be aiming to flow into our columns.

Block Overflow Columns

For Level 2 of the specification, we are considering how to enable a method by which overflow columns, those which currently end up causing the horizontal scrollbar, could instead be created in the block direction. This would mean that you could have a multicol container with a height, and once the content had made columns which filled that container, a new set of columns would be created below. This would look a little like our spanning example above, however, instead of having a spanner causing the new column boxes to start, it would be the overflow caused by a container with a restriction in the block dimension.

This feature would make multicol far more useful for the web. While we are a little way off right now, you can keep an eye on the issue in the CSS Working Group repo. If you have additional use cases for this feature do post them, it can really help when designing the new feature.

What Is Multicol Useful For Today?

With the current specification, splitting all of your content into columns without consideration for the problems of scrolling isn’t advised. However, there are some cases where multicol is ideal on the web. There are enough uses cases to make it something you should consider when looking at design patterns.

Collapsing Small UI Or Text Elements

Multicol can be useful in any place where you have a small list of items that you want to take up less space. For example a simple listing of checkboxes, or a list of names. Often in these scenarios, the visitor is not reading down one column and then going back to the top of the next, but scanning the content for a checkbox to click or an item to select. Even if you do create a scrolled experience, it may not be an issue.

You can see an example of multicol used in this way by Sander de Jong on the DonarMuseum website.

On DonarMuseum, we can see multicol used to display lists of names. (Image source) (Large preview) Known Small Amounts Of Content

There are times when we design a site where we know that some piece of content is relatively small, and will fit on the majority of screens without causing unwanted scrolling. I’ve used multicol on Notist presentation pages, for the introduction to a talk.

Andy Clarke designed a lovely example for the Equfund website.

On the Equfund website, you can see how different HTML elements remain in normal flow while displayed inside columns. (Image source) (Large preview)

To avoid the possibility of very small screens causing scrolling, remember that you can use media queries to check for height as well as width (or in a logical world, block as well as inline). If you only enable columns at a breakpoint which has a min-height large enough for their content, this can save users of very small devices having a poor scrolling experience.

Masonry-Like Display Of Content

Another place where Multiple-column Layout works beautifully is if you want to create a Masonry type of display of content. Multicol is the only layout method that will currently create this kind of layout with unequal height items. Grid would either leave a gap, or stretch the items to make a strict two-dimensional grid.

Veerle Pieters has a beautiful example of using multicol in this way on her inspiration page.

In this design by Veerle Pieters, multicol is used to layout multiple boxes or cards as columns. (Large preview) Grid And Flexbox Fallbacks

The column- properties can also be used as a fallback for Grid and Flex layout. If you specify one of the properties on a container, then turn that container into a Flex or Grid layout by using display: flex or display: grid any column behavior will be removed. If you have, for example, a cards layout that uses Grid Layout, and the layout would be readable if it ran in columns rather than across the page, you could use multicol as a simple fallback. Browsers that do not support Grid will get the multicol display, those which support Grid will get the Grid Layout.

Don’t Forget Multicol!

Fairly frequently I answer Grid and Flexbox questions where the answer is to not use Grid or Flexbox, but instead to look at Multicol. You probably won’t use it on every site, but when you come across a use case it can be really helpful. Over at MDN there are useful resources for multicol and the related fragmentation properties.

If you have used multicol on a project, perhaps drop a note in the comments, to share other ways in which we can use the feature.

(il)
Categories: Around The Web

Designing A Font Based On Old Handwriting

Smashing Magazine - Thu, 01/10/2019 - 7:00am
Designing A Font Based On Old Handwriting Designing A Font Based On Old Handwriting Carolyn Porter 2019-01-10T13:00:02+01:00 2019-01-18T21:18:05+00:00

Designers create handwriting-based connected cursive fonts for a variety of reasons: to immortalize the loops and swirls of a loved one’s handwriting, to digitize the penmanship of a person or document of historic significance, or to transform charming handwriting into a creative asset that can be licensed.

Let’s say you found a beautiful old handwriting specimen you want to digitize. You might presume you can trace individual letters, then seamlessly convert those tracings into a font. I will confess that was my assumption before I began to work on my first font. I had not taken into account the myriad of thoughtful and intentional decisions required to transform the specimen into an artful and functional font.

Before you begin the process of digitizing your specimen, it would be worthwhile to ask yourself a few questions about your goals and intent. Think of it as writing a creative brief for your project. Begin by assessing the importance of historical accuracy. Then conduct a close examination of the specimen: look at the idiosyncrasies in the handwriting, the variation in shape and position of individual letters, the method for connecting letters, and the texture. Possessing a keen familiarity of your specimen will allow you to make informed decisions about aesthetics as you design your font.

Recommended reading: Hands On The Sigmund Freud Typeface: Making A Font For Your Shrink

Meet Smashing Book 6 — our brand new book focused on real challenges and real front-end solutions in the real world: from design systems and accessible single-page apps to CSS Custom Properties, CSS Grid, Service Workers, performance, AR/VR and responsive art direction. With Marcy Sutton, Yoav Weiss, Lyza D. Gardner, Laura Elizabeth and many others.

Table of Contents → How Important Is Historical Accuracy?

One of the biggest decisions you will need to make is whether you want to capture every nuance of your handwriting specimen, or if you want to design something inspired by that handwriting. It is like watching a movie “based on a true story” versus one “inspired by real events.” In the first scenario, you can expect the movie (or font) maintains a higher degree of factual integrity than the second option, where the director (or designer) may take wide-ranging creative liberties.

If you choose to replicate your specimen with utmost precision, be aware that rigorously honoring accuracy may mean compromising legibility. “Old scripts, in particular, include letterforms that are less legible — even virtually illegible, like the old-style long s — than in modern handwriting,” notes Brian Willson, who has designed more than two dozen fonts based on the handwriting of notable figures such as Abigail Adams, Frederick Douglass, and Sam Houston.

Compare the similarities in these three fonts based on (or inspired by) the handwriting of Abraham Lincoln. Although 1863 Gettysburg (the font shown on the far right) was inspired by documents written by President Lincoln, the designer’s stated goal was not to replicate Lincoln’s exact writing, but to create a font that represented the era. (From left to right: LD Abe Lincoln by Lettering Delights/Illustration Ink, a Lincoln by Steve Woolf, and 1863 Gettysburg designed by GLC.) (Large preview)

You may find you want to make thoughtful revisions to strike a balance between historical accuracy and optimized legibility. As I designed the P22 Marcel Script, which is a connected cursive font based on handwritten WWII love letters, I chose to make small revisions to improve legibility.

The font retains the essential character of the original writing, but it is not a precise replica. Many of the original j’s, for example, did not have a tittle (a dot), and the original lowercase p did not have a closed curve on the bottom of the bowl. It looked like a hybrid between a p and an n. Knowing some people struggle to read cursive writing, I chose to dot the j and revise the shape of the p.

Note the small revisions to improve legibility. (From left to right: The original handwriting specimen, a close-up of the greeting “Mes chères petites”, and a sample of the font P22 Marcel Script.) (Large preview) Does Your Source Document Include Enough Material To Work With?

John Hancock had a fantastic signature, but designing an entire font based on the eight letters in his name — J, o, h, n, H, a, c, and k — would be a challenge. Assess whether your specimen is complete enough to support an entire font. Does it include both upper and lowercase letters? How about numbers?

When designing the font based on the handwriting of Jane Austen, designer Pia Frauss discovered she did not have a handwritten letter X to reference. If, like Frauss, you have a specimen that is mostly complete, you should be able to extrapolate what a specific letter might have looked like. That skill will also be necessary when it comes time to design new glyphs — the term for a specific character in a font file — like the Euro, which has only existed since 1999.

If your specimen only has a limited set of characters, gauge whether you feel comfortable designing the missing letters. If not, consider finding a handwritten specimen that is similar in style, then pulling the missing letters from the supplementary specimen.

What Idiosyncrasies Make The Handwriting Special?

Are crossbars unusually high, low, or angled? Are ascenders or descenders abnormally long or short? Are letters strikingly narrow or wide? Do specific letters extend above or below the baseline? Do letters loop in unusual ways?

If your goal is to create a historically accurate font, you will want to take care to ensure those idiosyncrasies are not lost as you digitize individual glyphs. If you are comfortable taking creative liberties, you might exaggerate those points of differentiation.

In the font Marydale, Brian Willson included quirky glyphs such as the loopy, two-story serif g found in the original handwriting. Brian thought it added friendly charm. But a risk of embracing idiosyncrasies is that some users may not like those letterforms — and indeed some users complained to Brian that the g was too unusual. Nevertheless, Marydale is one of Brian’s best-selling fonts.

To help you decode shapes and understand the mechanics behind some of your specimen’s idiosyncrasies, it may be helpful to identify the type of writing utensil that was used. A ballpoint pen will create uniform-width strokes; a split-nib pen can create graceful thicks and thins; a dip pen may carry evidence of ink being reapplied; a brush can create dramatic variation in thickness. You may also consider how the writing utensil had been held or if the writer had been in a hurry, since hand position and speed can influence the shape and style of the handwriting, too.

Assess Variations In Axis, Letter Height, Alignment To Baseline, And Stroke Width

Within any single handwriting specimen, you will likely see variation in axis, letter height, alignment to baseline, and stroke width. These irregularities enhance the individuality of handwriting — but transferring those irregularities to a digital font can be a challenge. If your font includes too many variations in axis, letter height, alignment to baseline, or stroke width, it may not reflect the visual unity of the original specimen. If your font does not include enough variation, it may lack the charm of the original writing.

Take time to assess which elements in the original specimen are consistent and which vary, then plan how you could incorporate those variations into your font. If you employ a consistent axis, consider varying alignment to baseline or stroke width. If you standardize stroke widths, consider varying axes and letter heights.

Fonts with increasing variability in axes, letter heights, alignment to baseline, and stroke thicknesses. (From left to right: Texas Hero by Brian Willson/Three Islands Press, P22 Cezanne Pro by Michael Want and James Grieshaber, and Selima by Jroh.) (Large preview)

When I began working on the P22 Marcel Script, I sourced favorite individual letters from five separate handwritten pages. The first time I pieced glyphs into words, I could see that the axes, letter heights, and stroke thicknesses were too variable. Even though each glyph had been a careful re-creation of one man’s handwriting, the resulting look was haphazard. I decided on a standard for axis and stroke thickness, then adjusted every glyph to that standard. Varying letter heights and alignment to baseline prevented the font from looking too mechanical.

Where And How Do Individual Letters Connect?

Are the connecting lines that sweep from one letter to the next high or low? Are the connecting lines thick or thin? Are there some letters that do not connect?

The key to designing a successfully connected cursive script font is to create an overlap so individual letters appear to seamlessly flow from one into the next. The trick is to identify one location for that overlap, then to start and end every glyph in that precise position. Some designers place those overlaps along the left-hand edge of a glyph, other designers place the overlap in the space between the glyphs. Some designers place the overlap low, others place the overlap high. There is no right or wrong answer; choose the location and method that makes sense for you.

Fonts that overlap on the left-hand edge of each glyph. The magenta circle shows the overlap; the horizontal magenta line shows the consistent placement of the sweeping connecting line on the letters m and a. (From left to right: Douglass Pen by Brian Willson/Three Islands Press, Rough Love by Positype, and Bambusa Pro by FontForecast.) (Large preview) Fonts that overlap in the space between the glyphs. (From left to right: Dear Sarah Pro by Christian Robertson, Storyteller Script by My Creative Land, and Mila by Facetime.) (Large preview)

You may also discover that not all letters in your specimen connect. In that case, you will still need to identify one location and implement a consistent strategy for the overlaps, though you will only create the overlap on those glyphs that connect.* *

Fonts where some, but not all, letters connect. (From left to right: Blooms by DearType, JoeHand 2 by JOEBOB Graphics, and Brush Marker by Fenotype.) (Large preview) Do You Want Your Font To Include A Texture Effect?

Adding texture can enhance a feeling of antiquity or nostalgia, but this treatment adds time, complexity, and increases file size. And it may influence whether or not someone will want to license and use your font, since they may or may not be looking for that specific effect.

Examine your original specimen to determine where the texture came from. Was it caused by the paper surface? Was variation caused by the writing tool or writing speed? Are irregularities clustered on curves? Does one side of the letter include more texture than the other? Do brush strokes or splatters of ink extend into the space surrounding each letter?

The word “Smashing” typeset in three different fonts that have three different textured looks: a paper texture look, rough edges, and brush strokes. (From left to right: Paper texture; Thirsty Rough by Yellow Design Studio, Scratchy pen and ink texture, Azalea Rough by Laura Worthington; Brush strokes, Sveglia by Wacaksara Co.) (Large preview)

Once you’ve made high-level decisions on the importance of historical accuracy, identified what idiosyncrasies make the handwriting special, considered how to add variation in axis, letter height, alignment to baseline, or stroke width, assessed how to connect glyphs, and decided if you want to include texture, it’s time to forge ahead with the design of your font.

Pick Your Letters

Make a copy of your specimen, and go through it line by line, flagging the specific characters you want to incorporate into your font. When designer Brian Willson begins a new font, it is not unusual for him to spend hours poring over the source material to select the individual letters he plans to include.

Consider flagging two types of letters:

  1. Favorite “workhorse” letters
    Workhorse letters will make up your basic glyph set. They might not be the fanciest option, but workhorse characters will make for a reliable and legible glyph set.

  2. Favorite swash letters
    Swash letters might include extra loops or flourishes, more or less texture, greater variation in position above or below the baseline, or exaggerated features such as extra-long crossbars.

Swash letters may be less legible, or may only be appropriate for use in specific instances, but can add variety, beauty, and personality. (Swash glyphs will be added later in the process; focus first on designing the workhorse glyph set.)

Ideally, at the end of your review, you will have flagged a complete set of upper and lowercase workhorse letters, numbers, punctuation marks, and an array of swash characters.

Scan Individual Letters And Prepare To Vectorize

Create high-resolution bitmap images of all letters you plan to include in your font. I have always used a flatbed scanner to capture those images, but I have heard of people exporting sketches from Procreate or taking high-resolution photos on their phones. If you take a photo, be sure your phone is parallel to your specimen to avoid distortion.

Once you have assembled a collection of bitmap images, you will need to choose between vectorizing the letterforms using Adobe Illustrator’s Image Trace feature or importing the scans directly into font editing software then vectorizing them by hand.

Using Illustrator’s Image Trace feature may be preferred if your specimen includes lots of texture since Illustrator can capture that texture for you. To create a vector outline, import a bitmap image into Illustrator, then using advanced Image Trace menu options, test combinations of Paths, Corners, and Noise to get the tracing result you prefer. Expand to get your vector outline.

Importing scans directly into font editing software may be preferred if your font is not going to include texture, if you are comfortable generating Bezier lines, or if you intend to make significant revisions to letter shapes.

Recommended reading: How New Font Technologies Will Improve The Web

Establish A New Font File

Popular font editing software options include FontLab Studio VI (Mac or Windows OS, $459), Glyphs (Mac OS, €249.90), Robofont (Mac OS, $490), Font Creator (Windows, $79–199), and Font Forge (free). There is also an extension for Illustrator and Photoshop CC called FontSelf which allows you to convert lettering into a font ($49–$98).

Establish a new font file. If you created vector outlines using Illustrator, import each outline into the applicable glyph cell (that is, place the vector outline of the letter a in the a glyph cell so that an a appears when you hit the a key on your keyboard).

If you chose to vectorize the glyphs within the font editing software, import each bitmap scan as a background sketch, then trace.

Identify Archetype Letters

Some font designers begin by designing or refining the letters n, b, o, v, A, H and O since those letters contain clues to the shape of many other letters. The n, for example, holds clues to the shape of the i and h; the b holds clues to the shape of d, p, and q; the O holds clues to C and G. Other designers begin with the most frequently used letters of the alphabet: e, t, a, o, i, and n. In the fantastic book Designing Type, which is chock full of images that compare variations in letter shapes, Karen Cheng notes some designers begin with the letters a, e, g, n, and o.

You may begin with one of those glyph sets, but if you’ve identified a few letters that quintessentially represent the aesthetic of your font, consider starting by refining those glyphs. When I began to work on the P22 Marcel Script, I began by working on the capital M for no other reason than the swoop of the original handwritten M was exquisite, and it brought joy to see that letter come to life as a glyph. (After working on the M, I focused on refining archetype letters n and e.)

From left to right: Original scan, original tracing, glyph outline in FontLab (note the refinements to stroke width and axis), and final M in P22 Marcel Script. (Large preview)

No matter which glyphs you begin with, you will quickly want to establish standards for the axis, letter heights, alignment to baseline, and stroke widths. Ensure all glyphs meet those standards while simultaneously keeping in mind incorporating variability to achieve an organic look.

In order to introduce variability in an intentional way, it might be helpful to add guidelines to your workspace to define the lower and upper ranges of variability. Use these guidelines to introduce variation in ascender height, descender length, or in alignment to the baseline.

Do you want your font to have more variability? Increase the distance between the guidelines. Do you want your font to have less variability? Decrease the distance between the guidelines. Add variability to stroke widths in a similar way.

Lowercase glyph set of P22 Marcel Script. Notice variability in length of the descenders in the letters f, g, y, and z, variability in the height of letters i and j, and how I chose not to connect letters v and w with the following letter. (Large preview)

You will also want to establish a standard position for the overlap. Since there is not one correct place for these overlaps, experiment with a limited number of glyphs until the overlaps appear as natural as if the letters had been written with a pen without lifting the pen off the page. Then, test the position of the overlap on tricky letters such as r, o, s, f, v and w to confirm the overlap works. You’ll know if there are issues because glyphs won’t connect, or the connection won’t appear smooth. (If you see white where two black letters overlap, check for a Postscript path direction error.)

The good news is that once you have established the successful position for your overlaps you should be able to cut, copy, and paste the connecting line to replicate the position of the overlap on all remaining letters.

Overlaps in P22 Marcel Script (Large preview) Test As You Go

As soon as you have a collection of glyphs — even if it isn’t the entire alphabet — generate a test file and preview your font. If your goal was to replicate your specimen with accuracy, assess whether the font reflects the rhythm and character of the original handwriting. Evaluate whether the “color” — the overall darkness or lightness — matches the original. Refine glyphs as necessary to achieve the right rhythm, character, and color.

If you have chosen to take liberties with the shapes of letters or to introduce variability, your goal should still be to achieve an overall cohesive aesthetic. It is up to you as the designer to define precisely what that means.

As you test, it will be helpful to print blocks of sample text at a range of sizes. Reverse letters out of black. Look at the spaces between letters. Look at the spaces inside of letters. Look at strings of glyphs backwards, then upside down. Look at the font both when printed on paper and on a computer monitor. Testing under different conditions will help you notice glyphs that need additional refinement. I found that when I tested sample text set in a foreign language the unfamiliar letter combinations would help me see individual glyphs that were too heavy, too light, too narrow or too wide, along with individual curves that seemed too rounded or too flat.

For the first-time type designer, I recommend the book Inside Paragraphs: Typographic Fundamentals by Cyrus Highsmith (see list of references below). The book provides an invaluable primer on learning how to look at shapes and spaces in and around letters.

Continue testing and revising glyphs until your font includes a–z lowercase, A–Z uppercase, numbers, fractions, punctuation marks, and diacritics (marks such as the umlaut, acute, or tilde added to letters to indicate stress or change in pronunciation).

Add Swashes And Alternate Characters

Once your workhorse glyph set is complete, consider adding the swash characters you flagged when you picked your initial letters. A digital font can never offer the infinite variability found in handwriting, but by writing lines of OpenType code and incorporating swashes, ligatures (two or more letters that are combined into a single glyph), and alternate characters, you can begin to close the gap between the mechanical nature of a font and organic variation of handwriting. OpenType code allows you to do things like ensure two of the same glyphs never appear next to each other, or replace a workhorses glyph with a fancy swash or with a glyph that has more (or less) texture.

This work can be time-consuming, but you just might find it is addictive. You might discover every word you test could benefit from some custom flourish. The font Suomi, designed by Tomi Haaparanta, includes more than 700 ligatures. The font Hipster Script, designed by Ale Paul has 1,066. Syys Script by Julia Sysmäläinen for Art. Lebedev Studio has more than 2,000 glyphs. And between the Latin and Cyrillic versions, the font NIVEA Care Type by Juliasys has more than 4,000 glyphs.

Between swashes, ornaments, and alternate characters, the Pro version of the P22 Marcel Script includes more than 1,300 glyphs. Many of the alternate glyphs were inspired by flourishes in the original specimen; other glyphs were of my own invention, but were made in the style of the original writing. In my experience, incorporating swashes, ligatures, and alternate characters is the most exciting part about designing a connected cursive script font. In fact, it is what brings a connected cursive script font to life.

From left to right: P22 Marcel Script basic (workhorse) glyph set, P22 Marcel Script Pro incorporating alternate glyphs, and P22 Marcel Script Pro showing additional alternate glyphs, swashes, and an ornament. (Large preview) Final Steps

Once all your glyphs have been designed and the font has been thoroughly tested for technical performance and aesthetics, it is time to name the font and release it into the world.

Ensure no other font is already using the name you are considering. You can do a preliminary search on aggregator websites such as MyFonts, Fonts.com, FontShop, or Creative Market. Fonts are also distributed by individual font foundries and designers. Because there are so many distribution channels, the only way to guarantee availability and protect a name is to apply for a copyright with the U.S. Patent and Trademark Office (for U.S. designers). Consider hiring a lawyer to help with the filing process.

Finally, when it is time to release the font, if this is your first font it may be easiest to distribute your font through an established foundry or aggregator website. They should offer technical support, and will track licensing and sales tax. Consider working with one of the websites listed above; each website will have a different process to submit a font for consideration.

Further Reading (ah, ra, il)
Categories: Around The Web

Powerful Image Analysis With Google Cloud Vision And Python

Smashing Magazine - Wed, 01/09/2019 - 7:45am
Powerful Image Analysis With Google Cloud Vision And Python Powerful Image Analysis With Google Cloud Vision And Python Bartosz Biskupski 2019-01-09T13:45:32+01:00 2019-01-18T21:18:05+00:00

Quite recently, I’ve built a web app to manage user’s personal expenses. Its main features are to scan shopping receipts and extract data for further processing. Google Vision API turned out to be a great tool to get a text from a photo. In this article, I will guide you through the development process with Python in a sample project.

If you’re a novice, don’t worry. You will only need a very basic knowledge of this programming language — with no other skills required.

Let’s get started, shall we?

Never Heard Of Google Cloud Vision?

It’s an API that allows developers to analyze the content of an image through extracted data. For this purpose, Google utilizes machine learning models trained on a large dataset of images. All of that is available with a single API request. The engine behind the API classifies images, detects objects, people’s faces, and recognizes printed words within images.

To give you an example, let’s bring up the well-liked Giphy. They’ve adopted the API to extract caption data from GIFs, what resulted in significant improvement in user experience. Another example is realtor.com, which uses the Vision API’s OCR to extract text from images of For Sale signs taken on a mobile app to provide more details on the property.

Machine Learning At A Glance

Let’s start with answering the question many of you have probably heard before — what is the Machine Learning?

The broad idea is to develop a programmable model that finds patterns in the data its given. The higher quality data you deliver and the better the design of the model you use, the smarter outcome will be produced. With ‘friendly machine learning’ (as Google calls their Machine Learning through API services), you can easily incorporate a chunk of Artificial Intelligence into your applications.

Recommended reading: Getting Started With Machine Learning

Ahoy! The hunt for shiny front-end & UX treasures has begun! Meet SmashingConf San Francisco 2019

Categories: Around The Web

How To Design Search For Your Mobile App

Smashing Magazine - Tue, 01/08/2019 - 8:00am
How To Design Search For Your Mobile App How To Design Search For Your Mobile App Suzanne Scacca 2019-01-08T14:00:40+01:00 2019-01-18T21:18:05+00:00

Why is Google the search behemoth it is today? Part of the reason is because of how it’s transformed our ability to search for answers.

Think about something as simple as looking up the definition of a word. 20 years ago, you would’ve had to pull your dictionary off the shelf to find an answer to your query. Now, you open your phone or turn on your computer, type or speak the word, and get an answer in no time at all and with little effort on your part.

This form of digital shortcutting doesn’t just exist on search engines like Google. Mobile apps now have self-contained search functions as well.

Is a search bar even necessary in a mobile app interface or is it overkill? Let’s take a look at why the search bar element is important for the mobile app experience. Then, we’ll look at a number of ways to design search based on the context of the query and the function of the app.

Using The Web With A Screen Reader

Did you know that VoiceOver makes up 11.7% of desktop screen reader users and rises to 69% of screen reader users on mobile? It’s important to know what sort of first-hand difficulties visually impaired users face and what web developers can do to help. Read article →

Our new book, in which Alla Kholmatova explores how to create effective and maintainable design systems to design great digital products. Meet Design Systems, with common traps, gotchas and the lessons Alla has learned over the years.

Table of Contents → Mobile App Search Is Non-Negotiable

The search bar has been a standard part of websites for years, but statistics show that it isn’t always viewed as a necessity by users. This data from Neil Patel and Kissmetrics focuses on the perception and usage of the search bar on e-commerce websites:

Data from a Kissmetrics infographic about site search. (Source: Kissmetrics) (Large preview)

As you can see, 60% of surveyed users prefer using navigation instead of search while 47% opt for filterable “search” over regular search functionality.

On a desktop website, this makes sense. When a menu is well-designed and well-labeled — no matter how extensive it may be — it’s quite easy to use. Add to that advanced filtering options, and I can see why website visitors would prefer that to search.

But mobile app users are a different breed. They go to mobile apps for different reasons than they do websites. In sum, they want a faster, concentrated, and more convenient experience. However, since smartphone screens have limited space, it’s not really feasible to include an expansive menu or set of filters to aid in the navigation of an app.

This is why mobile apps need a search bar.

You’re going to find a lot of use for search in mobile apps:

  • Content-driven apps like newspapers, publishing platforms, and blogs;
  • e-Commerce shops with large inventories and categorization of those inventories;
  • Productivity apps that contain documents, calendars, and other searchable records;
  • Listing sites that connect users to the right hotel, restaurant, itinerary, item for sale, apartment for rent, and so on;
  • Dating and networking apps that connect users with vast quantities of “matches”.

There are plenty more reasons why you’d need to use a search bar on your mobile app, but I’m going to let the examples below speak for themselves.

Ways To Design Search For Your Mobile App

I’m going to break down this next section into two categories:

  1. How to design the physical search element in your mobile app,
  2. How to design the search bar and its results within the context of the app.
1. Designing The Physical Search Element

There are a number of points to consider when it comes to the physical presence of your app search element:

Top Or Bottom?

Shashank Sahay explains why there are two places where the search element appears on a mobile app:

  • 1. Full-width bar at the top of the app.
    This is for apps that are driven by search. Most of the time, users open the app with the express purpose of conducting a search.
Facebook prioritizes app search by placing it at the top. (Source: Facebook) (Large preview)

Facebook is a good example. Although Facebook users most likely do engage with the news feed in the app, I have a sneaking suspicion that Facebook’s data indicates that the search function is more commonly engaged with — at least in terms of first steps. Hence, why it’s placed at the top of the app.

  • 2. A tab in the bottom-aligned navigation bar.
    This is for apps that utilize search as an enhancement to the primary experience of using the app’s main features.

Let’s contrast Facebook against one of its sister properties: Instagram. Unlike Facebook, Instagram is a very simple social media app. Users follow other accounts and get glimpses into the content they share through full-screen story updates as well as from inside their endless-scroll news feed.

Instagram places its search function in the bottom navigation bar. (Source: Instagram) (Large preview)

With that said, the search function does exist in the navigation bar so that users can look up other accounts to peruse through or follow.

As far as this basic breakdown goes, Sahay is right about how placement of search correlates with intention. But the designing of the search element goes beyond just where it’s placed on the app.

Shallow Or Deep?

There will be times when a mobile app would benefit from a search function deep within the app experience.

You’ll see this sort of thing quite often in e-commerce apps like Bed Bath & Beyond:

Bed Bath & Beyond uses deep search to help users find nearby stores (Source: Bed Bath & Beyond) (Large preview)

In this example, this search function exists outside of the standard product search on the main landing page. Results for this kind of search are also displayed in a unique way which is reflective of the purpose of the search:

Bed Bath & Beyond displays search results on a map. (Source: Bed Bath & Beyond) (Large preview)

There are other ways you use might need to use “deep” search functions on e-commerce apps.

Think about stores that have loads of comments attached to each product. If your users want to zero in on what other consumers had to say about a product (for example, if a camping tent is waterproof), the search function would help them quickly get to reviews containing specific keywords.

You’ll also see deep searches planted within travel and entertainment apps like Hotels.com:

Hotels.com includes a deep search to narrow down results by property name. (Source: Hotels.com) (Large preview)

You’re all probably familiar with the basic search function that goes with any travel-related app. You enter the details of your trip and it pulls up the most relevant results in a list or map format. That’s what this screenshot is of.

However, see where it says “Property Name” next to the magnifying glass? This is a search function within a search function. And the only things users can search for here are actual hotel property names.

Bar, Tab, Or Magnifying Glass?

This brings me to my next design point: how to know which design element to represent the search function with.

You’ve already seen clear reasons to use a full search bar over placing a tab in the navigation bar. But how about a miniaturized magnifying glass?

Here’s an example of how this is used in the YouTube mobile app:

YouTube uses a magnifying glass to represent its search function. (Source: YouTube) (Large preview)

The way I see it, the magnifying glass is the search design element you’d use when:

  • One of the primary reasons users come to the app is to do a search,
  • And it competes against another primary use case.

In this case, YouTube needs the mini-magnifying glass because it serves two types of users:

  1. Users that come to the app to search for videos.
  2. Users that come to the app to upload their own videos.

To conserve space, links to both exist within the header of the YouTube app. If you have competing priorities within your app, consider doing the same.

“Search” Or Give A Hint?

One other thing to think about when designing search for mobile apps is the text inside the search box. To decide this, you have to ask yourself:

“Will my users know what sort of stuff they can look up with this search function?”

In most cases they will, but it might be best to include hint text inside the search bar just to make sure you’re not adding unnecessary friction. Here’s what I mean by that:

This is the app for Airbnb:

Airbnb offers hint text to guide users to more accurate search results. (Source: Airbnb) (Large preview)

The search bar tells me to “Try ‘Costa de Valencia’”. It’s not necessarily an explicit suggestion. It’s more helping me figure out how I can use this search bar to research places to stay on an upcoming trip.

For users that are new to Airbnb, this would be a helpful tip. They might come to the site thinking it’s like Hotels.com that enables users to look up things like flights and car rentals. Airbnb, instead, is all about providing lodging and experiences, so this search text is a good way to guide users in the right direction and keep them from receiving a “Sorry, there are no results that match your query” response.

2. Designing The Search Bar And Results In Context

Figuring out where to place the search element is one point to consider. Now, you have to think about how to present the results to your mobile app users:

Simple Search

This is the most basic of the search functions you can offer. Users type their query into the search bar. Relevant results appear below. In other words, you leave it up to your users to know what they’re searching for and to enter it correctly.

When a relevant query is entered, you can provide results in a number of ways.

For an app like Flipboard, results are displayed as trending hashtags:

Flipboard displays search results as a list of hashtags. (Source: Flipboard) (Large preview)

It’s not the most common way you’d see search results displayed, but it makes sense in this particular context. What users are searching for are categories of content they want to see in their feed. These hashtagged categories allow users to choose high-level topics that are the most relevant to them.

ESPN has a more traditional basic search function:

ESPN has designed its search results in a traditional list. (Source: ESPN) (Large preview)

As you can see, ESPN provides a list of results that contain the keyword. There’s nothing more to it than that though. As you’ll see in the following examples, you can program your app search to more closely guide users to the results they want to see.

Filtered Search

According to the aforementioned Kissmetrics survey, advanced filtering is a popular search method among website users. If your mobile app has a lot of content or a vast inventory of products, consider adding filters to the end of your search function to improve the experience further. Your users are already familiar with the search technique. Plus, it’ll save you the trouble of having to add advancements to the search functionality itself.

Yelp has a nice example of this:

Yelp users have filter options available after doing a search. (Source: Yelp) (Large preview)

In the search above, I originally looked for restaurants in my “Current Location”. Among the various filters displayed, I decided to add “Order Delivery” to my query. My search query then became:

Restaurants > Current Location > Delivery

This is really no different than using breadcrumbs on a website. In this case, you let users do the initial work by entering a search query. Then, you give them filters that allow them to narrow down their search further.

Again, this is another way to reduce the chances that users will encounter the “No results” response to their query. Because filters correlate to actual categories and segmentations that exist within the app, you can ensure they end up with valid search results every time.

e-Commerce websites are another good use case for filters. Here is how Wayfair does this:

Wayfair includes filters in search to help users narrow down results. (Source: Wayfair) (Large preview)

Wayfair’s list of search results is fairly standard for an e-commerce marketplace. The number of items are displayed, followed by a grid of matching product images and summary details.

Here’s the thing though: Wayfair has a massive inventory. It’s the same with other online marketplaces like Amazon and Zappos. So, when you tell users that their search query produced 2,975 items, you need a way to mitigate some of the overwhelm that may come with that.

By placing the Sort and Filter buttons directly beside the search result total, you’re encouraging users to do a little more work on their search query to ensure they get the best and most relevant results.

Predictive Search

Autocomplete is something your users are already familiar with. For apps that contain lots of content, utilizing this type of search functionality could be majorly helpful to your users.

For one, they already know how it works and so they won’t be surprised when related query suggestions appear before them. In addition, autocomplete offers a sort of personalization. As you gather more data on a user as well as the kinds of searches they conduct, autocomplete anticipates their needs and provides a shortcut to the desired content.

Pinterest is a social media app that people use to aggregate content they’re interested in and to seek out inspiration for pretty much anything they’re doing in life:

Pinterest anticipates users’ search queries and provides autocomplete shortcuts. (Source: Pinterest) (Large preview)

Take a look at the search results above. Can you tell what I’ve been thinking about lately? The first is how I’m going to decorate my new apartment. The second is my next tattoo. And despite only typing out the word “Small”, Pinterest immediately knew what’s been top-of-mind with me as of recent. That doesn’t necessarily mean I as a user came to the app with that specific intention today… but it’s nice to see that personalized touch as I engage with the search bar.

Another app I engage with a lot is the Apple Photos app:

Apple Photos uses autocomplete to help users find the most relevant photos. (Source: Apple) (Large preview)

In addition to using it to store all of my personal photos, I use this on a regular basis to take screenshots for work (as I did in this article). As you can imagine, I have a lot of content saved to this app and it can be difficult finding what I need just by scrolling through my folders.

In the example above, I was trying to find a photo I had taken at Niagara Falls, but I couldn’t remember if I had labeled it as such. So, I typed in “water” and received some helpful autocomplete suggestions on “water”-related words as well as photos that fit the description.

I would also put “Recent Search” results into this bucket. Here’s an example from Uber:

Uber’s recent search results provide one-click shortcuts to repeat users. (Source: Uber) (Large preview)

Before I even had a chance to type my search query in the Uber app, it displays my most recent search queries for me.

I think this would be especially useful for people who use ride-sharing services on a regular basis. Think about professionals who work in a city. Rather than own a car, they use Uber to transport to and from their office as well as client appointments. By providing a shortcut to recent trips in search results, the Uber app cuts down the time they spend booking a trip.

If you have enough data on your users and you have a way to anticipate their needs, autocomplete is a fantastic way to personalize search and improve the overall experience.

Limited Search

I think this time savings point is an important one to remember when designing search for mobile apps.

Unlike websites where longer times-on-page matter, that’s not always the case with mobile apps. Unless you’ve built a gaming or news app where users should spend lots of time engaging with the app on a daily basis, it’s not usually the amount of time spent inside the app that matters.

Your goal in building a mobile app is to retain users over longer periods, which means providing a meaningful experience while they’re inside it. A well-thought-out search function will greatly contribute to this as it gets users immediately to what they want to see, even if it means they leave the app just a few seconds later.

If you have an app that needs to get users in and out of it quickly, think about limiting search results as Ibotta has done:

Ibotta displays categories that users can search in. (Source: Ibotta) (Large preview)

While users certainly can enter any query they’d like, Ibotta makes it clear that the categories below are the only ones available to search from. This serves as both a reminder of what the app is capable of as well as a means for circumventing the search results that don’t matter to users.

Hotels.com also places limits on its search function:

Hotels.com forces users to make a choice so they don’t end up with too many results. (Source: Hotels.com) (Large preview)

As you can see here, users can’t just look for hotels throughout the country of Croatia. It’s just too broad of a search and one that Hotels.com shouldn’t have to provide. For one, it’s probably too taxing on the Hotels.com server to execute a query of that nature. Plus, it would provide a terrible experience for users. Imagine how many hotels would show up in that list of results.

By reining in what your users can search for and the results they can see, you can improve the overall experience while shortening the time it takes them to convert.

Wrapping Up

As you can see here, a search bar isn’t some throwaway design element. When your app promises a speedy and convenient experience to its users, a search bar can cut down on the time they have to spend inside it. It can also make the app a more valuable resource as it doesn’t require much work or effort to get to the desired content.

(ra, yk, il)
Categories: Around The Web

Front-End Performance Checklist 2019 [PDF, Apple Pages, MS Word]

Smashing Magazine - Mon, 01/07/2019 - 7:00am
Front-End Performance Checklist 2019 [PDF, Apple Pages, MS Word] Front-End Performance Checklist 2019 [PDF, Apple Pages, MS Word] Vitaly Friedman 2019-01-07T12:00:13+00:00 2019-01-18T21:18:05+00:00

Web performance is a tricky beast, isn’t it? How do we actually know where we stand in terms of performance, and what our performance bottlenecks exactly are? Is it expensive JavaScript, slow web font delivery, heavy images, or sluggish rendering? Is it worth exploring tree-shaking, scope hoisting, code-splitting, and all the fancy loading patterns with intersection observer, server push, clients hints, HTTP/2, service workers and — oh my — edge workers? And, most importantly, where do we even start improving performance and how do we establish a performance culture long-term?

Back in the day, performance was often a mere afterthought. Often deferred till the very end of the project, it would boil down to minification, concatenation, asset optimization and potentially a few fine adjustments on the server’s config file. Looking back now, things seem to have changed quite significantly.

Performance isn’t just a technical concern: it matters, and when baking it into the workflow, design decisions have to be informed by their performance implications. Performance has to be measured, monitored and refined continually, and the growing complexity of the web poses new challenges that make it hard to keep track of metrics, because metrics will vary significantly depending on the device, browser, protocol, network type and latency (CDNs, ISPs, caches, proxies, firewalls, load balancers and servers all play a role in performance).

So, if we created an overview of all the things we have to keep in mind when improving performance — from the very start of the process until the final release of the website — what would that list look like? Below you’ll find a (hopefully unbiased and objective) front-end performance checklist for 2019 — an updated overview of the issues you might need to consider to ensure that your response times are fast, user interaction is smooth and your sites don’t drain user’s bandwidth.

Table Of Contents

(You can also just download the checklist PDF (166 KB) or download editable Apple Pages file (275 KB) or the .docx file (151 KB). Happy optimizing, everyone!)

ol.start { counter-reset: perfcounter; } ol.start > li:before, ol.continue > li:before { content: counters(perfcounter, '.', decimal-leading-zero); counter-increment: perfcounter; } @media all and (min-width: 1024px) { ol.start > li, ol.continue > li { list-style: none; margin-bottom: 1.5em; margin-top: 2em; } ol.start > li:first-child, ol.continue > li:first-child { margin-top: 1em; } ol.start > li:before, ol.continue > li:before { margin-left: -1.1em; margin-right: 2.4%; font-family: "Mija", Arial, sans-serif; display: inline-block; line-height: 1.1em; text-align: center; background-color: #E53B2C; color: #fff; padding: .65em .5em .5em .5em; border-radius: 11px; } ol.start p, ol.continue p { font-size: inherit; } }

Front-end is messy and complicated these days. That's why we publish articles, printed books and webinars with useful techniques to improve your work. Even better: Smashing Membership with a growing selection of front-end & UX goodies. So you get your work done, better and faster.

Explore Smashing Membership ↬ Getting Ready: Planning And Metrics

Micro-optimizations are great for keeping performance on track, but it’s critical to have clearly defined targets in mind — measurable goals that would influence any decisions made throughout the process. There are a couple of different models, and the ones discussed below are quite opinionated — just make sure to set your own priorities early on.

  1. Establish a performance culture.
    In many organizations, front-end developers know exactly what common underlying problems are and what loading patterns should be used to fix them. However, as long as there is no established endorsement of the performance culture, each decision will turn into a battlefield of departments, breaking up the organization into silos. You need a business stakeholder buy-in, and to get it, you need to establish a case study on how speed benefits metrics and Key Performance Indicators (KPIs) they care about.

    Without a strong alignment between dev/design and business/marketing teams, performance isn’t going to sustain long-term. Study common complaints coming into customer service and see how improving performance can help relieve some of these common problems.

    Run performance experiments and measure outcomes — both on mobile and on desktop. It will help you build up a company-tailored case study with real data. Furthermore, using data from case studies and experiments published on WPO Stats will help increase sensitivity for business about why performance matters, and what impact it has on user experience and business metrics. Stating that performance matters alone isn’t enough though — you also need to establish some measurable and trackable goals and observe them.

    How to get there? In her talk on Building Performance for the Long Term, Allison McKnight shares a comprehensive case-study of how she helped establish a performance culture at Etsy (slides).

Performance budget builder by Brad Frost and Jonathan Fielding’s Performance Budget Calculator can help you set up your performance budget and visualize it. (Large preview)
  1. Goal: Be at least 20% faster than your fastest competitor.
    According to psychological research, if you want users to feel that your website is faster than your competitor’s website, you need to be at least 20% faster. Study your main competitors, collect metrics on how they perform on mobile and desktop and set thresholds that would help you outpace them. To get accurate results and goals though, first study your analytics to see what your users are on. You can then mimic the 90th percentile’s experience for testing.

    To get a good first impression of how your competitors perform, you can use Chrome UX Report (CrUX, a ready-made RUM data set, video introduction by Ilya Grigorik), Speed Scorecard (also provides a revenue impact estimator), Real User Experience Test Comparison or SiteSpeed CI (based on synthetic testing).

    Note: If you use Page Speed Insights (no, it isn’t deprecated), you can get CrUX performance data for specific pages instead of just the aggregates. This data can be much more useful for setting performance targets for assets like “landing page” or “product listing”. And if you are using CI to test the budgets, you need to make sure your tested environment matches CrUX if you used CrUX for setting the target (thanks Patrick Meenan!).

    Collect data, set up a spreadsheet, shave off 20%, and set up your goals (performance budgets) this way. Now you have something measurable to test against. If you’re keeping the budget in mind and trying to ship down just the minimal script to get a quick time-to-interactive, then you’re on a reasonable path.

    Need resources to get started?

    Once you have a budget in place, incorporate them into your build process with Webpack Performance Hints and Bundlesize, Lightouse CI, PWMetrics or Sitespeed CI to enforce budgets on pull requests and provide a score history in PR comments. If you need something custom, you can use webpagetest-charts-api, an API of endpoints to build charts from WebPagetest results.

    For instance, just like Pinterest, you could create a custom eslint rule that disallows importing from files and directories that are known to be dependency-heavy and would bloat the bundle. Set up a listing of “safe” packages that can be shared across the entire team.

    Beyond performance budgets, think about critical customer tasks that are most beneficial to your business. Set and discuss acceptable time thresholds for critical actions and establish "UX ready" user timing marks that the entire organization has agreed on. In many cases, user journeys will touch on the work of many different departments, so alignment in terms of acceptable timings will help support or prevent performance discussions down the road. Make sure that additional costs of added resources and features are visible and understood.

    Also, as Patrick Meenan suggested, it’s worth to plan out a loading sequence and trade-offs during the design process. If you prioritize early on which parts are more critical, and define the order in which they should appear, you will also know what can be delayed. Ideally, that order will also reflect the sequence of your CSS and JavaScript imports, so handling them during the build process will be easier. Also, consider what the visual experience should be in "in-between"-states, while the page is being loaded (e.g. when web fonts aren’t loaded yet).

    Planning, planning, planning. It might be tempting to get into quick "low-hanging-fruits"-optimizations early on — and eventually it might be a good strategy for quick wins — but it will be very hard to keep performance a priority without planning and setting realistic, company-tailored performance goals.

The difference between First Paint, First Contentful Paint, First Meaningful Paint, Visual Complete and Time To Interactive. Large view. Credit: @denar90
  1. Choose the right metrics.
    Not all metrics are equally important. Study what metrics matter most to your application: usually it will be related to how fast you can start render most important pixels of your product and how quickly you can provide input responsiveness for these rendered pixels. This knowledge will give you the best optimization target for ongoing efforts.

    One way or another, rather than focusing on full page loading time (via onLoad and DOMContentLoaded timings, for example), prioritize page loading as perceived by your customers. That means focusing on a slightly different set of metrics. In fact, choosing the right metric is a process without obvious winners.

    Based on Tim Kadlec’s research and Marcos Iglesias’ notes in his talk, traditional metrics could be grouped into a few sets. Usually, we’ll need all of them to get a complete picture of performance, and in your particular case some of them might be more important than others.

    • Quantity-based metrics measure the number of requests, weight and a performance score. Good for raising alarms and monitoring changes over time, not so good for understanding user experience.
    • Milestone metrics use states in the lifetime of the loading process, e.g. Time To First Byte and Time To Interactive. Good for describing the user experience and monitoring, not so good for knowing what happens between the milestones.
    • Rendering metrics provide an estimate of how fast content renders (e.g. Start Render time, Speed Index). Good for measuring and tweaking rendering performance, but not so good for measuring when important content appears and can be interacted with.
    • Custom metrics measure a particular, custom event for the user, e.g. Twitter’s Time To First Tweet and Pinterest’s PinnerWaitTime. Good for describing the user experience precisely, not so good for scaling the metrics and comparing with with competitors.

    To complete the picture, we’d usually look out for useful metrics among all of these groups. Usually, the most specific and relevant ones are:

    • First Meaningful Paint (FMP)
      Provides the timing when primary content appears on the page, providing an insight into how quickly the server outputs any data. Long FMP usually indicates JavaScript blocking the main thread, but could be related to back-end/server issues as well.
    • Time to Interactive (TTI)
      The point at which layout has stabilized, key webfonts are visible, and the main thread is available enough to handle user input — basically the time mark when a user can interact with the UI. The key metrics for understanding how much wait a user has to experience to use the site without a lag.
    • First Input Delay (FID), or Input responsiveness
      The time from when a user first interacts with your site to the time when the browser is actually able to respond to that interaction. Complements TTI very well as it describes the missing part of the picture: what happens when a user actually interacts with the site. Intended as a RUM metric only. There is a JavaScript library for measuring FID in the browser.
    • Speed Index
      Measures how quickly the page contents are visually populated; the lower the score, the better. The Speed Index score is computed based on the speed of visual progress, but it’s merely a computed value. It’s also sensitive to the viewport size, so you need to define a range of testing configurations that match your target audience (thanks, Boris!).
    • CPU time spent
      A metric that indicates how busy is the main thread with the processing of the payload. It shows how often and how long the main thread is blocked, working on painting, rendering, scripting and loading. High CPU time is a clear indicator of a janky experience, i.e. when the user experiences a noticeable lag between their action and a response. With WebPageTest, you can select "Capture Dev Tools Timeline" on the "Chrome" tab to expose the breakdown of the main thread as it runs on any device using WebPageTest.
    • Ad Weight Impact
      If your site depends on the revenue generated by advertising, it’s useful to track the weight of ad related code. Paddy Ganti’s script constructs two URLs (one normal and one blocking the ads), prompts the generation of a video comparison via WebPageTest and reports a delta.
    • Deviation metrics
      As noted by Wikipedia engineers, data of how much variance exists in your results could inform you how reliable your instruments are, and how much attention you should pay to deviations and outlers. Large variance is an indicator of adjustments needed in the setup. It also helps understand if certain pages are more difficult to measure reliably, e.g. due to third-party scripts causing significant variation. It might also be a good idea to track browser version to understand bumps in performance when a new browser version is rolled out.
    • Custom metrics
      Custom metrics are defined by your business needs and customer experience. It requires you to identify important pixels, critical scripts, necessary CSS and relevant assets and measure how quickly they get delivered to the user. For that one, you can monitor Hero Rendering Times, or use Performance API, marking particular timestaps for events that are important for your business. Also, you can collect custom metrics with WebPagetest by executing arbitrary JavaScript at the end of a test.

    Steve Souders has a detailed explanation of each metric. It’s important to notice that while Time-To-Interactive is measured by running automated audits in the so-called lab environment, First Input Delay represents the actual user experience, with actual users experiencing a noticeable lag. In general, it’s probably a good idea to always measure and track both of them.

    Depending on the context of your application, preferred metrics might differ: e.g. for Netflix TV UI, key input responsiveness, memory usage and TTI are more critical, and for Wikipedia, first/last visual changes and CPU time spent metrics are more important.

    Note: both FID and TTI do not account for scrolling behavior; scrolling can happen independently since it’s off-main-thread, so for many content consumption sites these metrics might be much less important (thanks, Patrick!).

User-centric performance metrics provide a better insight into the actual user experience. First Input Delay (FID) is a new metric that tries to achieve just that. (Large preview)
  1. Gather data on a device representative of your audience.
    To gather accurate data, we need to thoroughly choose devices to test on. It’s a good option to choose a Moto G4, a mid-range Samsung device, a good middle-of-the-road device like a Nexus 5X and a slow device like Alcatel 1X, perhaps in an open device lab. For testing on slower thermal-throttled devices, you could also get a Nexus 2, which costs just around $100.

    If you don’t have a device at hand, emulate mobile experience on desktop by testing on a throttled network (e.g. 150ms RTT, 1.5 Mbps down, 0.7 Mbps up) with a throttled CPU (5× slowdown). Eventually switch over to regular 3G, 4G and Wi-Fi. To make the performance impact more visible, you could even introduce 2G Tuesdays or set up a throttled 3G network in your office for faster testing.

    Keep in mind that on a mobile device, you should be expecting a 4×–5× slowdown compared to desktop machines. Mobile devices have different GPUs, CPU, different memory, different battery characteristics. While download times are critical for low-end networks, parse times are critical for phones with slow CPUs. In fact, parse times on mobile are 36% higher than on desktop. So always test on an average device — a device that is most representative of your audience.

  2. Introducing the slowest day of the week. Facebook has introduced 2G Tuesdays to increase visibility and sensitivity of slow connections. (Image source)

    Luckily, there are many great options that help you automate the collection of data and measure how your website performs over time according to these metrics. Keep in mind that a good performance picture covers a set of performance metrics, lab data and field data:

    • Synthetic testing tools collect lab data in a reproducible environment with predefined device and network settings (e.g. Lighthouse, WebPageTest) and
    • Real User Monitoring (RUM) tools evaluate user interactions continuously and collect field data (e.g. SpeedCurve, New Relic — both tools provide synthetic testing, too).

    The former is particularly useful during development as it will help you identify, isolate and fix performance issues while working on the product. The latter is useful for long-term maintenance as it will help you understand your performance bottlenecks as they are happening live — when users actually access the site.

    By tapping into built-in RUM APIs such as Navigation Timing, Resource Timing, Paint Timing, Long Tasks, etc., synthetic testing tools and RUM together provide a complete picture of performance in your application. You could use PWMetrics, Calibre, SpeedCurve, mPulse and Boomerang, Sitespeed.io, which all are great options for performance monitoring. Furthermore, with Server Timing header, you could even monitor back-end and front-end performance all in one place.

    Note: It’s always a safer bet to choose network-level throttlers, external to the browser, as, for example, DevTools has issues interacting with HTTP/2 push, due to the way it’s implemented (thanks, Yoav, Patrick!). For Mac OS, we can use Network Link Conditioner, for Windows Windows Traffic Shaper, for Linux netem, and for FreeBSD dummynet.

Lighthouse, a performance auditing tool integrated into DevTools. (Large preview)
  1. Set up "clean" and "customer" profiles for testing.
    While running tests in passive monitoring tools, it’s a common strategy to turn off anti-virus and background CPU tasks, remove background bandwidth transfers and test with a clean user profile without browser extensions to avoid skewed results (Firefox, Chrome).

    However, it’s also a good idea to study which extensions your customers are using frequently, and test with a dedicated "customer" profile as well. In fact, some extensions might have a profound performance impact on your application, and if your users use them a lot, you might want to account for it up front. "Clean" profile results alone are overly optimistic and can be crushed in real-life scenarios.

  2. Share the checklist with your colleagues.
    Make sure that the checklist is familiar to every member of your team to avoid misunderstandings down the line. Every decision has performance implications, and the project would hugely benefit from front-end developers properly communicating performance values to the whole team, so that everybody would feel responsible for it, not just front-end developers. Map design decisions against performance budget and the priorities defined in the checklist.

Setting Realistic Goals
  1. 100-millisecond response time, 60 fps.
    For an interaction to feel smooth, the interface has 100ms to respond to user’s input. Any longer than that, and the user perceives the app as laggy. The RAIL, a user-centered performance model gives you healthy targets: To allow for <100 milliseconds response, the page must yield control back to main thread at latest after every <50 milliseconds. Estimated Input Latency tells us if we are hitting that threshold, and ideally, it should be below 50ms. For high-pressure points like animation, it’s best to do nothing else where you can and the absolute minimum where you can't.

    RAIL, a user-centric performance model.

    Also, each frame of animation should be completed in less than 16 milliseconds, thereby achieving 60 frames per second (1 second ÷ 60 = 16.6 milliseconds) — preferably under 10 milliseconds. Because the browser needs time to paint the new frame to the screen, your code should finish executing before hitting the 16.6 milliseconds mark. We’re starting having conversations about 120fps (e.g. iPad’s new screens run at 120Hz) and Surma has covered some rendering performance solutions for 120fps, but that’s probably not a target we’re looking at just yet.

    Be pessimistic in performance expectations, but be optimistic in interface design and use idle time wisely. Obviously, these targets apply to runtime performance, rather than loading performance.

  2. Speed Index < 1250, TTI < 5s on 3G, Critical file size budget < 170KB (gzipped).
    Although it might be very difficult to achieve, a good ultimate goal would be First Meaningful Paint under 1 second and a Speed Index value under 1250. Considering the baseline being a $200 Android phone (e.g. Moto G4) on a slow 3G network, emulated at 400ms RTT and 400kbps transfer speed, aim for Time to Interactive under 5s, and for repeat visits, aim for under 2s (achievable only with a service worker),

    Notice that, when speaking about interactivity metrics, it’s a good idea to distinguish between First CPU Idle and Time To Interactive to avoid misunderstandings down the line. The former is the earliest point after the main content has rendered (where there is at least a 5-second window where the page is responsive). The latter is the point where the page can be expected to always be responsive to input (thanks, Philip Walton!).

    We have two major constraints that effectively shape a reasonable target for speedy delivery of the content on the web. On the one hand, we have network delivery constraints due to TCP Slow Start. The first 14KB of the HTML is the >most critical payload chunk — and the only part of the budget that can be delivered in the first roundtrip (which is all you get in 1 sec at 400ms RTT due to mobile wake-up times).

    On the other hand, we have hardware constraints on memory and CPU due to JavaScript parsing times (we’ll talk about them in detail later). To achieve the goals stated in the first paragraph, we have to consider the critical file size budget for JavaScript. Opinions vary on what that budget should be (and it heavily depends on the nature of your project), but a budget of 170KB JavaScript gzipped already would take up to 1s to parse and compile on an average phone. Assuming that 170KB expands to 3× that size when decompressed (0.7MB), that already could be the death knell of a "decent" user experience on a Moto G4 or Nexus 2.

    Of course, your data might show that your customers are not on these devices, but perhaps they simply don’t show up in your analytics because your service is inaccessible to them due to slow performance. In fact, Google’s Alex Russels recommends to aim for 130–170KB gzipped as a reasonable upper boundary, and exceeding this budget should be an informed and deliberate decision. In real-life world, most products aren’t even close: an average bundle size today is around 400KB, which is up 35% compared to late 2015. On a middle-class mobile device, that accounts for 30-35 seconds for Time-To-Interactive.

    We could also go beyond the bundle size budget though. For example, we could set performance budgets based on the activities of the browser’s main thread, i.e. paint time before start render, or track down front-end CPU hogs. Tools such as Calibre, SpeedCurve and Bundlesize can help you keep your budgets in check, and can be integrated into your build process.

    Also, a performance budget probably shouldn’t be a fixed value. Depending on the network connection, performance budgets should adapt, but payload on slower connection is much more "expensive", regardless of how they’re used.

From Fast By Default: Modern loading best practices by Addy Osmani (Slide 19) Performance budgets should adapt depending on the network conditions for an average mobile device. (Image source: Katie Hempenius) (Large preview) Defining The Environment
  1. Choose and set up your build tools.
    Don’t pay too much attention to what’s supposedly cool these days. Stick to your environment for building, be it Grunt, Gulp, Webpack, Parcel, or a combination of tools. As long as you are getting results you need and you have no issues maintaining your build process, you’re doing just fine.

    Among the build tools, Webpack seems to be the most established one, with literally hundreds of plugins available to optimize the size of your builds. Getting started with Webpack can be tough though. So if you want to get started, there are some great resources out there:

  2. Use progressive enhancement as a default.
    Keeping progressive enhancement as the guiding principle of your front-end architecture and deployment is a safe bet. Design and build the core experience first, and then enhance the experience with advanced features for capable browsers, creating resilient experiences. If your website runs fast on a slow machine with a poor screen in a poor browser on a sub-optimal network, then it will only run faster on a fast machine with a good browser on a decent network.

  3. If you need a practical implementation of the strategy on mid-scale and large-scale projects, Scott Jehl’s Modernizing our Progressive Enhancement Delivery article is a good place to start.

    -->
  4. Choose a strong performance baseline.
    With so many unknowns impacting loading — the network, thermal throttling, cache eviction, third-party scripts, parser blocking patterns, disk I/O, IPC latency, installed extensions, antivirus software and firewalls, background CPU tasks, hardware and memory constraints, differences in L2/L3 caching, RTTS — JavaScript has the heaviest cost of the experience, next to web fonts blocking rendering by default and images often consuming too much memory. With the performance bottlenecks moving away from the server to the client, as developers, we have to consider all of these unknowns in much more detail.

    With a 170KB budget that already contains the critical-path HTML/CSS/JavaScript, router, state management, utilities, framework and the application logic, we have to thoroughly examine network transfer cost, the parse/compile time and the runtime cost of the framework of our choice.

    As noted by Seb Markbåge, a good way to measure start-up costs for frameworks is to first render a view, then delete it and then render again as it can tell you how the framework scales. The first render tends to warm up a bunch of lazily compiled code, which a larger tree can benefit from when it scales. The second render is basically an emulation of how code reuse on a page affects the performance characteristics as the page grows in complexity.

From Fast By Default: Modern Loading Best Practices by Addy Osmani (Slides 18, 19).
  1. Evaluate each framework and each dependency.
    Now, not every project needs a framework and not every page of a single-page-application needs to load a framework. In Netflix’s case, "removing React, several libraries and the corresponding app code from the client-side reduced the total amount of JavaScript by over 200KB, causing an over-50% reduction in Netflix’s Time-to-Interactivity for the logged-out homepage." The team then utilized the time spent by users on the landing page to prefetch React for subsequent pages that users were likely to land on (read on for details).

    It might sound obvious but worth stating: some projects can also benefit benefit from removing an existing framework altogether. Once a framework is chosen, you’ll be staying with it for at least a few years, so if you need to use one, make sure your choice is informed and well considered.

    Inian Parameshwaran has measured performance footprint of top 50 frameworks (against First Contentful Paint — the time from navigation to the time when the browser renders the first bit of content from the DOM). Inian discovered that, out there in the wild, Vue and Preact are the fastest across the board — both on desktop and mobile, followed by React (slides). You could examine your framework candidates and the proposed architecture, and study how most solutions out there perform, e.g. with server-side rendering or client-side rendering, on average.

    Baseline performance cost matters. According to a study by Ankur Sethi, "your React application will never load faster than about 1.1 seconds on an average phone in India, no matter how much you optimize it. Your Angular app will always take at least 2.7 seconds to boot up. The users of your Vue app will need to wait at least 1 second before they can start using it." You might not be targeting India as your primary market anyway, but users accessing your site with suboptimal network conditions will have a comparable experience. In exchange, your team gains maintainability and developer efficiency, of course. But this consideration needs to be deliberate.

    You could go as far as evaluating a framework (or any JavaScript library) on Sacha Greif’s 12-point scale scoring system by exploring features, accessibility, stability, performance, package ecosystem, community, learning curve, documentation, tooling, track record, team, compatibility, security for example. But on a tough schedule, it’s a good idea to consider at least the total cost on size + initial parse times before choosing an option; lightweight options such as Preact, Inferno, Vue, Svelte or Polymer can get the job done just fine. The size of your baseline will define the constraints for your application’s code.

    A good starting point is to choose a good default stack for your application. Gatsby.js (React), Preact CLI, and PWA Starter Kit provide reasonable defaults for fast loading out of the box on average mobile hardware.

(Image credit: Addy Osmani) (Large preview)
  1. Consider using PRPL pattern and app shell architecture.
    Different frameworks will have different effects on performance and will require different strategies of optimization, so you have to clearly understand all of the nuts and bolts of the framework you’ll be relying on. When building a web app, look into the PRPL pattern and application shell architecture. The idea is quite straightforward: Push the minimal code needed to get interactive for the initial route to render quickly, then use service worker for caching and pre-caching resources and then lazy-load routes that you need, asynchronously.
PRPL stands for Pushing critical resource, Rendering initial route, Pre-caching remaining routes and Lazy-loading remaining routes on demand. An application shell is the minimal HTML, CSS, and JavaScript powering a user interface.
  1. Have you optimized the performance of your APIs?
    APIs are communication channels for an application to expose data to internal and third-party applications via so-called endpoints. When designing and building an API, we need a reasonable protocol to enable the communication between the server and third-party requests. Representational State Transfer (REST) is a well-established, logical choice: it defines a set of constraints that developers follow to make content accessible in a performant, reliable and scalable fashion. Web services that conform to the REST constraints, are called RESTful web services.

    As with good ol' HTTP requests, when data is retrieved from an API, any delay in server response will propagate to the end user, hence delaying rendering. When a resource wants to retrieve some data from an API, it will need to request the data from the corresponding endpoint. A component that renders data from several resources, such as an article with comments and author photos in each comment, may need several roundtrips to the server to fetch all the data before it can be rendered. Furthermore, the amount of data returned through REST is often more than what is needed to render that component.

    If many resources require data from an API, the API might become a performance bottleneck. GraphQL provides a performant solution to these issues. Per se, GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. Unlike REST, GraphQL can retrieve all data in a single request, and the response will be exactly what is required, without over or under-fetching data as it typically happens with REST.

    In addition, because GraphQL is using schema (metadata that tells how the data is structured), it can already organize data into the preferred structure, so, for example, with GraphQL, we could remove JavaScript code used for dealing with state management, producing a cleaner application code that runs faster on the client.

    If you want to get started with GraphQL, Eric Baer published two fantastic articles on yours truly Smashing Magazine: A GraphQL Primer: Why We Need A New Kind Of API and A GraphQL Primer: The Evolution Of API Design (thanks for the hint, Leonardo!).

A difference between REST and GraphQL, illustrated via a conversation between Redux + REST on the left, an Apollo + GraphQL on the right. (Image source: Hacker Noon) (Large preview)
  1. Will you be using AMP or Instant Articles?
    Depending on the priorities and strategy of your organization, you might want to consider using Google’s AMP or Facebook’s Instant Articles or Apple’s Apple News. You can achieve good performance without them, but AMP does provide a solid performance framework with a free content delivery network (CDN), while Instant Articles will boost your visibility and performance on Facebook.

    The seemingly obvious benefit of these technologies for users is guaranteed performance, so at times they might even prefer AMP-/Apple News/Instant Pages-links over "regular" and potentially bloated pages. For content-heavy websites that are dealing with a lot of third-party content, these options could potentially help speed up render times dramatically.

    Unless they don't. According to Tim Kadlec, for example, "AMP documents tend to be faster than their counterparts, but they don’t necessarily mean a page is performant. AMP is not what makes the biggest difference from a performance perspective."

    A benefit for the website owner is obvious: discoverability of these formats on their respective platforms and increased visibility in search engines. You could build progressive web AMPs, too, by reusing AMPs as a data source for your PWA. Downside? Obviously, a presence in a walled garden places developers in a position to produce and maintain a separate version of their content, and in case of Instant Articles and Apple News without actual URLs (thanks Addy, Jeremy!).

  2. Choose your CDN wisely.
    Depending on how much dynamic data you have, you might be able to "outsource" some part of the content to a static site generator, pushing it to a CDN and serving a static version from it, thus avoiding database requests. You could even choose a static-hosting platform based on a CDN, enriching your pages with interactive components as enhancements (JAMStack). In fact, some of those generators (like Gatsby on top of React) are actually website compilers with many automated optimizations provided out of the box. As compilers add optimizations over time, the compiled output gets smaller and faster over time.

    Notice that CDNs can serve (and offload) dynamic content as well. So, restricting your CDN to static assets is not necessary. Double-check whether your CDN performs compression and conversion (e.g. image optimization in terms of formats, compression and resizing at the edge), support for servers workers, edge-side includes, which assemble static and dynamic parts of pages at the CDN’s edge (i.e. the server closest to the user), and other tasks.

    Note: based on research by Patrick Meenan and Andy Davies, HTTP/2 is effectively broken on many CDNs, so we shouldn’t be too optimistic about the performance boost there.

Meet Smashing Book 6 — our brand new book focused on real challenges and real front-end solutions in the real world: from design systems and accessible single-page apps to CSS Custom Properties, CSS Grid, Service Workers, performance, AR/VR and responsive art direction. With Marcy Sutton, Yoav Weiss, Lyza D. Gardner, Laura Elizabeth and many others.

Table of Contents → Assets Optimizations
  1. Use Brotli or Zopfli for plain text compression.
    In 2015, Google introduced Brotli, a new open-source lossless data format, which is now supported in all modern browsers. In practice, Brotli appears to be much more effective than Gzip and Deflate. It might be (very) slow to compress, depending on the settings, but slower compression will ultimately lead to higher compression rates. Still, it decompresses fast. You can also estimate Brotli compression savings for your site.

    Browsers will accept it only if the user is visiting a website over HTTPS though. What’s the catch? Brotli still doesn’t come preinstalled on some servers today, and it’s not straightforward to set up without self-compiling Nginx. Still, it’s not that difficult, and its support is coming, e.g. it’s available since Apache 2.4.26. Brotli is widely supported, and many CDNs support it (Akamai, AWS, KeyCDN, Fastly, Cloudlare, CDN77) and you can enable Brotli even on CDNs that don’t support it yet (with a service worker).

    At the highest level of compression, Brotli is so slow that any potential gains in file size could be nullified by the amount of time it takes for the server to begin sending the response as it waits to dynamically compress the asset. With static compression, however, higher compression settings are preferred.

    Alternatively, you could look into using Zopfli’s compression algorithm, which encodes data to Deflate, Gzip and Zlib formats. Any regular Gzip-compressed resource would benefit from Zopfli’s improved Deflate encoding because the files will be 3 to 8% smaller than Zlib’s maximum compression. The catch is that files will take around 80 times longer to compress. That’s why it’s a good idea to use Zopfli on resources that don’t change much, files that are designed to be compressed once and downloaded many times.

    If you can bypass the cost of dynamically compressing static assets, it’s worth the effort. Both Brotli and Zopfli can be used for any plaintext payload — HTML, CSS, SVG, JavaScript, and so on.

    The strategy? Pre-compress static assets with Brotli+Gzip at the highest level and compress (dynamic) HTML on the fly with Brotli at level 1–4. Make sure that the server handles content negotiation for Brotli or gzip properly. If you can’t install/maintain Brotli on the server, use Zopfli.

  2. Use responsive images and WebP.
    As far as possible, use responsive images with srcset, sizes and the <picture> element. While you’re at it, you could also make use of the WebP format (supported in Chrome, Opera, Firefox 65, Edge 18) by serving WebP images with the <picture> element and a JPEG fallback (see Andreas Bovens' code snippet) or by using content negotiation (using Accept headers). Ire Aderinokun has a very detailed tutorial on converting images to WebP, too.

    Sketch natively supports WebP, and WebP images can be exported from Photoshop using a WebP plugin for Photoshop. Other options are available, too. If you’re using WordPress or Joomla, there are extensions to help you easily implement support for WebP, such as Optimus and Cache Enabler for WordPress and Joomla’s own supported extension (via Cody Arsenault).

    It’s important to note that while WebP image file sizes compared to equivalent Guetzli and Zopfli, the format doesn’t support progressive rendering like JPEG, which is why users might see an actual image faster with a good ol' JPEG although WebP images might get faster through the network. With JPEG, we can serve a "decent" user experience with the half or even quarter of the data and load the rest later, rather than have a half-empty image as it is in the case of WebP. Your decision will depend on what you are after: with WebP, you’ll reduce the payload, and with JPEG you’ll improve perceived performance.

    On Smashing Magazine, we use the postfix -opt for image names — for example, brotli-compression-opt.png; whenever an image contains that postfix, everybody on the team knows that the image has already been optimized. And — shameless plug! — Jeremy Wagner even published a Smashing book on WebP.

The Responsive Image Breakpoints Generator automates images and markup generation.
  1. Are images properly optimized?
    When you’re working on a landing page on which it’s critical that a particular image loads blazingly fast, make sure that JPEGs are progressive and compressed with mozJPEG (which improves the start rendering time by manipulating scan levels) or Guetzli, Google’s new open-source encoder focusing on perceptual performance, and utilizing learnings from Zopfli and WebP. The only downside: slow processing times (a minute of CPU per megapixel). For PNG, we can use Pingo, and for SVG, we can use SVGO or SVGOMG. And if you need to quickly preview and copy or download all the SVG assets from a website, svg-grabber can do that for you, too.

    Every single image optimization article would state it, but keeping vector assets clean and tight is always worth reminding. Make sure to clean up unused assets, remove unnecessary metadata and reduces the amount of path points in artwork (and thus SVG code). (Thanks, Jeremy!)

    There are more advanced options though. You could:

    • Use Squoosh to compress, resize and manipulate images at the optimal compression levels (lossy or lossless),
    • Use the Responsive Image Breakpoints Generator or a service such as Cloudinary or Imgix to automate image optimization. Also, in many cases, using srcset and sizes alone will reap significant benefits.
    • To check the efficiency of your responsive markup, you can use imaging-heap, a command line tool that measure the efficiency across viewport sizes and device pixel ratios.
    • Lazy load images and iframes with lazysizes, a library that detects any visibility changes triggered through user interaction (or IntersectionObserver which we’ll explore later).
    • Watch out for images that are loaded by default, but might never be displayed — e.g. in carousels, accordions and image galleries.
    • Consider Swapping Images with the Sizes Attribute by specifying different image display dimensions depending on media queries, e.g. to manipulate sizes to swap sources in a magnifier component.
    • Review image download inconsistencies to prevent unexpected downloads for foreground and background images.
    • To optimize storage interally, you could use Dropbox’s new Lepton format for losslessly compressing JPEGs by an average of 22%.
    • Watch out for the aspect-ratio property in CSS and intrinsicsize attribute which will allow us to set aspect ratios and dimensions for images, so browser can reserve a pre-defined layout slot early to avoid layout jumps during the page load.
    • If you feel adventurous, you could chop and rearrange HTTP/2 streams using Edge workers, basically a real-time filter living on the CDN, to send images faster through the network. Edge workers use JavaScript streams that use chunks which you can control (basically they are JavaScript that runs on the CDN edge that can modify the streaming responses), so you can control the delivery of images. With service worker it’s too late as you can’t control what’s on the wire, but it does work with Edge workers. So you can use them on top of static JPEGs saved progressively for a particular landing page.
    A sample output by imaging-heap, a command line tool that measure the efficiency across viewport sizes and device pixel ratios. (Image source) (Large preview)

    The future of responsive images might change dramatically with the adoption of client hints. Client hints are HTTP request header fields, e.g. DPR, Viewport-Width, Width, Save-Data, Accept (to specify image format preferences) and others. They are supposed to inform the server about the specifics of user’s browser, screen, connection etc. As a result, the server can decide how to fill in the layout with appropriately sized images, and serve only these images in desired formats. With client hints, we move the resource selection from HTML markup and into the request-response negotiation between the client and server.

    As Ilya Grigorik noted, client hints complete the picture — they aren’t an alternative to responsive images. "The <picture> element provides the necessary art-direction control in the HTML markup. Client hints provide annotations on resulting image requests that enable resource selection automation. Service Worker provides full request and response management capabilities on the client." A service worker could, for example, append new client hints headers values to the request, rewrite the URL and point the image request to a CDN, adapt response based on connectivity and user preferences, etc. It holds true not only for image assets but for pretty much all other requests as well.

    For clients that support client hints, one could measure 42% byte savings on images and 1MB+ fewer bytes for 70th+ percentile. On Smashing Magazine, we could measure 19-32% improvement, too. Unfortunately, client hints still have to gain some browser support. Under consideration in Firefox. However, if you supply both the normal responsive images markup and the <meta> tag for Client Hints, then the browser will evaluate the responsive images markup and request the appropriate image source using the Client Hints HTTP headers.

    Not good enough? Well, you can also improve perceived performance for images with the multiple background images technique. Keep in mind that playing with contrast and blurring out unnecessary details (or removing colors) can reduce file size as well. Ah, you need to enlarge a small photo without losing quality? Consider using Letsenhance.io.

    These optimizations so far cover just the basics. Addy Osmani has published a very detailed guide on Essential Image Optimization that goes very deep into details of image compression and color management. For example, you could blur out unnecessary parts of the image (by applying a Gaussian blur filter to them) to reduce the file size, and eventually you might even start removing colors or turn the picture into black and white to reduce the size even further. For background images, exporting photos from Photoshop with 0 to 10% quality can be absolutely acceptable as well. Ah, and don’t use JPEG-XR on the web — "the processing of decoding JPEG-XRs software-side on the CPU nullifies and even outweighs the potentially positive impact of byte size savings, especially in the context of SPAs".

  2. Are videos properly optimized?
    We covered images so far, but we’ve avoided a conversation about good ol' GIFs. Frankly, instead of loading heavy animated GIFs which impact both rendering performance and bandwidth, it’s a good idea to switch either to animated WebP (with GIF being a fallback) or replace them with looping HTML5 videos altogether. Yes, the browser performance is slow with <video>, and, unlike with images, browsers do not preload <video> content, but they tend to be lighter and smaller than GIFs. Not an option? Well, at least we can add lossy compression to GIFs with Lossy GIF, gifsicle or giflossy.

    Early tests show that inline videos within img tags display 20× faster and decode 7× faster than the GIF equivalent, in addition to being a fraction in file size. Although the support for <img src=".mp4"> has landed in Safari Technology Preview, we are far from it being adopted widely as it’s not coming to Blink any time soon.

    Addy Osmani recommends to replace animated GIFs with looping inline videos. The file size difference is noticeable (80% savings). (Large preview)

    In the land of good news though, video formats have been advancing massively over the years. For a long time, we had hoped that WebM would become the format to rule them all, and WebP (which is basically one still image inside of the WebM video container) will become a replacement for dated image formats. But despite WebP and WebM gaining support these days, the breakthrough didn’t happen.

    In 2018, the Alliance of Open Media has released a new promising video format called AV1. AV1 has compression similar to H.265 codec (the evolution of H.264) but unlike the latter, AV1 is free. The H.265 license pricing pushed browser vendors to adopting a comparably performant AV1 instead: AV1 (just like H.265) compress twice as good as WebP.

    AV1 has good chances of becoming the ultimate standard for video on the web. (Image credit: Wikimedia.org) (Large preview)

    In fact, Apple currently uses HEIF format and HEVC (H.265), and all the photos and videos on the latest iOS are saved in these formats, not JPEG. While HEIF and HEVC (H.265) aren’t properly exposed to the web (yet?), AV1 is — and it’s gaining browser support. So adding the AV1 source in your <video> tag is reasonable, as all browser vendors seem to be on board.

    For now, the most widely used and supported encoding is H.264, served by MP4 files, so before serving the file, make sure that your MP4s are processed with a multipass-encoding, blurred with the frei0r iirblur effect (if applicable) and moov atom metadata is moved to the head of the file, while your server accepts byte serving. Boris Schapira provides exact instructions for FFmpeg to optimize videos to the maximum. Of course, providing WebM format as an alternative would help, too.

    Video playback performance is a story on its own, and if you’d like to dive into it in details, take a look at Doug Sillar’s series on The Current State of Video and Video Delivery Best Practices that include details on video delivery metrics, video preloading, compression and streaming.

Zach Leatherman’s Comprehensive Guide to Font-Loading Strategies provides a dozen options for better web font delivery.
  1. Are web fonts optimized?
    The first question that’s worth asking if you can get away with using UI system fonts in the first place. If it’s not the case, chances are high that the web fonts you are serving include glyphs and extra features and weights that aren’t being used. You can ask your type foundry to subset web fonts or if you are using open-source fonts, subset them on your own with Glyphhanger or Fontsquirrel. You can even automate your entire workflow with Peter Müller’s subfont, a command line tool that statically analyses your page in order to generate the most optimal web font subsets, and then inject them into your page.

    WOFF2 support is great, and you can use WOFF as fallback for browsers that don’t support it — after all, legacy browsers would probably be served well enough with system fonts. There are many, many, many options for web font loading, and you can choose one of the strategies from Zach Leatherman’s "Comprehensive Guide to Font-Loading Strategies," (code snippets also available as Web font loading recipes).

    Probably the better options to consider today are Critical FOFT with preload and "The Compromise" method. Both of them use a two-stage render for delivering web fonts in steps — first a small supersubset required to render the page fast and accurately with the web font, and then load the rest of the family async. The difference is that "The Compromise" technique loads polyfill asynchronously only if font load events are not supported, so you don’t need to load the polyfill by default. Need a quick win? Zach Leatherman has a quick 23-min tutorial and case study to get your fonts in order.

    In general, it’s a good idea to use the preload resource hint to preload fonts, but in your markup include the hints after the link to critical CSS and JavaScript. Otherwise, font loading will cost you in the first render time. Still, it might be a good idea to be selective and choose files that matter most, e.g. the ones that are critical for rendering or that would help you avoiding visible and disruptive text reflows. In general, Zach advises to preload one or two fonts of each family — it also makes sense to delay some font loading if they are less-critical.

    Nobody likes waiting for the content to be displayed. With the font-display CSS descriptor, we can control the font loading behavior and enable content to be readable immediately (font-display: optional) or almost immediately (font-display: swap). However, if you want to avoid text reflows, we still need to use the Font Loading API, specifically to group repaints, or when you are using third party hosts. Unless you can use Google Fonts with Cloudflare Workers, of course. Talking about Google Fonts: consider using google-webfonts-helper, a hassle-free way to self-host Google Fonts. Always self-host your fonts for maximum control if you can.

    In general, if you use font-display: optional, it might not be a good idea to also use preload as it it’ll trigger that web font request early (causing network congestion if you have other critical path resources that need to be fetched). Use preconnect for faster cross-origin font requests, but be cautious with preload as preloading fonts from a different origin wlll incur network contention. All of these techniques are covered in Zach’s Web font loading recipes.

    Also, it might be a good idea to opt out of web fonts (or at least second stage render) if the user has enabled Reduce Motion in accessibility preferences or has opted in for Data Saver Mode (see Save-Data header). Or when the user happens to have slow connectivity (via Network Information API).

    To measure the web font loading performance, consider the All Text Visible metric (the moment when all fonts have loaded and all content is displayed in web fonts), as well as Web Font Reflow Count after first render. Obviously, the lower both metrics are, the better the performance is. It’s important to notice that variable fonts might require a significant performance consideration. They give designers a much broader design space for typographic choices, but it comes at the cost of a single serial request opposed to a number of individual file requests. That single request might be slow blocking the entire typographic appearance on the page. On the good side though, with a variable font in place, we’ll get exactly one reflow by default, so no JavaScript will be required to group repaints.

    Now, what would make a bulletproof web font loading strategy? Subset fonts and prepare them for the 2-stage-render, declare them with a font-display descriptor, use Font Loading API to group repaints and store fonts in a persistent service worker’s cache. You could fall back to Bram Stein’s Font Face Observer if necessary. And if you’re interested in measuring the performance of font loading, Andreas Marschke explores performance tracking with Font API and UserTiming API.

    Finally, don’t forget to include unicode-range to break down a large font into smaller language-specific fonts, and use Monica Dinculescu’s font-style-matcher to minimize a jarring shift in layout, due to sizing discrepancies between the fallback and the web fonts.

Ahoy! The hunt for shiny front-end & UX treasures has begun! Meet SmashingConf San Francisco 2019

Categories: Around The Web

HTML5 SVG Fill Animation With CSS3 And Vanilla JavaScript

Smashing Magazine - Fri, 01/04/2019 - 7:00am
HTML5 SVG Fill Animation With CSS3 And Vanilla JavaScript HTML5 SVG Fill Animation With CSS3 And Vanilla JavaScript Marina Ferreira 2019-01-04T13:00:19+01:00 2019-01-18T21:18:05+00:00

SVG stands for Scalable Vector Graphics and it is a standard XML-based markup language for vector graphics. It allows you to draw paths, curves, and shapes by determining a set of points in the 2D plane. Moreover, you can add twitch properties on those paths (such as stroke, color, thickness, fill, and more) in order to produce animations.

Since April 2017, CSS Level 3 Fill and Stroke Module allow SVG colors and fill patterns to be set from an external stylesheet, instead of setting attributes on each element. In this tutorial, we will use a simple plain hex color, but both fill and stroke properties also accept patterns, gradients and images as values.

Note: When visiting the Awwwards website, the animated note display can only be viewed with browser width set to 1024px or more.

A demo of the final result (Large preview)
Categories: Around The Web

How Much Should You Get Paid To Build Websites In 2019?

Smashing Magazine - Thu, 01/03/2019 - 7:50am
How Much Should You Get Paid To Build Websites In 2019? How Much Should You Get Paid To Build Websites In 2019? Suzanne Scacca 2019-01-03T13:50:00+01:00 2019-01-18T21:18:05+00:00

(This is a sponsored post.) When a business owner is in need of a new website, one of the first answers they’re going to go in search of is: “How much should I pay for a website?”

Most of the articles they’ll find tell business owners that there are a few contributing factors when it comes to pricing:

  • Type of website (e.g. personal blog, small business website, booming e-commerce shop)
  • Size of website
  • Complexity of website

And some say that pricing should differ based on who builds your website (i.e. web designer vs. design agency).

The problem with this answer is that it teaches business owners to think about a website in terms of hours and manpower put into it. As you already know, this leaves many website clients focused on:

“How much work are you gonna do for me?”

Instead of:

“What will be the outcome of this investment?”

As you go out into the world, trying to reverse this faulty logic and convince customers to pay a fair wage for your web design services, you should do some calculations of your own. I’m going to provide you with a number of ways to set your prices and get paid well to create a website in 2019.

Different Ways To Get Paid To Build Websites

There are a few different ways you can get paid to build websites:

  1. Charge an hourly rate
  2. Charge a flat rate
  3. Charge a monthly rate.

There are pros and cons to each option. Let’s review what they are before we take a look at how to come up with a numerical value.

1. Charge An Hourly Rate

In this scenario, you set a value to each hour of work you put in. Then, when the project is done, you bill the client for total hours worked. Sources like Upwork put average hourly freelance rates between $15 and $75 an hour.

Here’s what you need to know about setting an hourly rate that works in both your favor and the client’s:

Client-Friendly (Pro)

As I explained above, many clients expect this form of payment. You put X amount of hours into designing their website and, in exchange, they’ll pay you for every hour worked.

Just remember to employ a time tracker, so you can later provide evidence of how much time was spent on the project (in case they ask for it).

An example of the in-app time tracker from AND CO.

AND CO has a great in-app time tracker that you can also add as a browser extension. What’s especially nice about this is that it integrates with your contract and invoicing software, so you can manage most of your financial relationship with clients in the same place.

Easy to Calculate (Pro)

For many new web designers, charging an hourly rate is an attractive prospect. Since you might not know how long a project will take — especially if it’s a kind you’ve never designed before — you still have an idea of what sort of hourly rate you want to charge.

If you don’t, I’d suggest using this web design calculator from BeeWits:

BeeWits provides a simple design calculator tool to help you determine an hourly

Input the estimated hours for each part of the website you’re contracted to do. Then apply what you think your hourly rate should be.

Take a look at the total. If it looks like a worthy value, commit to it and provide that to your clients.

You can adjust your hourly rate as you take on more projects and get a better sense for how long it actually takes. When Nela Dunato first started out, she reverse-engineered her rates until she was able to find the right sweet spot:

“I charged per-project rates and logged my working hours so I knew what my hourly rate was on each project. At the end of the project I’d compare my actual hourly rate with my desired hourly rate and if it ended up lower I knew that I’d need to charge more on the next project of similar scope.”

If you’re just starting your career as a designer, I’d suggest using a similar approach which is a cross between per-hour rates and per-project rates. Just keep in mind that hourly rates aren’t something you’re required to share with clients. This is for your own edification as you attempt to establish the right flat rate for your services. (More on this below.)

Secure Your Income (Pro)

Web designers have the unfortunate luck of running into clients that want to squeeze as much free work out of them as possible. However, when you agree to an hourly rate with a client, it’s very difficult for them to work their way around it.

Lisa Webster told SkillCrush:

“I’ve worked with too many entrepreneurs who keep adding changes that affect the entire design. This can result in hours of extra work that wouldn’t have been anticipated if you charged them per project.”

So, in a sense, an hourly rate does seem like a smart choice if you have clients trying to get the biggest bang for their buck — all at your expense. (I’ll talk a bit more about this below.)

Just be mindful of what this means for your workflow. As Dunato explains:

“My productivity fluctuates. Sometimes I’m very inspired and I get things done super quick, and sometimes it takes me more time to complete a project. This has nothing to do with the client, so they shouldn’t pay me more or less based on that.”

So, while an hourly rate might protect you from overzealous clients, it could unintentionally cause a strain on the relationship you have with them if pricing is based on your current productivity levels.

Micro-Managing Clients (Con)

Although there are clear benefits to charging an hourly rate, there is a tradeoff which I hinted at earlier. In other words:

When clients associate a website with the hourly work put into it, they fail to see the value of it.

In turn, this puts a lot of pressure on you in the wrong way.

For instance, you’ll find that clients become super cognizant of the time you’re spending on something. When they see that beautiful mockup you’ve created for them, one of the first things they’ll ask is:

“How much time did you spend on this?”

This detracts from having more meaningful conversations that they’d otherwise initiate if they weren’t so focused on what you’re billing them.

Then, there are the inevitable interruptions that arise when you have to stop working to respond to clients who want to know what their total bill is to date. Worse, they might go the route of doubting how truthful you’re being:

“My nephew built a website for his team and he said it only took 8 hours. Why am I paying you for 50 hours if he can do it in a fifth of the time?”

You also might encounter clients who decide to cherry-pick what’s included in their website. Rather than allow you to develop a website from start to finish, you’ll end up committing to fractions of the website work which will lead to a disjointed experience on the frontend when the design conflicts with the copy and the SEO was dropped from the scope completely. (You get the idea.)

Earning Potential Cap (Con)

You have to be very careful about the hourly rate you charge for a website. While you might be okay with profit margins that come from a $30/hour rate… is it sustainable?

Think about it like this: You’re trying to be mindful of your clients. You know they need websites. You know they’re probably strapped for cash. And you don’t want to scare anyone away with high rates. So you compromise. $30 an hour will still net you a good chunk of change.

That said, when your business model is contingent on how much work you put into a website, that limits your earning potential. Let’s say you’re willing to work 50 hours a week and are able to bill clients for about 40 of it (the rest of the time is spent on business management).

40 hours × $30/hour = $1,200/week

That’s it. That is all the money you will ever be able to make.

If you choose to automate your workflows with software to free up time to work on more projects simultaneously, that reduces the number of billable hours you can charge. Automation just doesn’t work with this business model.

That said, I do think this is a viable option for new web designers. Until you have made a name for yourself, have an impressive portfolio to show off as well as clients who’ve given you rave reviews, it’ll be difficult to charge clients any other way. Just be careful with how much you set that hourly rate for.

2. Charge A Flat Rate

In this scenario, you charge a single flat rate for web design. You can also create a tier of web design packages that allow you to charge varying flat fees based on website type.

WebsiteSetup estimates these rates to be:

  • Between $1,000 and $3,000 for solo freelancers.
  • Between $10,000 and $15,000 for full-scale design agencies.

Here’s what you need to know to find your perfect flat rate:

Focus On Value (Pro)

The clear differentiator between charging website clients per hour and charging a flat rate is the mindset — both for you and the client. Instead of obsessing over how many hours went into the building of a website, both of you remain focused on the ultimate value of the product.

Because the client has a clearer understanding that they’re paying for the outcome, you can charge more as well.

Study Web Development breaks this logic down nicely:

“[I]f the business sells an average of ten 3D printers at an average of $2,000 each per month… and after calculating that I could potentially increase sales by 30% month after month, it then equals an extra three sales per month (or $6,000).”

In other words, your rate must reflect the true value of the website to the client.

That’s not to say you would charge $6,000 (in this specific case) and call it a day. You should think about what sort of ROI they’re going to get. Decide on a flat rate that reflects that and commit to it.

Faster Sales Process (Pro)

You’re not just a web designer. You’re also in charge of finding prospects and convincing them to become clients.

When you charge clients an hourly rate, you could certainly publish it to your website. But it leaves the matter open-ended, right? You might be able to say your web design services go for $100/hour… but they’re still going to want an idea of the invoice they can expect at the end.

Drawing up custom quotes for prospective clients takes time — time away from makes sales and designing websites. Rather than get wrapped up in the quoting process where prospects take their time looking over the numbers and question why certain parts of it would take so long (and whether they’re needed), a flat rate simplifies all of this.

Here is an example from Connective Web Design:

Connective Web Design simplifies pricing with flat rates

As you can see here, website types are explained in the most basic of terms (the ones that matter most to clients) and then a clear value is assigned to them. Clients also have the option to add more to the website, if they feel it’s necessary.

For those of you who are nervous about publishing your rates online, that’s okay. You don’t have to.

You can still charge flat rates — and the same ones for certain website types — even if it’s not publicly available. Just create a pricing sheet that you can send to prospects that inquire about your services.

Efficiency (Pro)

Because you’re not tied to the expectation that you’ll put in a certain number of hours in exchange for X amount of dollars, you can utilize more efficient ways of designing websites.

To start, you can templatize your workflow. You can do this with everything from communications you send to clients (e.g. contracts and emails) to the baseline frameworks you build websites from (like sitemaps and wireframes).

Smashing Magazine is an example of a source that provides templates and design kits that ease the amount of work designers have to do from-scratch:

Smashing Magazine offers free design templates and sets for designers to use.

Basically, anything that doesn’t require creativity and is repetitive in nature can be turned into a template.

You should also look for ways to offload menial and ill-fitting tasks. Anything that would be better handled by software should be automated. Anything else that doesn’t belong on your plate (maybe copywriting, QA and so on) should be outsourced to a team member or a third-party provider.

There are a number of benefits to this:

  1. You’ll maximize your efforts and be able to boost profit margins as you spend less money but accomplish more.
  2. You’ll enjoy the work you do because you won’t be tied down to tasks that don’t belong on your plate. Your happiness will have a direct impact on the quality of work you produce.
  3. As you delegate tasks to others and automate with software, you can multiply your efforts and take on more website projects simultaneously. Which means more money for you!
It Takes Time (Con)

Charging a flat rate to build websites is the best way to run and scale a design business. That said, it will be difficult to convince clients to pay that much if you don’t have enough experience behind you and proof to back it up.

Unlike hourly rates that are great for newer designers, this approach is one you probably can’t jump into right away.

That said, if you’re bringing extensive experience with you from a well-known design agency or another business and can demonstrate that you have the skills to meet client expectations, go for it. Just be aware that you’re more likely to face pushback if your business isn’t ready for it.

Scope Creep (Con)

Inevitably, you’re going to encounter clients that want you to do more without them having to pay for it. Some of them will be more blatant than others, asking how much you’re willing to give away in order to earn or retain their business.

Then, there are others who try a subtler approach.

“I really love Version 3 [of the design], but was wondering if you could add a live chat button to the bottom corner real quick. I saw another website that had it and I thought it looked great. Our customers would love it!”

That request, in and of itself, is not a problem. What is a problem is how you handle it.

If you have no contract in place, seemingly small changes like these can add up and eat away at your profit margins. Without a contract that limits how many revision requests are allowed or what exactly you’re to build, clients can technically ask for whatever they want and you’d have no recourse for charging more.

Now, let’s say you do have a contract in place. The terms of that agreement lay out what you are obligated to do. However, it’s an issue when you agree to make “small” changes that exceed those terms that it becomes an issue.

Even though the client has made it seem easy enough to add a button to the design, that button actually has to function on the website… which means they’re asking for much more than a design tweak. You now have to find a live chat platform, pay for it, integrate it with the site and make sure the button works properly.

Give a client an inch and they’ll run a mile with it. So, always make sure you have a strict contract in place and be willing to enforce those terms when clients try to push the limits of it.

3. Charge A Monthly Rate

In this scenario, you charge a flat rate, but it’s for a recurring web design service; not just a one-off build. The pros and cons of this are essentially the same as charging a flat, one-time fee.

The key difference is that this allows you to retain clients over the long-term — which is fantastic for creating a steady stream of predictable revenue for your business.

In terms of why you would do this, consider the following:

There are DIY website solutions like Wix and Weebly that appear to make the process of building one’s own site easy and cheap.

Then, there are traditional content management systems like WordPress that are more and more going the way of the user-friendly page builder, hoping to appeal to a larger set of users.

WordPress has recently implemented a more user-friendly page builder.

It’s already hard enough trying to convince clients that they need to hire a professional designer and to pay them a fair wage to build a website. Now, page builder tools are telling them that they really don’t need you.

That said, if you become an end-to-end website provider, you can not only charge a flat rate for your design services, you can do so month after month. It would simply require a shift in mindset from you, an adjustment to your branding and advertising, as well as some additional services.

In terms of how you would do this, consider offering a total solution so they don’t have to go anywhere else. The added convenience of entrusting all website-related matters to one professional could be the tipping point between you and the other options.

Think about rounding out your offering with:

  • Domain and web hosting management
  • SSL installation
  • CDN implementation
  • Premium theme licensing
  • Premium plugins licensing
  • Third-party storage services
  • Website maintenance
  • Marketing and SEO

You would also want ongoing web design edits and annual design audits to be a part of your ongoing service

Just as you would do with flat-rate design services, you could outsource items above that aren’t in your wheelhouse to others. Then, add a markup to the price when you sell the website package to the client. You’re still making money without having to increase your workload.

As you might imagine, this option for getting paid is for the experienced designer who has everything else in order and is in a position to comfortably shift their offering to one of greater value.

How To Decide How Much To Charge For Websites

Finally, we come to the valuation of your web design services.

Ask yourself the following in order to determine your best rate:

What kinds of websites are you capable of building?

Put them into buckets:

  • Small blogs,
  • Small- to medium-sized company websites,
  • Small- to medium-sized digital e-commerce stores,
  • Large e-commerce stores with physical and digital products,
  • Large e-commerce stores with brick-and-mortar presences,
  • Membership sites,
  • And so on.

Choose no more than three types to build. Then, break down how many pages as well as the key features you will need to build. This should tell you how much work is involved in creating a website of this nature. You can determine basic timelines and “manpower” based on this.

Who is your target client?

This is a slightly different question as it forces you to ask yourself who exactly you want to work for. This might mean defining a business by its size or it might mean choosing a niche industry to work in.

Either way, figure out who you want to build sites for and make sure they can afford your rates. (Check the competition’s rates to get an idea for what price range they’re willing to pay in.) If they can’t afford what you want to charge, they might be better off with the DIY approach and you should look for a new pool to play in.

How will these websites convert?

This is where the value question comes into play. In other words, what will your clients expect these websites to do for them:

  • Subscribe readers?
  • Schedule demos with prospective customers?
  • Sell goods?
  • Gain members?
  • Make money through advertising?
  • Something else?

You might not know exactly how much of a boost in conversions a new website will lead to, but you can estimate how much each new conversion is worth to them.

These three questions help you determine how much you should get paid to build websites. But there’s one more thing to think about:

“What do you have to spend to make this happen?”

You’re providing a valuable service here, but you’re not doing it all on your own, from a 10-year-old computer and in a rent-free apartment.

You have bills to pay that enable you to run your business in a way that leads to the top results you bring to clients. As such, you have to factor in your costs when determining the cost of your services.

The Bottom Line

Ultimately, it’s up to you to decide what monetary value you want to sign to your web design rates. However, if you want to remain competitive within the space, make sure to charge within one of the estimated ranges mentioned earlier — at least, to start. Then, as your business grows, you can steadily raise your prices in line with the increasing value of the websites you build.

(ms, ra, il)
Categories: Around The Web

How To Learn CSS

Smashing Magazine - Wed, 01/02/2019 - 7:00am
How To Learn CSS How To Learn CSS Rachel Andrew 2019-01-02T14:00:30+02:00 2019-01-18T21:18:05+00:00

I get a lot of people asking me to recommend to them tutorials on various parts of CSS, or asking how to learn CSS. I also see a lot of people who are confused about bits of CSS, in part because of outdated ideas about the language. Given that CSS has changed quite substantially in the last few years, this is a really good time to refresh your knowledge. Even if CSS is a small part of what you do (because you work elsewhere in the stack), CSS is how things end up looking as you want them on screen, so it is worth being reasonably up to date.

Therefore, this article aims to outline the key fundamentals of CSS and resources for further reading on key areas of modern CSS development. Many of those are things right here on Smashing Magazine, but I’ve also selected some other resources and also people to follow in key areas of CSS. It’s not a complete beginner guide or intended to cover absolutely everything. My aim is to cover the breadth of modern CSS with a focus on a few key areas, that will help to unlock the rest of the language for you.

Language Fundamentals

For much of CSS, you don’t need to worry about learning properties and values by heart. You can look them up when you need them. However, there are some key underpinnings of the language, without which you will struggle to make sense of it. It really is worth dedicating some time to making sure you understand these things, as it will save you a lot of time and frustration in the long run.

Front-end is messy and complicated these days. That's why we publish articles, printed books and webinars with useful techniques to improve your work. Even better: Smashing Membership with a growing selection of front-end & UX goodies. So you get your work done, better and faster.

Explore Smashing Membership ↬ Selectors, More Than Just Class

A selector does what it says on the tin, it selects some part of your document in order that you can apply CSS rules to it. While most people are familiar with using a class, or styling an HTML element such as body directly, there are a large number of more advanced selectors which can select elements based on their location in the document, perhaps because they come directly after an element, or are the odd rows in a table.

The selectors that are part of the Level 3 specification (you may have heard them referred to as Level 3 selectors) have excellent browser support. For a detailed look at the various selectors you can use, see the MDN Reference.

Some selectors act as if you had applied a class to something in the document. For example p:first-child behaves as if you added a class to the first p element, these are known as pseudo-class selectors. The pseudo-element selectors act as if an element was dynamically inserted, for example ::first-line acts in a similar way to you wrapping a span around the first line of text. However it will reapply if the length of that line changes, which wouldn’t be the case if you inserted the element. You can get fairly complex with these selectors. In the below CodePen is an example of a pseudo-element chained with a pseudo-class. We target the first p element with a :first-child psuedo-class, then the ::first-line selector selects the first line of that element, acting as if a span was added around that first line in order to make it bold and change the color.

See the Pen first-line by Rachel Andrew (@rachelandrew) on CodePen.

Inheritance And The Cascade

The cascade defines which rule wins when a number of rules could apply to one element. If you have ever been in a situation where you can’t understand why some CSS doesn’t seem to be applying, it’s likely the cascade is tripping you up. The cascade is closely linked to inheritance, which defines which properties are inherited by the child elements of the element they are applied to. It is also linked to specificity; different selectors have different specificity which controls which wins when there are several selectors which could apply to one element.

Note: To get an understanding of all of these things, I would suggest reading The Cascade and Inheritance, in the MDN Introduction to CSS.

If you are struggling with getting some CSS to apply to an element then your browser DevTools are the best place to start, take a look at the example below in which I have an h1 element targeted by the element selector h1 and making the heading orange. I am also using a class, which sets the h1 to rebeccapurple. The class is more specific and so the h1 is purple. In DevTools, you can see that the element selector is crossed out as it does not apply. Once you can see that the browser is getting your CSS (but something else has overruled it), then you can start to work out why.

See the Pen specificity by Rachel Andrew (@rachelandrew) on CodePen.

DevTools can help you see why some CSS is not applying to an element (Large preview) The Box Model

CSS is all about boxes. Everything that is displayed on the screen has a box, and the Box Model describes how the size of that box is worked out — taking into account margins, padding, and borders. The standard CSS Box Model takes the width that you have given an element, then adds onto that width the padding and border — meaning that the space taken up by the element is larger than the width you gave it.

More recently, we have been able to choose to use an alternate box model which uses the given width on the element as the width of the visible element on screen. Any padding or border will inset the content of the box from the edges. This makes a lot more sense for many layouts.

In the demo below, I have two boxes. Both have a width of 200 pixels, with a border of 5 pixels and padding of 20 pixels. The first box uses the standard box model, so takes up a total width of 250 pixels. The second uses the alternate box model, so is actually 200 pixels wide.

See the Pen box models by Rachel Andrew (@rachelandrew) on CodePen.

Browser DevTools can once again help you with understanding the box model in use. In the below image, I use Firefox DevTools to inspect a box using the default content-box box model. The tools tell me this is the Box Model in use, and I can see the sizing and how the border and padding is added to the width I assigned.

DevTools help you see why a box is a certain size, and the box model in use (Large preview)

Note: Prior to IE6, Internet Explorer used the alternate Box Model, with padding and borders insetting content away from the given width. So for a while browsers used different Box Models! When frustrated by interoperability issues today, be glad that things have improved so we aren’t dealing with browsers calculating the width of things differently.

There is a good explanation of the Box Model and Box Sizing on CSS Tricks, plus an explanation of the best way to globally use the alternate box model in your site.

Normal Flow

If you have a document with some HTML marking up the content and view it in a browser, it will hopefully be readable. Headings and paragraphs will start on a new line, words display as a sentence with a single white space between them. Tags for formatting, such as em, do not break up the sentence flow. This content is being displayed in Normal Flow, or Block Flow Layout. Each part of the content is described as “in flow”; it knows about the rest of the content and so doesn’t overlap.

If you work with rather than against this behavior, your life is made much easier. It is one of the reasons why starting with a correctly marked up HTML document makes a lot of sense, as due to normal flow and the inbuilt stylesheets that browsers have which respect it, your content starts from a readable place.

Formatting Contexts

Once you have a document with content in normal flow, you may want to change how some of that content looks. You do this by changing the formatting context of the element. As a very simple example, if you wanted all of your paragraphs to run together and not start on a new line, you could change the p element to display: inline changing it from a block to an inline formatting context.

Formatting contexts essentially define an outer and an inner type. The outer controls how the element behaves alongside other elements on the page, the inner controls how the children should look. So, for example, when you say display: flex you are setting the outer to be a block formatting context, and the children to have a flex formatting context.

Note : The latest version of the Display Specification changes the values of display to explicitly declare the inner and outer value. Therefore, in the future you might say display: block flex; (block being the outer and flex being the inner).

Read more about display over at MDN.

Being In Or Out Of Flow

Elements in CSS are described as being ‘in flow’ or ‘out of flow.’ Elements in flow are given space and that space is respected by the other elements in flow. If you take an element out of flow, by floating or positioning it, then the space for that element will no longer be respected by other in flow items.

This is most noticeable with absolutely positioned items. If you give an item position: absolute it is removed from flow, then you will need to ensure that you do not have a situation in which the out of flow element overlaps and makes unreadable some other part of your layout.

See the Pen Out of Flow: absolute positioning by Rachel Andrew (@rachelandrew) on CodePen.

However, floated items also are removed from flow, and while following content will wrap around the shortened line boxes of a floated element, you can see by placing a background color on the box of the following elements that they have risen up and are ignoring the space used by the floated item.

See the Pen Out of flow: float by Rachel Andrew (@rachelandrew) on CodePen.

You can read more about in flow and out of flow elements on MDN. The important thing to remember is that if you take an element out of flow, you need to manage overlap yourself as the regular rules of block flow layout no longer apply.

Layout

For over fifteen years we have been doing layout in CSS without a designed for the job layout system. This has changed. We now have a perfectly capable layout system which includes Grid and Flexbox, but also Multiple-column Layout and the older layout methods used for their real purpose. If CSS Layout is a mystery to you, head on over to the MDN Learn Layout tutorial, or read my article Getting Started With CSS Layout here on Smashing Magazine.

Do not imagine that methods such as grid and flexbox are somehow competing. In order to use Layout well, you will sometimes find a component is best as a flex component and sometimes as Grid. On occasion, you will want the column flowing behavior of multicol. All of these are valid choices. If you feel you are fighting against the way something behaves, that is, in general, a very good sign that it might be worth taking a step back and trying a different approach. We are so used to hacking at CSS to make it do what we want that we are likely to forget that we have a number of other options to try.

Layout is my main area of expertise and I’ve written a number of articles here on Smashing Magazine and elsewhere to try and help tame the new Layout landscape. In addition to the Layout article mentioned above, I have a whole series on Flexbox — start with What Happens When You Create a Flexbox Flex Container. On Grid By Example, I have a whole bunch of small examples of CSS Grid — plus a video screencast tutorial.

In addition — and especially for designers — check out Jen Simmons and her Layout Land video series.

Alignment

I’ve separated Alignment out from Layout in general because while most of us were introduced to Alignment as part of Flexbox, these properties apply to all layout methods, and it is worth understanding them in that context rather than thinking about “Flexbox Alignment” or “CSS Grid alignment.” We have a set of Alignment properties which work in a common way where possible; they then have some differences due to the way different layout methods behave.

On MDN, you can dig into Box Alignment and how it is implemented for Grid, Flexbox, Multicol, and Block Layout. Here on Smashing Magazine, I have an article specifically covering alignment in Flexbox: Everything You Need To Know About Alignment In Flexbox.

Sizing

I spent much of 2018 speaking about the Intrinsic and Extrinsic Sizing specification, and how it relates to Grid and Flexbox in particular. On the web, we are used to setting sizing in lengths or percentages, as this is how we have been able to make Grid-type layouts using floats. However, modern layout methods can do a lot of the space distribution for us — if we let them. Understanding how Flexbox assigns space (or the Grid fr unit works), is worth your time.

Here on Smashing Magazine, I’ve written about Sizing in Layout in general and also for Flexbox in How Big Is That Flexible Box?.

Responsive Design

Our new layout methods of Grid and Flexbox often mean that we can get away with fewer media queries than we needed with our older methods, due to the fact that they are flexible and respond to changes in viewport or component size without us needing to change the widths of elements. However, there will be places where you will want to add in some breakpoints to further enhance your designs.

Here are some simple guides to Responsive Design, and for media queries, in general, check out my article Using Media Queries for Responsive Design in 2018. I take a look at what Media Queries are useful for, and also show the new features coming to Media Queries in Level 4 of the spec.

Fonts And Typography

Along with Layout, the use of fonts on the web has undergone huge change in the last year. Variable Fonts, enabling a single font file to have unlimited variations, are here. To get an overview of what they are and how they work, watch this excellent short talk from Mandy Michael: Variable Fonts and the Future of Web Design. Also, I would recommend Dynamic Typography With Modern CSS and Variable Fonts by Jason Pamental.

To explore Variable Fonts and their capabilities, there is a fun demo from Microsoft plus a number of playgrounds to try out Variable Fonts — Axis Praxis being the most well known (I also like the Font Playground).

Once you start working with Variable Fonts, then this guide on MDN will prove incredibly useful. To learn how to implement a fallback solution for browsers which does not support Variable Fonts read Implementing a Variable Font With Fallback Web Fonts by Oliver Schöndorfer. The Firefox DevTools Font Editor also has support for working with Variable Fonts.

Transforms And Animation

CSS Transforms and Animation are definitely something I look up on a need-to-know basis. I don’t often need to use them, and the syntax seems to hop right out of my head between uses. Thankfully, the reference on MDN helps me out and I would suggest starting with the guides on Using CSS Transforms and Using CSS Animations. Zell Liew also has a nice article that provides a great explanation to CSS transitions.

To discover some of the things that are possible, take a look at the Animista site.

One of the things that can be confusing about animations, is which approach to take. In addition to what is supported in CSS, you might need to involve JavaScript, SVG, or the Web Animation API, and these things all tend to get lumped together. In her talk, Choose Your Animation Adventure recorded at An Event Apart, Val Head explains the options.

Use Cheatsheets As A Reminder, Not A Learning Tool

When I mention Grid or Flexbox resources, I often see replies saying that they can’t do Flexbox without a certain cheatsheet. I have no problem with cheatsheets as a memory helper to look up syntax, and I’ve published some of my own. The problem with entirely relying on those is that you can miss why things work as you copy syntax. Then, when you hit a case where that property seems to behave differently, that apparent inconsistency seems baffling, or a fault of the language.

If you find yourself in a situation where CSS seems to be doing something very strange, ask why. Create a reduced test case that highlights the issue, ask someone who is more familiar with the spec. Many of the CSS problems I am asked about are because that person believes a property works in a different way to the way it works in reality. It’s why I talk a lot about things like alignment and sizing, as these are places where this confusion often lives.

Yes, there are strange things in CSS. It is a language that has evolved over the years, and there are things about it that we can’t change — until we invent a timemachine. However, once you have some basics down, and understand why things behave as they do, you will have a much easier time with the trickier places.

(il)
Categories: Around The Web

2018: A Smashing Year In Review

Smashing Magazine - Mon, 12/31/2018 - 8:00am
2018: A Smashing Year In Review 2018: A Smashing Year In Review Rachel Andrew 2018-12-31T14:00:30+01:00 2019-01-18T21:18:05+00:00

As we come to the end of 2018, I spoke to some of the Smashing team, to get some thoughts on what the past year has been like for Smashing Magazine. We’re a small and fully remote team, communicating via Slack and Notion. Many of us only work part-time for Smashing, however, in many ways, I think that is one of our strengths.

We’re not just the publishers of an online magazine or conference organizers, we are people who work in the web industry. Among the team, products have been launched, books are being written, conferences have been spoken at, and websites launched that have nothing to do with Smashing Magazine itself. I love that. It stops us being insular, and I hope this helps us to constantly broaden our reach — bringing people together from all over the world to share ideas and inspiration as we all work together to build a better web.

As Editor in Chief of Smashing Magazine, I look after the content that goes out on the online magazine, and also our upcoming print magazine for members. This year, we have published almost every weekday — that represents over 290 articles! That’s a whole lot of content on subjects from privacy and accessibility to CSS and WordPress. While I read every article that goes out, I do not have the expertise to know everything about all of these subjects. I couldn’t do my job without the help of our talented editors who work with individual authors: Alma Hoffmann (Design), Chui Chui Tan (UX Design), Drew McLellan (Coding), Jim Dabell (Mobile), Marko Dugonjić (Typography), Michel Bozgounov (Graphics), and Rey Bango (Coding). Plus thanks to Iris Lješnjanin, Markus Seyfferth, Yana Kirilenko, Cosima Mielke, Andrew Lobo and Ricardo Gimenes for their hard work and efforts.

In Between Timezones

On a personal note, this year has once again involved a lot of travel, as I continue to tour around speaking about new CSS and CSS Layout. That has included talks and workshops for Smashing. In total (with speaking engagements, workshops and CSS Working Group meetings), I have traveled 272,865 kilometers while visiting 45 cities and 15 countries. That amounts to spending 146 days on the road.

Here’s a fun fact: My weekly standup post in our Smashing Slack usually starts with sharing the timezones I’m going to be in that week. Well, next year will involve more travel, and I’ll be bringing my new CSS Layout workshop to San Francisco, Toronto, and New York.

As for the magazine, I hope we can continue to publish great content from authors — those who are experienced writers but also folks writing for the first time. We are very happy to work with you to shape an article for publication. Personally, writing has helped boost my career more than anything else I have done. I love to help other people get started. So, if you have an idea, read this and then send over an outline.

Please don’t hesitate. Some of our most popular posts have been beginner guides to a technology, so don’t feel you need to have solved a big problem, or have some brand new technique in order to contribute. A nice technique, demonstrated and explained well, is worth a lot to someone who has just hit that same issue.

Anyway, enough from me! What were the highlights of the year for everyone else here at Smashing?

Vitaly Friedman: A Transitional Year

2018 was a quite busy and adventurous year for me, with a good number of ups and downs, challenges, surprises, and rewards. I was honored to have had the opportunity to run trainings, workshops and even offer consultancy to the European Parliament, EPAM, OTTO, Sipgate, Axel Springer and Wondrous, among others. I was happy to support dozens of local meet-ups and conferences around the world with the kind help of our Smashing Members.

Earlier this year, I explored how we can improve the level of education for front-end and design. While speaking at universities and schools, I was also teaching to get a sense of what’s required to set up a proper design school. In February, I taught at the New Digital School in Porto, Portugal, for a week, while exploring the state of front-end and responsive interface design in a class of 20 students. In June, I helped dear friends from the Projector Design School in Kyiv, Ukraine, set up Berlin Design Campus, an initiative for Ukrainian students to explore how digital agencies and designers work and live in Berlin. In October, I participated in a week-long co-working co-living campus in Mokrin, Serbia.

Specifically, I was exploring the state of design and front-end in uncommon locations, mostly second- and third-largest cities: Porto and Braga in Portugal (thanks Tiago!), Yerevan in Armenia (thanks Sona and Sargis!), Gdansk in Poland (thanks Patrycja!), Salzburg in Austria (thanks Markus!), Moscow and Saint Petersburg in Russia (thanks Julia, Daria, Alex, Andrey, Vadim and Alexey!), Split and Labin in Croatia (thanks Toni, Antonio and Domagoj!), Belgrade and Mokrin in Serbia (thanks Tatjana and Marija!), Belfast in Northern Ireland (thanks Tash and Oliver!), Manila in Philippines (thanks Sophia!), Tallinn in Estonia (thanks Artur!).

Much of the time in the second half of the year was spent with wonderful people at the European Parliament in Brussels, where Nicolas and Manuel were kind enough to invite me to work on refinements and improvements of UIs for election sites, media library, and a few smaller sites. That was quite a bit of traveling, with the absolute worst highlight of the last years being a massively delayed 47-hour trip to the Philippines due to a closed runway at the Manila airport (thanks for bearing with me through this, dear Sophia and the crew!)

Over the course of the year, I have spoken at 17 conferences, and was privileged to meet many — many! — remarkable people. It ended up with conversations I will remember for years to come. Some of these conversations changed me for the better as a person and professional, so I was happy to receive constructive criticism on MCing skills, writing, as well as code and design. I managed to wrap my head around the intricacies of CSS Grid Layout and Service Workers but also spent a lot of time learning about network protocols and the underlying layers of the Internet. I also attended 6 workshops to stay afloat of what’s happening in our industry these days and sharpened up my front-end/UX/communication skills. In September, I was honored to participate in the Mozilla Tech Speakers coaching, along with Ada Rose Edwards and Marc Thiele, mentoring and giving feedback to dozens of new speakers (here’s a review of the event by Havi Hoffman).

In terms of the Smashing Universe, we spent quite a bit of time revising our workflows and streamlining our processes for conferences, books, and the Smashing Membership. With fantastic event management skills of Mariona Ciller, Amanda Tamny Annandale and Charis Rooda, we’ve run 5 conferences this year: in London, San Francisco, Toronto, Freiburg and New York.

For the first time, we experimented with a ’no-slides’ format in Toronto (every speaker presented “live” on stage in front of a large screen shwoing how they build and design — with performance and accessibility audits to live designing/coding/sketching sessions on stage. In fact, that’s the format we are going to continue exploring in 2019.

Editor’s Note: If this format sounds interesting to you, you can watch all of the SmashingConf talks on Vimeo.

Nadieh Bremer presenting at SmashingConf Toronto (watch on Vimeo)

After many months of work, we finally published “Smashing Book 6” and “Form Design Patterns” by Adam Silver, but quite a bit of time was spent on the next upcoming books that will be published in the next years. For the Membership, we were able to secure Scott Whitehead and Bruce Lawson to help evolve the Membership program.

On a more personal level, I will vividly remember vacations to Morocco (Marrakesh, Fez and the Sahara desert trip) and Sardinia (Northern part) earlier this year. Also, on a sad note, I’ve moved out from Vilnius, Lithuania, where I’ve resided for the past 3 years.

Overall, I see 2018 as an important “transitional” year which took a lot of time, effort, and hard work. It feels like it’s been a transitional year between how things used to be and what’s coming up next. With this in mind, I couldn’t be more excited to see what 2019 will bring us! Expect a few new books coming up, Smashing Magazine Print edition, four Smashing Conferences (San Francisco, Toronto, Freiburg, New York) and many wonderful Smashing TV sessions!

Markus Seyfferth: Never Stand Still

Change happens everywhere and all the time — in all organizations, agencies, and businesses. If you don’t thrive change on your own, then there comes a time when change takes place on its own and things get out of control.

Looking back on the year 2018, we’ve undergone changes to even better fit the needs of our readers. We published the Smashing Book 6: New Frontiers in Web Design, a book packed into the probably the most beautiful cover that we have had designed so far. It’s a book that sheds light on all kinds of upcoming challenges that await web designers and developers in the near future.

Smashing Book 6 (photo credit Marc Thiele)

We also published Form Design Patterns, a book that focusses on building all sorts of accessible and resilient web forms, and how to make them pretty (thanks to progressive enhancement) — a book that I personally learned a lot from. We’ve also started working on two new books that we’ll be publishing early next year: “Art Direction on the Web” by Andy Clarke, and “Inclusive Components” by Heydon Pickering. I am eagerly looking forward to holding both of them in my hands!

At the end of last year, we did something that we usually wouldn’t do because it would be too much of a risk. We launched a fully redesigned site: we migrated the entire magazine, the Job Board, and our Smashing Shop onto a new platform, and also launched our Membership initiative to reduce advertising on the site and to make Smashing more independent from ads in the long run. All of this took place at the same time. Was it worth it? A definite “Yes!” We’ve seen a noticeable uptrend in our analytics and many positive outcomes. At around mid-2018, we had already crossed the 1,000 members mark, and we look forward to breaking the next big mark in the next year (always with the long-term goal of getting fully independent within the next three years)!

That’s right; Smashing Membership continues to evolve. In the upcoming months, we’ll be introducing a new print magazine for our Members — something that is both visually appealing and also most useful to read. Rachel will be building the print magazine mostly with print.css, so I’m really looking forward to seeing how this will turn out and whether we can reuse some of it for our upcoming books!

And that’s not the only sort of change that is still ongoing at Smashing. We also tried a new live coding and design conference format at this year’s SmashingConf in Toronto; we thought that the old format had gotten a bit too much of the same, something that makes SmashingConf a bit too similar with what others already do. After all, we want to run conferences that contain content that we ourselves find most useful and interesting, and the new live format brings precisely that! It did take quite a bit of a risk though, and we’re thrilled that it turned out to be a tremendous success! So we are going to double down with this new format in the next year.

Last but not least, we also moved our smashingconf.com site to Netlify just recently, but that happened mostly in the background, so if no one really noticed the change, I guess that’s a good thing.

Yes, 2018 was a year full of transitions, but I guess you never can afford to stand still anyway? ;-)

Bruce Lawson: Joining The Team

Before the end of the first year of Smashing Membership, we reached a thousand members — thank you so much, everyone! Those extra-special people who were with us for the whole year received a little thank you in the post.

I joined Scott in October, which allowed us to increase the number of Smashing TV webinars (which are free to Members and Smashing Members, of course). We’ve had sessions on coding Machine Learning, Designing with Ethics, the State of the Web in South-East Asia, and statistical techniques for collecting user data without compromising privacy. (All are recorded and available to members, if you have FOMO!)

When we set up Membership, we promised that it would be an inclusive place where lesser-heard voices (in addition to big names) would be beamed straight to your living room/ home office/ sauna over Smashing TV. While we’ve been speaking at other non-Smashing events, we’ve watched other sessions from lesser-known talents in our industry. With only $5 to $9 a month, your Membership subscription allows us to bring you even greater content, pay all our contributors fairly, and reduce advertising on the site.

Next year, we’ll be increasing the number of webinars again. Lined up is a course on how to make Progressive Web Apps, Internationalization, Semantic HTML, Houdini, as well as a monthly show hosted by me and Vitaly with industry guests. We sincerely hope you’ll join us!

Amanda Annandale: A Year Of Firsts

2018 was a year of firsts, new cities, new attendees, new speakers, and even a couple new formats. We had more than a few challenges in store, but if you have any experience with the Smashing Team, you’ll know that we thrive on challenges.

We started the year in London (our first time in the capital city and the first time in England in a couple of years). The sold-out conference took place in LSO’s St. Luke’s Church, and bathed in sunlight. This performance-based conference brought in a new crowd of attendees and speakers — all discussing why Performance Matters, the common pitfalls, and the tips and tricks for improving the day to day user experience. With Una Kravets and Patrick Hamman as MCs, the experience was new and empowering.

In April, the Smashing team headed back to San Francisco. The weather was wonderful as we returned to the bay, with 14 speakers, 8 workshops, and nearly 500 attendees. Held at the Palace of Fine Arts, Mina Markham walked us through the process of redesigning Slack, while Joe Leech broke down the process of “Designing Powerful User Experiences With Psychology.” We toured the area, competed with each other at the arcade, and came together to find new ways to solve new processes and challenges.

Backstage at Smashing Conf Toronto (Photo credit: Marc Thiele)

A couple of months later, SmashingConf experimented with its boldest change: no slides! All of the presenters, from Aaron Draplin to Rachel Andrew, tossed out their ‘normal’ presentation format and showed the attendees how they work. The experience was enlightening, showing how similar we all are in our work processes in some ways, while approaching things from an entirely different angle in others. In fact, we loved it so much that we’ve decided 2019 should be the year of No Slides!

The end of the summer is when Smashing goes home. Set on the foothills of the Black Forest, at the infamous Markethall, SmashingConf came back to Freiburg, Germany with 14 speakers. Chui Chui Tan spoke about Designing for Global Audiences while Josh Clark talked about Design in the Era of the Algorithm. In addition, we had a new experience adding community lightning talks to our program. No matter what changes though, there’s nothing like hosting SmashingConf Freiburg and bringing people to our home.

And finally, we ended the year in the city that never sleeps — and lived up to the name! In New York City, we had 14 speakers, 8 workshops, a packed speaker panel, a couple of retro parties, and events that kept everyone busy for four days. Smashing challenged the sold-out audience with an engaging group of speakers from John Maeda to Debbie Millman and Sara Soueidan. No matter how many times we go back, the experiences always change us in a way.

But, then again, that’s how the Smashing team always feels at the end of a season: challenged, moved, and driven. We’ve learned from over 30 speakers, met over 1500 attendees, flown to 5 cities, eaten lots of incredible food, and had countless wonderful experiences. Now, the team is ready to create, improve, and progress to see what 2019 has in store for us!

Marc Thiele: Moving Closer Together

If you ask me, I think that this year went by really quickly. When I look back, I see five Smashing conferences, which took place in London, San Francisco, Toronto, Freiburg and New York, as well as many improvements which we’ve achieved in the background.

Editor’s note: Marc has taken photos of many of our conferences, you can find the albums on his Flickr account.

When I say background, I mean that maybe readers, attendees or folks who visit Smashing Magazine don’t even recognize the work we do behind the curtains. Of course, there are final products that are presented in the articles published on Smashing Magazine, the Smashing Books, or projects that have been brought to your attention via Smashing TV or while attending a Smashing conference or workshops, but there is a small team of people who work hard to continue improving workflows and experiences for our cherished customers. What you often don’t see is see the messy middle and the bumpy journey we are on — from talking about a new idea to the final product. There actually is a lot of work, a lot of failure, and many discussions and conversations involved.

From the end of April onwards, we had many meetings and conversations to see where we can improve the work that we do. Defining clear roles and tasks, checking how the many different parts of the Smashing Universe can grow closer together, and also looking for new, exciting ideas to bring to life. There are also many new faces on board of the Smashing boat — fresh energy to move forward — and I am very much looking forward to seeing the results of their passion and input. Expect the quality you know from the magazine and the events and an even better Smashing Membership, Smashing TV, and maybe the one or other new idea.

So, when I personally speak about 2018, I tend to say that this year was not too good and felt strange for a reason that I can’t really grab and describe. Perhaps it is the overall mood and spirit that comes from what you see when you turn on the news, read the newspaper in the morning or talk to your neighbor? All I know is that it is important to stay positive and have a positive look into the future. I ran three very successful beyond tellerrand shows in Munich, Dusseldorf and Berlin, and I’ve seen the success we had with all the Smashing conferences and the improvements we’ve accomplished for the overall Smashing experience.

My wish for the upcoming new year: let’s meet — even more. Let’s share ideas and what we’ve learned. Let’s not just meet on the web, but in real life. It is wonderful to teach and share and to see other people taking what they’ve learned from you and take it further to create, inspire and teach others with it. One more thing that also is important: Stay curious and ask questions. Never fear to ask a question as you “might look stupid asking.” If you have a question, then it’s stupid not to ask.

With this, I wish everyone a wonderful journey over to 2019 and I am looking forward to meeting you in 2019!

Alma Hoffmann: Reflections

Working at Smashing Magazine has been a very rewarding experience. Each time one of the articles I have edited gets published, I think I am happier than the authors.

One article, in particular, that was very meaningful to me was written by Trine Falbe and titled “Ethical Design The Practical Getting-Started Guide.” We all talk about ethical design, but not often we are provided with a way to get started. It is a good article to reflect upon as the current year ends and the new starts.

Thank you, Smashing, for keeping me around!

A Truly Smashing Year

Reading all of this certainly makes me proud to be part of the Smashing team. At the heart of everything Smashing, is an absolute focus on you, our readers, members, and conference attendees. We hope that the things we do demonstrate that, and we are always happy to listen and to learn when we get it wrong!

I’m excited for the things we will be sharing in 2019, and along with all of the team I am always happy to hear your feedback. What can we do better? What do you want to learn? How can we help? We will be opening up a survey for some more formal feedback early in 2019, but our door (or email inbox at least) is always open!

(il)
Categories: Around The Web

New Year, New Beginnings (January 2019 Wallpapers Edition)

Smashing Magazine - Mon, 12/31/2018 - 7:30am
New Year, New Beginnings (January 2019 Wallpapers Edition) New Year, New Beginnings (January 2019 Wallpapers Edition) Cosima Mielke 2018-12-31T13:30:00+01:00 2019-01-18T21:18:05+00:00

Maybe you’ve already started into the new year when you read this, maybe you’re still waiting for the big countdown to begin. No matter what: Let’s welcome 2019 with a fresh wallpaper!

To give you a little inspiration boost, artists and designers from across the globe once again tickled their creativity and designed unique wallpapers for you to indulge in. All of them come in versions with and without a calendar for January 2019 and can be downloaded for free — just like every month since more than nine years already. At the end of this post, we also compiled some January favorites from past years that are too good not to share. Have an exciting new year!

Further Reading on SmashingMag:

Please note that:

  • All images can be clicked on and lead to the preview of the wallpaper,
  • You can feature your work in our magazine by taking part in our Desktop Wallpaper Calendar series. We are regularly looking for creative designers and artists to be featured on Smashing Magazine. Are you one of them?

Meet Smashing Book 6 — our brand new book focused on real challenges and real front-end solutions in the real world: from design systems and accessible single-page apps to CSS Custom Properties, CSS Grid, Service Workers, performance, AR/VR and responsive art direction. With Marcy Sutton, Yoav Weiss, Lyza D. Gardner, Laura Elizabeth and many others.

Table of Contents → Let The Magic Begin

“When the noisy holidays stay behind us, and everything calms down to a peaceful setting, it is a perfect moment for the magic to step in and start making our wishes, hopes, and decisions come true. Happy January, everyone!” — Designed by PopArt Web Design from Serbia.

New Year

“The dawn of January the 1st of 2019 is the beginning of a new year which gives dreams, hopes and a lot more to billions of people around the world.” — Designed by Sweans Technologies Ltd. from London.

A New Beginning

“I wanted to do a lettering-based wallpaper because I love lettering. I chose January because for a lot of people the new year is perceived as a new beginning and I wish to make them feel as positive about it as possible! The ideia is to make them feel like the new year is (just) the start of something really great.” — Designed by Carolina Sequeira from Portugal.

Intense Winter

“Winter brings both Christmas & New Year together. A season which provides time for comfort, food, warmth, and touch of a friendly hand and for a talk beside the fire.” — Designed by Call Taxi Software from India.

New Year, New Chances

“The climate is changing very fast. 2019 is a new chance to save the earth, the people and the animals who suffer from global warming.” — Designed by Melissa Bogemans from Belgium.

A Cold But Happy 2019

“January is a cold but cozy month so i tried to make my illustrations in cold and cozy colors. Blue and white as the cold colors and red darkblue as the cozy colors. I made some small details like reindeers, clouds snowflakes and trees to make it look better.” — Designed by Vince Teckmans from Belgium.

Cold... Penguins!

“The new year is here! We waited for it like penguins. We look at the snow and enjoy with it!” — Designed by Veronica Valenzuela from Spain.

Hidden Gem

“Kingfishers are called ‘ijsvogels’ (ice-birds) in Dutch. Not because they like winter cold, but because of the intense blue and teal colors...” — Designed by Franke Margrete from the Netherlands.

Snowman

Designed by Ricardo Gimenes from Sweden.

Freezy Hope For 2019

“I took this photo while walking around the city where I live. It's located in the Vosges, France. It was cold but without snow. White color is coming from freezy touchs of the fog remaining on everything. I found it amazing. White is a color for hope. Let's have a pleasant year 2019” — Designed by Philippe Brouard from France

Beginnings

“Welcome, New Year! A New Year is filled with new opportunities and exciting doors that will open to us all. Our friends in the southern hemisphere are experiencing the warmest time of year while we’re at our chilliest!” — Designed by Heather Ozee from the United States.

Oldies But Goodies

The past New Year’s editions have brought forth some timeless wallpaper goodies that work equally well in 2019. Please note that they don’t come with a calendar. May we present…

Open The Doors Of The New Year

“January is the first month of the year and usually the coldest winter month in the Northern hemisphere. The name of the month of January comes from ‘ianua’, the Latin word for door, so this month denotes the door to the new year and a new beginning. Let’s open the doors of the new year together and hope it will be the best so far!” — Designed by PopArt Studio from Serbia.

Start Somewhere

“If we wait until we’re ready, we’ll be waiting for the rest of our lives. Start today - somewhere, anywhere.” — Designed by Shawna Armstrong from the United States.

Winter Leaves

Designed by Nathalie Ouederni from France.

Boom!

Designed by Elise Vanoorbeek from Belgium.

January Fish

“My fish tank at home inspired me to make a wallpaper with a fish :)” — Designed by Arno De Decker from Belgium.

Angel In Snow

Designed by Brainer from Ukraine.

Happy Hot Tea Month

“You wake me up to a beautiful day; lift my spirit when I’m feeling blue. When I’m home you relieve me of the long day’s stress. You help me have a good time with my loved ones; give me company when I’m all alone. You’re none other than my favourite cup of hot tea.” — Designed by Acodez IT Solutions from India.

Dare To Be You

“The new year brings new opportunities for each of us to become our true selves. I think that no matter what you are — like this little monster — you should dare to be the true you without caring what others may think. Happy New Year!” — Designed by Maria Keller from Mexico.

White Mountains

“In Central Europe, we’ve had a very warm beginning of winter. I hope there will be lots of powder for snowboarding soon. I’d love to see the French Alps again as white as in 2015 when I took this photo.” — Designed by Annika Oeser from Germany.

Winter Getaway

“What could be better, than a change of scene for a week? Even if you are too busy, just think about it.” — Designed by Igor Izhik from Canada.

Be Awesome Today

“A little daily motivation to keep your cool during the month of January.” — Designed by Amalia Van Bloom from the United States.

Japanese New Year

Designed by Evacomics from Singapore.

A New Start

“The new year brings hope, festivity, lots and lots of resolutions, and many more goals that need to be achieved. This wallpaper is based on the idea of ‘A New Start’.” — Designed by Damn Perfect from India.

The Way To Get Started

“January is all about renewing efforts and making plans, but sometimes we need little reminders that plans don’t matter if you don’t do anything about them. Initially, I was inspired by the idea of a fresh sheet of paper, which became the background for some great words from Walt Disney.” — Designed by Resa Barillas from the United States.

Three Wise Men Of The East

“In Belgium remember the Three Wise Men of the East is a tradition. It involves children going from door to door, dressed up as the three Wise Men. They sing a little song, in exchange for sweets and/or money. The design is very minimalistic and ‘flat’. I hope you like it :)” — Designed by Jeroen Bartels from Belgium.

Rest Up For The New Year

“I was browsing for themes when I found this “Festival of Sleep” that takes place on the 3rd, and I’m a big fan of sleep… Especially in these cold months after the holiday craziness, it’s nice to get cozy and take a nice nap.” — Designed by Dorothy Timmer from Central Florida, USA.

Hello Summer In Australia

Designed by Tazi Designs from Australia.

Join In Next Month!

Please note that we respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience throughout their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us, but rather designed from scratch by the artists themselves.

Thank you to all designers for their participation. Join in next month!

(il)
Categories: Around The Web

Will PWAs Replace Native Mobile Apps?

Smashing Magazine - Fri, 12/28/2018 - 6:30am
Will PWAs Replace Native Mobile Apps? Will PWAs Replace Native Mobile Apps? Suzanne Scacca 2018-12-28T12:30:52+01:00 2019-01-18T09:14:22+00:00

A developer friend of mine has decided to build a progressive web app for his new company. When I asked why he opted for a PWA instead of a native app, he said:

“Because the PWA is the future of the web.”

I thought that was an interesting sentiment. Until he mentioned it, I was of a similar mindset as Aaron Gustafson when he discussed the battle between the native app and PWA. In other words, I thought it really just came down to choice; not whether one was better than the other.

Now that the idea has been planted, though, I can’t help but notice a bunch of people proclaiming their support for the PWA over the native app. Not only that, many of them have gone as far as to say that the PWA will replace the native app entirely.

I’d like to see if that argument holds any water.

An Extensive Guide To PWAs

Progressive Web Applications are more of a methodology that involves a combination of technologies to make powerful web applications. Tell me more about PWAs →

Will PWAs Replace Native Apps?

I’m going to go ahead and answer that question right now:

“Yes, but not for everyone.”

Here’s the way I see it:

The mobile web has definitely improved from where it was just a couple years ago. It’s very rare to run into a website that isn’t 100% responsive in design. That said, I don’t think many mobile websites are 100% mobile-first in design (which I recently hinted at when talking about ditching design elements instead of acquiring more in 2019).

I think for an experience to be truly mobile-first, it would need to be faster and have an app shell. Which is exactly what a PWA offers.

While native apps may provide a superior experience (mostly) to other mobile experiences, I just don’t see a valid reason to spend that amount of money and time to build and manage one… unless your app sits in the top 20 of your category in an app store.

Let me break down the logic I used to come to this decision.

Our new book, in which Alla Kholmatova explores how to create effective and maintainable design systems to design great digital products. Meet Design Systems, with common traps, gotchas and the lessons Alla has learned over the years.

Table of Contents → Reason #1: Mobile Web Is Lagging

comScore’s Global Digital Future in Focus report from 2018 makes this point painfully clear:

comScore 2018 report shows use of mobile web vs. mobile apps (Image source: comScore) (Large preview)

That said, I don’t believe native apps will make mobile websites disappear. I also don’t believe this point counteracts the argument I’m attempting to make today. If this data demonstrates anything, it’s that mobile users strongly prefer the experience of interacting with a digital property through an app interface.

Web developers recognize this preference as well, as this survey from JAXenter demonstrates:

JAXenter developer survey about PWAs (Image source: JAXenter) (Large preview)

So, although the mobile web browser has proven to be the less preferred interface through which someone views a website, I don’t think that’ll be the case for much longer as more businesses build PWAs.

The PWA takes all of the things users love about native apps — the app shell, offline access, telephony features, an always-present navigation bar and so on — and gives users a more convenient means for experiencing them.

Look at a brand like Crabtree & Evelyn:

Crabtree & Evelyn PWA example (Image source: Crabtree & Evelyn) (Large preview)

This major retailer has the funds to build a native app counterpart to its website, but it’s chosen not to go that route. Instead, the progressive web app experience gives mobile users the convenience of browsing the online store and making a purchase without having to leave the browser.

Or, if they’re frequent users, they can add this PWA to their home screen and treat it as they would any other app (but more on that later).

Now, let’s look at an example of a PWA that, again, has opted not to go the route of the native app. Instead, Infobae has created a PWA that beats the mobile web experience:

Infobae PWA example (Image source: Infobae) (Large preview)

According to Google data, the Infobae PWA has:

  • A 5% bounce rate. The mobile web was 51%.
  • Sessions that are 230% longer than they were on mobile web.
  • Over three times more pages viewed per session than the mobile web.

So, if you’re worried that the PWA won’t cut it as an alternative to the mobile web, you can stop right there. There are clear benefits to building a PWA.

Reason #2: Native App Stores Are Overflowing

Native apps have a lot of competition in the native app stores — many of which are heavy hitters that mobile users are all too familiar with. If your intention is to launch an app in an already congested space, is the app store really the best place for it?

comScore’s report breaks down the top 5 apps based on reach:

comScore data on the top 5 apps by reach in 2018 (Image source: comScore) (Large preview)

As you can see, the top 5 apps tend to be dominated by the same mobile apps, no matter what part of the world mobile users are located in.

What you might be thinking is, “But what if my app has a unique edge? Isn’t that enough to dominate our niche?”

I could see that, especially if your app is targeted to region-specific mobile users. Then again, you have to consider what sort of app types perform well with mobile app users.

comScore breaks down this point:

comScore data on share of total app minutes (Image source: comScore) (Large preview)

Roughly 70% to 80% of all time spent in mobile apps goes to four categories:

  • Entertainment (like YouTube);
  • Social media (like Facebook);
  • Instant messaging (like Whatsapp);
  • Games (like Fortnite).

If your app concept doesn’t fall into one of those categories, is it worth all that work to place your app in the app store? While I recognize that those aren’t the only kinds of apps that succeed, I just think it would be a risky and expensive gamble to make, especially if your client’s business is brand new. Even then, there are so many cases of well-known entities that have opted not to compete in app stores, despite having a large enough audience or customer base to do so.

West Elm is a great example of a retailer who’s done this:

The West Elm PWA (Image source: West Elm) (Large preview)

If you look in the app stores, you’ll find that West Elm has developed two native apps. One is for registries. This makes sense as a mobile app could be conducive to tagging and tracking registry items. It also has one for the West Elm card. If someone is a frequent enough shopper, this type of app might make sense as well.

That said, neither of these native apps is popular with users (at least not in terms of quantity of reviews). So, it was a smart and economical move by West Elm to keep its main shopping interface in the PWA.

Reason #3: PWAs Rank In Search

On a related note, progressive web apps come with the added benefit of ranking in search engines. There are a few reasons why you and your clients should be overjoyed by this:

  1. Your app’s rank in search is contingent upon the SEO work you put into it. If you’re already doing this with your website, this should be easy!
  2. You don’t have to worry about a brand new app getting buried in app store search. Or easily dismissed because of a lack of ratings.
  3. Because a PWA can live in mobile users’ browsers as well as from a button on the home screen, it needs to have a link. And links make for much easier sharing with friends/family/colleagues than telling them the name of an app, hoping they can find it in the store on their own.

Bottom line: if you can give users a tangible link to your app, you can drastically reduce the friction often caused by having one that only exists in the app store.

Plus, I think the searchability aspect is an important one to consider when you think about how people use your app. Take micro-moments, for example.

When a consumer is inspired to:

  • Research something of interest,
  • Go somewhere,
  • Make a purchase,
  • Or do something…

Instead of opening a data-hogging application on their device, they’ll open their search browser and type or speak their query. It’s what we’re all trained to do as consumers. Have a question? Need something? Want help choosing a restaurant? Go to Google.

If your website or app provides an answer to those kinds of questions, you don’t want it hidden away in app stores. You also don’t want to give them a mobile website that offers an option to “Download the App”. You’re only creating extra work for them.

A PWA enables you to place your app directly in search results and to get your users the instant answers they require.

I think this is why e-commerce businesses have especially gravitated towards PWAs, like HobbyCraft.

HobbyCraft PWA example (Image source: HobbyCraft) (Large preview)

As you can see here, HobbyCraft is a niche retailer that sells craft supplies out of the UK. It wouldn’t make much sense to put something like this in the app stores — especially when the PWA interface works well enough as it is.

Lancome is another e-tailer that’s made the conscious decision to forego the native app and keep the mobile shopping experience in a PWA format.

Lancome e-commerce PWA example (Image source: Lancome) (Large preview)

One important design element I would point you to in both these examples is the Stores icon located in the top navigation bar. For businesses with brick-and-mortar counterparts, there’s no reason to keep your app out of local search in Google.

If you design your PWA correctly, you can make it show up in relevant location-based queries. And if you present an interface that’s reminiscent of a native app — and just as secure as one (since PWAs require HTTPS) — you can compel more mobile users to make a purchase on the spot.

Reason #4: Native Apps Struggle With Retention

For app types that have a hook that compels users to spend time inside a native app and spend money to enjoy the experience further, that’s great. When you find that perfect fit, there’s good money to be made from having a native app. It’s simply a matter of having people willing to commit to the download.

However, as we recently saw, most native apps struggle to retain users.

It doesn’t matter how many initial downloads you get. If mobile users don’t return to the app to engage with your content, purchase subscriptions or upgrades or click on ads, consider it a wasted investment. Unfortunately, that’s the case with a lot of them.

PWAs, on the other hand, don’t require the lofty commitment of having to download an app to one’s device. Heck, users don’t even have to save the PWA to their home screens, if they don’t want to. It’s an overall more convenient experience.

Nevertheless, you may want to urge users to save it for instant access in the future, as The Weather Channel does:

The Weather Channel asks users to save PWA to device. (Image source: The Weather Channel) (Large preview)

Really, what it boils down to is the type of app you’ve built.

The Weather Channel, for instance, provides a service that mobile users will want to use on a daily basis. They could install a native app from the app store with up-to-date weather forecasting, but that app would likely chew through data and battery power a lot more quickly than the browser-based PWA will.

There are other business types that should consider using a PWA for this reason. Think about an online magazine like Forbes.

Users can add the Forbes PWA to their home screen just like a native app. (Image source: Forbes) (Large preview)

Highly specialized publications would do really well to develop PWAs for their daily readers.

Again, it provides a much lighter-weight experience for their phones. Plus, PWAs give users offline access, so they can get access to content no matter where they are or how limited their access may be to the Internet. And the home screen presence (if they choose to put the button there), provides a nice little shortcut around the mobile web browser.

Reason #5: PWAs Can Generate More Revenue

With the exception of in-app advertising, Apple and Google take a sizable cut from any sales you make through a native app. This includes paid downloads, in-app purchases or upgrades and subscription fees. At one point, these fees were as high as 30% per sale.

When you’re hoping to spend money on design tweaks, much-needed development updates and promotional advertising, that’s the last thing you want to hear. In other words, a significant portion of the money that starts to trickle in from your native app goes straight into the pockets of app store owners. That doesn’t seem right, especially if you have to pay for app store ads in order to gain visibility within them.

PWAs don’t come with fees to pay-to-play, which means all revenue generated from them go directly to you (or whoever the owner of the business is). This is especially nice if you have an app concept like a local newspaper (such as The Billings Gazette) that probably deals in smaller profit margins to begin with.

The Billings Gazette PWA monetization example (Image source: The Billings Gazette) (Large preview)

That’s not the only way you can make more money from PWAs than native apps either.

To start, they’re significantly easier to build than native apps. Plus, managing them after launch requires less of a time commitment and resources from you. Yes, it still needs to be updated and maintained — just like anything else on the web — but you don’t have to deal with the obstacles that come with apps in the app store.

For example, you only have to build one progressive web app. You don’t have to create separate ones to match the guidelines for different mobile devices.

Updates are easier, too, especially if your PWA is based off of a WordPress website. You push an update through the pipeline and it shows up immediately in the live PWA. There’s no need to push updates to the app store admins and wait for their approvals. Everything happens in real time, which means getting new features and money-making initiatives out to the public more quickly.

This is helpful in the case of PWAs like Twitter Lite.

The Twitter Lite PWA can stay on the cutting edge in real time (Image source: Twitter) (Large preview)

When going up against a plethora of social media giants that dominate the app stores, having the ability to keep your app updated in real time can serve as a strong competitive edge. This is in addition to all of the other benefits that come from developing your app in a progressive web format.

This is what happened when Twitter put out its PWA.

As this case study from Google shows, Twitter took an incremental approach to optimizing its PWA. As such, they’ve been able to introduce huge improvements to the user experience without much detection from the end user. Their only response to the updates, in fact, has been greater usage of the PWA.

The PWA Is The Future For (Most Of) The Web

Visibility and searchability are known problems with native mobile apps. User retainment is another. And they’re just not sustainable unless you have an idea that’s inherently meant for a native interface that’s sure to bring in money. Mobile games are one example of this. I’d argue that dating apps are another. I used to think social media fell into that category, but Twitter has since proven me wrong.

Based on what I’m seeing online and from what I’ve heard from developer friends and colleagues, I do believe the future is in the PWA.

I think app stores will slowly quiet down as developers realize there are many more benefits to putting a small- to medium-sized company’s app into a progressive web form. The major players will stay put, and companies that have outgrown the bounds of the PWA may eventually move over. But, otherwise, most apps will end up in the progressive web format.

As this trend towards the PWA continues to grow, consumers will become more accustomed to encountering it in search and know that this user-friendly interface is accessible right from their browser. In turn, they’ll only go to the app stores for the kinds of apps that belong there, i.e. messaging, games, entertainment, and some social media. This will create a clearer division between online search and app store search, and further help to improve the overall user experience online.

(ra, yk, il)
Categories: Around The Web

Common CSS Issues For Front-End Projects

Smashing Magazine - Thu, 12/27/2018 - 7:30am
Common CSS Issues For Front-End Projects Common CSS Issues For Front-End Projects Ahmad Shadeed 2018-12-27T13:30:11+01:00 2019-01-17T09:35:34+00:00

When implementing a user interface in a browser, it’s good to minimize those differences and issues wherever you can, so that the UI is predictable. Keeping track of all of those differences is hard, so I’ve put together a list of common issues, with their solutions, as a handy reference guide for when you’re working on a new project.

Let’s begin.

1. Reset The Backgrounds Of button And input Elements

When adding a button, reset its background, or else it will look different across browsers. In the example below, the same button is shown in Chrome and in Safari. The latter adds a default gray background.

(Large preview)

Resetting the background will solve this issue:

button { appearance: none; background: transparent; /* Other styles */ }

See the Pen Button and Inputs by Ahmad Shadeed (@shadeed) on CodePen.

Front-end is messy and complicated these days. That's why we publish articles, printed books and webinars with useful techniques to improve your work. Even better: Smashing Membership with a growing selection of front-end & UX goodies. So you get your work done, better and faster.

Explore Smashing Membership ↬ 2. Overflow: scroll vs. auto

To limit the height of an element and allow the user to scroll within it, add overflow: scroll-y. This will look good in Chrome on macOS. However, on Chrome Windows, the scroll bar is always there (even if the content is short). This is because scroll-y will show a scroll bar regardless of the content, whereas overflow: auto will show a scroll bar only when needed.

Left: Chrome on macOS. Right: Chrome on Windows. (Large preview) .element { height: 300px; overflow-y: auto; }

See the Pen overflow-y by Ahmad Shadeed (@shadeed) on CodePen.

3. Add flex-wrap

Make an element behave as a flex container simply by adding display: flex. However, when the screen size shrinks, the browser will display a horizontal scroll bar in case flex-wrap is not added.

<div class="wrapper"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div> .wrapper { display: flex; } .item { flex: 0 0 120px; height: 100px; }

The example above will work great on big screens. On mobile, the browser will show a horizontal scroll bar.

Left: A horizontal scroll bar is shown, and the items aren’t wrapped. Right: The items are wrapped onto two rows. (Large preview)

The solution is quite easy. The wrapper should know that when space is not available, it should wrap the items.

.wrapper { display: flex; flex-wrap: wrap; }

See the Pen flex-wrap by Ahmad Shadeed (@shadeed) on CodePen.

4. Don’t Use justify-content: space-between When The Number Of Flex Items Is Dynamic

When justify-content: space-between is applied to a flex container, it will distribute the elements and leave an equal amount of space between them. Our example has eight card items, and they look good. What if, for some reason, the number of items was seven? The second row of elements would look different than the first one.

The wrapper with eight items. (Large preview) The wrapper with seven items. (Large preview)

See the Pen justify-content by Ahmad Shadeed (@shadeed) on CodePen.

In this case, using CSS grid would be more suitable.

5. Long Words And Links

When an article is being viewed on a mobile screen, a long word or inline link might cause a horizontal scroll bar to appear. Using CSS’ word-break will prevent that from happening.

Large preview .article-content p { word-break: break-all; } (Large preview)

Check out CSS-Tricks for the details.

6. Transparent Gradients

When adding gradient with a transparent start and end point, it will look black-ish in Safari. That's because Safari doesn’t recognize the keyword transparent. By substituting it with rgba(0, 0, 0, 0), it will work as expected. Note the below screenshot:

Top: Chrome 70. Bottom: Safari 12. (Large preview) .section-hero { background: linear-gradient(transparent, #d7e0ef), #527ee0; /*Other styles*/ }

This should instead be:

.section-hero { background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0; /*Other styles*/ } 7. The Misconception About The Difference Between auto-fit And auto-fill In CSS Grid

In CSS grid, the repeat function can create a responsive column layout without requiring the use of media queries. To achieve that, use either auto-fill or auto-fit.

.wrapper { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); } (Large preview)

In short, auto-fill will arrange the columns without expanding their widths, whereas auto-fit will collapse them to zero width but only if you have empty columns. Sara Soueidan has written an excellent article on the topic.

8. Fixing Elements To The Top Of The Screen When The Viewport Is Not Tall Enough

If you fix an element to the top of the screen, what happens if the viewport is not tall enough? Simple: It will take up screen space, and, as a result, the vertical area available for the user to browse the website will be small and uncomfortable, which will detract from the experience.

@media (min-height: 500px) { .site-header { position: sticky; top: 0; /*other styles*/ } }

In the snippet above, we’re telling the browser to fix the header to the top only if the viewport’s height is equal to or greater than 500 pixels.

Also important: When you use position: sticky, it won’t work unless you specify the top property.

Large preview

See the Pen Vertical media queries: Fixed Header by Ahmad Shadeed (@shadeed) on CodePen.

9. Setting max-width For Images

When adding an image, define max-width: 100%, so that the image resizes when the screen is small. Otherwise, the browser will show a horizontal scroll bar.

img { max-width: 100%; } 10. Using CSS Grid To Define main And aside Elements

CSS grid can be used to define the main and aside sections of a layout, which is a perfect use for grid. As a result, the aside section’s height will be equal to that of the main element, even if it’s empty.

To fix this, align the aside element to the start of its parent, so that its height doesn’t expand.

.wrapper { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-gap: 20px; } // align-self will tell the aside element to align itself with the start of its parent. aside { grid-column: 1 / 4; grid-row: 1; align-self: start; } main { grid-column: 4 / 13; } (Large preview)

See the Pen main and aside by Ahmad Shadeed (@shadeed) on CodePen.

11. Adding fill To An SVG

Sometimes, while working with SVGs, fill won’t work as expected if the fill attribute has been added inline in the SVG. To solve this, either to remove the fill attribute from the SVG itself or override fill: color.

Take this example:

.some-icon { fill: #137cbf; }

This won’t work if the SVG has an inline fill. It should be this instead:

.some-icon path { fill: #137cbf; } 12. Working With Pseudo-Elements

I love to use pseudo-elements whenever I can. They provide us with a way to create fake elements, mostly for decorative purposes, without adding them to the HTML.

When working with them, the author might forget to do one of the following:

  • add the content: "" property,
  • set the width and height without defining the display property for it.

In the example below, we have a title with a badge as a pseudo-element. The content: "" property should be added. Also, the element should have display: inline-block set in order for the width and height to work as expected.

Large preview 13. The Weird Space When Using display: inline-block

Setting two or more elements to display: inline-block or display: inline will create a tiny space between each one. The space is added because the browser is interpreting the elements as words, and so it’s adding a character space between each one.

In the example below, each item has a space of 8px on the right side, but the tiny space caused by using display: inline-block is making it 12px, which is not the desired result.

li:not(:last-child) { margin-right: 8px; } (Large preview)

A simple fix for this is to set font-size: 0 on the parent element.

ul { font-size: 0; } li { font-size: 16px; /*The font size should be reassigned here because it will inherit `font-size: 0` from its parent.*/ } (Large preview)

See the Pen Inline Block Spacing by Ahmad Shadeed (@shadeed) on CodePen.

14. Add for="ID" When Assigning A Label Element To An Input

When working with form elements, make sure that all label elements have an ID assigned to them. This will make them more accessible, and when they’re clicked, the associated input will get focus.

<label for="emailAddress">Email address:</label> <input type="email" id="emailAddress"> Large preview 15. Fonts Not Working With Interactive HTML Elements

When assigning fonts to the whole document, they won’t be applied to elements such as input, button, select and textarea. They don’t inherit by default because the browser applies the default system font to them.

To fix this, assign the font property manually:

input, button, select, textarea { font-family: your-awesome-font-name; } 16. Horizontal Scroll Bar

Some elements will cause a horizontal scroll bar to appear, due to the width of those elements.

The easiest way to find the cause of this issue is to use CSS outline. Addy Osmani has shared a very handy script that can be added to the browser console to outline every element on the page.

[].forEach.call($$("*"), function(a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); }); (Large preview) 17. Compressed Or Stretched Images

When you resize an image in CSS, it could be compressed or stretched if the aspect ratio is not consistent with the width and height of the image.

The solution is simple: Use CSS’ object-fit. Its functionality is similar to that of background-size: cover for background images.

img { object-fit: cover; } (Large preview)

Using object-fit won’t be the perfect solution in all cases. Some images need to appear without cropping or resizing, and some platforms force the user to upload or crop an image at a defined size. For example, Dribbble accepts thumbnails uploads at 800 by 600 pixels.

18. Add The Correct type For input.

Use the correct type for an input field. This will enhance the user experience in mobile browsers and make it more accessible to users.

Here is some HTML:

<form action=""> <p> <label for="name">Full name</label> <input type="text" id="name"> </p> <p> <label for="email">Email</label> <input type="email" id="email"> </p> <p> <label for="phone">Phone</label> <input type="tel" id="phone"> </p> </form>

This is how each input will look once it’s focused:

(Large preview) 19. Phone Numbers In RTL Layouts

When adding a phone number like + 972-123555777 in a right-to-left layout, the plus symbol will be positioned at the end of the number. To fix that, reassign the direction of the phone number.

p { direction: ltr; } (Large preview) Conclusion

All of the issues mentioned here are among the most common ones I’ve faced in my front-end development work. My goal is to keep a list to check regularly while working on a web project.

Do you have an issue that you always face in CSS? Let us know in the comments!

(dm, ra, al, yk, il)
Categories: Around The Web

What We Wished For

Smashing Magazine - Mon, 12/24/2018 - 8:30am
What We Wished For What We Wished For Mat Marquis 2018-12-24T14:30:46+01:00 2019-01-16T07:54:18+00:00

I think we’re headed for trouble, though I can’t say for sure. Trouble — trouble I know. The on-ramp to it, though; I’ve only heard about that. I’ve only been doing this for ten years. I missed all the lead-up the last time around. What I can say for sure — what I know from experience — is that I’ve never had a wish made in anger come true without regretting it.

Ten years (I don’t mind saying) is a pretty long time. Back when I first truth-stretched my way into a web design internship, good ol’ Internet Explorer was already a laughingstock.

“If you notice that a piece of your content appears and disappears, and sections of the page only get half-drawn, these are good indications that an element requires a layout. [...] A hasLayout fix involves nothing more than declaring a CSS property that causes an element to gain a layout, when it wouldn’t ordinarily have a layout by default.”

The Internet Explorer hasLayout Property

I hated IE. I feel like I can cop to that now. I tried not to; I really, sincerely did. I’d tell people it was fun to support, if you can believe it.

As all the other browsers got easier and easier to deal with, I attempted to convince myself that there was at least still a challenge to quirky old IE. That even became something of a point of pride: I had gotten so good at fixing obscure IE issues that I’d learned to dodge them during the course of my everyday development, leaving nothing (well, less) to dread come the big “open it up in IE and see what broke” phase.

Web forms are such an important part of the web, but we design them poorly all the time. The brand-new “Form Design Patterns” book is our new practical guide for people who design, prototype and build all sorts of forms for digital services, products and websites. The eBook is free for Smashing Members.

Check the table of contents ↬

It’s fun, in a way. Fun. That was the lie I told myself.

/* Fixes #2588: When Windows Phone 7.5 (Mango) tries to calculate a numeric opacity for a select (including “inherit”) without explicitly specifying an opacity on the parent to give it context, a bug appears where clicking elsewhere on the page after opening the select will open the select again. */

jQuery Mobile source

I hated it. I full-on, bad-jokes-in-a-conference-talk hated IE, in every one of its incarnations. I hated it every bit as much everybody else did.

“Internet Explorer 6 has a puzzling bug involving multiple floated elements; text characters from the last of the floated elements are sometimes duplicated below the last float. ... The direct cause is nothing more than ordinary HTML comments, such as, <!-- end left column -->, sandwiched between floats that come in sequence.”

Explorer 6 Duplicate Characters Bug

A waste of my goddamned time is what it was. All those hours I spent hunched over a janky virtual machine—reload, wait, throw a nonsense fix at a nonsense bug, reload, crash, open IE again, wait, double-check that caching wasn’t a factor, reload, wait, and repeat. I could have been doing so much more with my time — I could have learned so much more.

I was certain that it didn’t just hold back my work, and it didn’t just hold the web back, but it held me back, as a developer. On that second point, I guess I wasn’t entirely wrong — all the obscure IE 6-7 browser bug knowledge I accumulated is all useless now. All I have to show for it are an involuntary flinch at the word “filter,” an inscrutable preference for padding over margin, and a deep-seated but largely unfounded fear of z-index. ​ “…extra whitespace causes the wrong styles to be picked up if the actual class name is a substring (or superstring) of some other class name.”

IE5/Mac whitespace parsing bug

I wished it would go away. Uninstalled by a clever and widespread virus, banned by law, Microsoft finally deciding to cut their shoddy rendering engine’s losses and switching to Firefox’s rendering engine, Gecko — whatever — just make it go away. But… no. The web kept evolving and we developers beat on, boats against the current, borne back ceaselessly into the past.

Chrome came along, Firefox kept getting better, new features kept rolling out, the exciting and endless possibilities presented by the advent of responsive web design spread out before us, and also (quick aside) remember that you’ll only have a couple of days to make it all more-or-less work in old IE, so don’t get too carried away. ​ “IF you are using IE8, AND you are using the CSS ordered list numbering approach described above, AND the HTML that has the classes that use the counter-reset and counter-increment CSS attributes is HIDDEN when the page loads, THEN whenever that hidden HTML is displayed, ALL of the automatic numbers will be ZERO, BUT ONLY IF THE CSS :hover PSEUDO-CLASS IS USED ON THAT PAGE!”

The IE8 “hover” Bug: The Most Awesome IE Bug Ever?

It’s hard to imagine experiencing that kind of frustration nowadays, at least for us relatively-old-timers. Not to say that there isn’t an incredible amount of work involved in tuning things up cross-browser these days, too — I know all too well that there is. But it’s tough not to feel the occasional pang of, “back in my day, all we had were floats, and let me tell you about IE’s double margin bug,” when you hear about a little difference in how CSS Grid works from one browser to another.

I was wrong; I want to be clear on that point. Not wrong for being frustrated. I don’t think anyone should be blamed for being frustrated with those old browser bugs, same as I don’t think anyone should be blamed for their frustration with any aspect of web development now. No, I was wrong for the conclusion that anger brought me to: the desire to see Trident burned to the ground and the earth where it once stood salted.

I suspect that only one dramatically-ironic thing grows out of that salted earth: those same frustrations, born anew, for a new generation of web developers. When I started my career, scant few years after the browser wars, those seeds had already taken root. Because, for a time — a time before my own — we web developers cursed Netscape the same way. The weaker, buggier, inarguably worse browser. But Internet Explorer — developers loved that browser. And they wished those other browsers — the bad browsers — would just go away: uninstalled by a clever and widespread virus, banned by law, Netscape finally deciding to cut their shoddy rendering engine’s losses and switch to IE’s rendering engine, Trident — whatever — just make it go away. Those inscrutable Internet Explorer bugs didn’t happen by coincidence or negligence. They came about because Internet Explorer had won, and we loved it for winning.

See, our frustration and our anger lied to us, as they usually do. They told us that supporting those other, worse browsers didn’t just hold back our work, and didn’t just hold the web back, but it held us back, as developers. A waste of our goddamned time is what it was. So, we told ourselves that it wasn’t only for our own good, but for the good of the entire web.

We weighed IE just a little more heavily. We gave it just a little more say in our decisions. And so, holding so many chips, Microsoft played their cards accordingly — who could blame them? Everyone built websites for them first, and the others second. Their word wasn’t law, but it was certainly more than suggestion. Sure, they deviated from web standards here and there (just a little bit), but after all, wasn’t something implemented by The Biggest Browser a sort of de facto standard anyway? Besides, supporting the better, faster, easier browser was doing the web itself a service! Together with Microsoft, we were pushing the web forward! Everybody wins.

The rendering engine that powers Microsoft’s Edge browser today — EdgeHTML — is a fork of gnarly old Trident. It’s a stripped-down and vastly improved fork of Trident, for sure, but it isn’t, let’s say, universally judged on its own merit. The EdgeHTML team has always been working with a couple of disadvantages: the first was technical, in that it took a tremendous amount of time and effort to catch up with the likes of Safari, Firefox, and Chrome. The second was emotional. It was us — you and me — jaded from years of Internet Explorer, staring down a cheery blue lowercase “e” with cold disdain.

A few weeks ago, the Edge team announced that they’d soon be abandoning EdgeHTML in favor of Blink, the rendering engine that powers Chrome. With this change, the last few remaining embers of Trident will be snuffed out forever. The wish I’d shared with so many will finally be granted. Ironically timed — as it turns out — EdgeHTML was becoming a pretty solid rendering engine.

Blink is an open-source project led and governed by Google. It powers both Chrome and Opera, the latter of which similarly abandoned their home-grown rendering engine a few years ago.

By an overwhelming margin, Blink is (and will increasingly be) the way the web is experienced the world over. Blink is fast, stable, packed with modern features, and — by comparison to development for the still-evolving EdgeHTML — painless.

It may have happened too late to save us from those ancient IE bugs, but our work will be easier now that there’s one less rendering engine to support. You and I will lose a little more of our collective “but does it work cross-browser” burden. Our projects will go more smoothly, and the web will lose just a little more of what was once holding it back.

As stewards of the engine powering so very much of the web, well, Google’s word won’t be law, but certainly more than suggestion. And maybe over the course of the next few years, they’ll deviate from web standards here and there (whether intentionally or accidentally) in the tiniest of ways. But after all, isn’t something implemented by The Biggest Browser a sort of de facto standard itself? Besides, how could you argue? Favoring the better, faster, more powerful browser is doing the web itself a service, after all. Together with Google, we’ll be pushing the web forward. Everybody will win.

That is, as long as little standards deviations and tiny, nagging bugs don’t grow bigger over time — thanks to the twin forces of entropy and complacency. Unless the decisions we’ve made for the good of the web (hand-in-hand with a notoriously privacy-hostile advertising company) begin to feel a little darker, and a new bogeyman begins to take shape in our minds — unless we find that our old fears and frustrations have risen again (like a phoenix that renders a couple hundred pixels away from where it should and flickers in a weird way when you scroll).

It doesn’t take much imagination to see newer, more exciting rendering engines appearing over the next handful of years. It takes just as little imagination to see them failing due to lack of support, as we favor “the browser that everyone uses” — first by choice, and later perhaps in grudging service of “the bottom line.”

Again, though, I don’t know. I’ve never seen this happen with a rendering engine myself. I’ve just heard the whole story, and I only know first-hand how it ends. I know the ending from the ache of old psychic scars; from an involuntary flinch at some bits of code, and muscle-memory that compels me to avoid others. I know it from the jokes in conference talks that always felt a little tired, but still resonated just the same in a way I wouldn’t allow myself to admit and still spoke to a secret wish that I held deep in my heart. A bitter, hateful wish.

But hey, listen. Not anymore. Now, I mean — I would never. I really do love a good rendering engine bug, now. I do.

“CSS 3D transforms with perspective() are rendered inside out.”

bugs.chromium.org

I mean, that’s actually kind of a fun bug, right? Like, fun in a way. Y’know?

It’s fun.

It’ll be fun.

(dm, ra, il)
Categories: Around The Web

Generic First CSS: New Thinking On Mobile First

Smashing Magazine - Fri, 12/21/2018 - 8:45am
Generic First CSS: New Thinking On Mobile First Generic First CSS: New Thinking On Mobile First Alastair Hodgson 2018-12-21T14:45:16+01:00 2019-01-15T08:16:29+00:00

I think it’s safe to say that Ethan Marcotte’s Responsive Web Design was a welcome revelation for web developers the world over. It triggered a whole new wave of design thinking and wonderful new front-end techniques. The reign of the oft-despised m dot websites was also over. In the same era and almost as influential was Luke Wroblewski’s Mobile First methodology — a solid improvement that built upon Marcotte’s impressive foundations.

These techniques are at the bedrock of most web developers lives, and they’ve served us well, but alas, times change, and developers constantly iterate. As we increase the efficiency of our methods and the project requirements become more complex, new frustrations emerge.

The Journey To Generic First

I can’t pinpoint exactly what made me change the way I write my CSS because it was really a natural progression for me that happened almost subconsciously. Looking back, I think it was more of a by-product of the development environment I was working in. The team I worked with had a nice SCSS workflow going on with a nifty little mixin for easily adding breakpoints within our CSS declarations. You probably use a similar technique.

This wonderful little SCSS mixin suddenly made it easy to write super granular media queries. Take a hypothetical biography block that looks a little something like this:

.bio { display: block; width: 100%; background-color: #ece9e9; padding: 20px; margin: 20px 0; @include media('>=small') { max-width: 400px; background-color: white; margin: 20px auto; } @include media('>=medium') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }

Fig.1. Typical mobile first with cascading media queries

This works nicely — I’ve written a lot of CSS like this in the past. However, one day it dawned upon me that overwriting CSS declarations as the device width increased just didn’t make sense. Why declare a CSS property for it only to be overwritten in the following declaration?

Front-end is messy and complicated these days. That's why we publish articles, printed books and webinars with useful techniques to improve your work. Even better: Smashing Membership with a growing selection of front-end & UX goodies. So you get your work done, better and faster.

Explore Smashing Membership ↬

This is what lead me to begin writing compartmentalized media queries as opposed to the more common approach of media queries that cascade upwards (or downwards) like the example in Fig.1.

Instead of writing media queries that cascade upwards with increases in screen size, I began creating targeted media queries that would encapsulate styles at desired screen widths. The media query mixin would really come into its own here. Now my SCSS media queries are starting to look like this:

.bio { display: block; width: 100%; padding: 20px; margin: 20px 0; @include media('>=small', '<medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', '<large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', '<huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }

Fig.2. An example of compartmentalized media queries

This new approach just felt more intuitive to me, it cut down on having to reset styles from the previous breakpoint, and it was making the CSS easier to read. More importantly, it was making the media queries self-documenting in a more significant way.

I still wasn’t 100% happy with the above though, It seemed like there was still a major issue to overcome.

The Problem With Mobile First

The issue with mobile first is that by definition you will most likely have to override mobile-first styles in subsequent media-queries. This feels like a bit of an anti-pattern.

So — to me — the answer was obvious: let’s take the idea of media query compartmentalization to its logical conclusion — we will also compartmentalize the mobile specific styles into their very own media queries. I know, I know, this goes against the common convention we’ve learned over the years. “Mobile First” is so ubiquitous that it’s usually one of the “skills” questions a hiring manager will ask. So surely any alternative must be wrong, shouldn’t it? This is usually the part where people shake their heads at me whilst uttering mobile first over and over.

Okay, so we’re going to break through the mobile first dogma and compartmentalize all our styles into the relevant media queries. What we’re now left with is pure generic styles declared on a CSS selector, with all other device specific styles encapsulated in media queries that only apply to the relevant screen dimensions. We now have Generic First CSS:

.bio { display: block; width: 100%; @include media('>=0', '<small') { padding: 20px; margin: 20px 0; } @include media('>=small', '<medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', '<large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', '<huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }

Fig.3. An example of Generic First CSS

Yes, there are slightly more media queries, however, I see this as a benefit, any developer can now looks at this CSS and see exactly what styles are applied at each and every screen size without the cognitive overhead of having to pick apart media-query specificity.

This can be great for people unfamiliar with the code base or even the future you!

When Not To Compartmentalize

There are still times when media query compartmentalization is a burden, and in some cases a good old >= media query is fine. Remember, all we’re trying to do is avoid property overwrites.

Dev Tool Bliss

One major unintended consequence of writing compartmentalized Generic First CSS is the experience you will get from your developer tools style panel. Without the media query cascade, you will now have a clearer overview of which styles are applied — You won’t have a style panel full of struck-out declarations from overwritten media query rules — The noise is gone! This — for me — is one of the biggest benefits of the Generic First CSS technique. It brings a little extra sanity to the CSS debugging experience, and this is worth its weight in gold. Thank me later.

Fig.4. How generic first, compartmentalized css can help bring joy and sanity to your dev console. (Large preview) Performance Implications

So all these Generic First CSS benefits are starting to sound pretty good, but I think there is one last key question that I think needs to be addressed. It’s on the subject of performance optimization. Now I don’t know for certain yet, but I have an inkling that fully compartmentalized media queries may have a slight performance benefit.

Browsers perform a rendering task called computed style calculation. It’s the browsers way of calculating which styles need to be applied to an element at any given moment. This task is always performed on initial page load, but it can also be performed if page content changes or if other browser actions take place. Any boost you can give to the speed of the process is going to be great for initial page load, and it could have a compound effect on the lifecycle of your websites pages.

So going back to generic first CSS: Are there any performance issues related to the browser having to work out the CSS specificity of a multitude of cascading media queries?

To answer that, I’ve devised a test case that can be used to measure any speed benefits or indeed drawbacks.

The Test Case

The test case is comprised of a basic HTML page that outputs a “bio” block 5000 times, the markup is the same for each block, but the classes are slightly different (numeric differentiator), the CSS for this block is also outputted 5000 times, with class names being the only thing to differ. The outputted CSS is piped through a tool called CSS MQPacker, this helps dramatically reduce file size of CSS that uses a lot of inline media queries by combining all the separate instances of a specific media query into one — It’s a great tool that will probably benefit most modern CSS codebases — I’ve used it as a standalone cli tool via a npm task in the test projects package.json, you can also use it as a postcss plugin, which is nice and convenient!

The first test case is a mobile-first cascading media queries example, the second test case is a generic first compartmentalized variant of the CSS. The CSS for these cases is a little verbose and could probably be written in much more concise terms, but it really just serves as a rough example to test the argument.

The test was run 20 times for each CSS variation in desktop Google Chrome v70, not a massive set of data, but enough to give me a rough idea of a performance gain/loss.

The test metrics I have chosen to use are:

  • Overall page load time
    A basic metric to check page load time using the Performance API markers in the the start of the <head> and very end of <body>
  • The Recalculate Style
    Time from within the dev tools performance pane.
  • The Overall Page Rendering
    Time from within the dev tools performance pane.
Fig.5. The key metric being measured is “Recalculate Style”. (Large preview)

Results Table (all times in milliseconds)

@media all and (max-width: 799px) { .break-out { display: none; } } @media all and (min-width: 800px) { .mobiletable { display: none; } @media all and (max-width: 1099px) { .pfix { margin-top: -12em;" } }

Mobile First Generic First Load time Calculate styles Total render time Load time Calculate styles Total render time 1135 565.7 1953 1196 536.9 2012 1176 563.5 1936 1116 506.9 1929 1118 563.1 1863 1148 514.4 1853 1174 568.3 1929 1124 507.1 1868 1204 577.2 1924 1115 518.4 1854 1155 554.7 1991 1177 540.8 1905 1112 554.5 1912 1111 504.3 1886 1110 557.9 1854 1104 505.3 1954 1106 544.5 1895 1148 525.4 1881 1162 559.8 1920 1095 508.9 1941 1146 545.9 1897 1115 504.4 1968 1168 566.3 1882 1112 519.8 1861 1105 542.7 1978 1121 515.7 1905 1123 566.6 1970 1090 510.7 1820 1106 514.5 1956 1127 515.2 1986 1135 575.7 1869 1130 504.2 1882 1164 545.6 2450 1169 525.6 1934 1144 565 1894 1092 516 1822 1115 554.5 1955 1091 508.9 1986 1133 554.8 2572 1001 504.5 1812 AVG 1139.55 557.04 1980 1119.1 514.67 1903.15

Mobile First Load time Calculate styles Total render time 1135 565.7 1953
1118 563.1 1863 1174 568.3 1929
1112 554.5 1912
1105 542.7 1978
1106 514.5 1956
1164 545.6 2450
1115 554.5 1955

Generic First Load time Calculate styles Total render time 1196 536.9 2012 1148 514.4 1853 1124 507.1 1868 1111 504.3 1886 1121 515.7 1905 1127 515.2 1986 1169 525.6 1934 1091 508.9 1986

Fig.6. 20 test runs measuring key load/render metrics of mobile first vs generic first CSS.

From my admittedly small dataset, it does seem like my initial suspicion may be correct. On average, I see the Style Recalculation task take 42ms less time which is a 7.6% speed increase, and therefore the overall rendering time also decreases. The difference isn’t mind-blowing, but it is an improvement. I don’t think the dataset is big enough to be 100% conclusive and the test case is a little unrealistic, but I’m very glad not to be seeing a performance degradation.

I would be very interested to see the generic first methodology applied to a real-world existing codebase that has been written in the mobile-first way — the before after metrics would be much more realistic to everyday practice.

And if anyone has suggestions on how to automate this test over a broader set of iterations, please let me know in the comments! I’d imagine there must be a tool that can do this.

Conclusion

To recap on the benefits of this new development methodology...

  • CSS that does exactly as intended, no second guessing;
  • Self-documenting media-queries;
  • A better dev tools experience;
  • Pages that render faster.

I’d like to think I’m not the only person espousing the writing of CSS in this style. If you have already adopted the generic first mindset, hurray! But if not, I think you’ll really like the benefits it brings. I’ve personally benefited greatly from the uncluttered dev tools experience, which in itself will be a huge positive to a lot of devs. the self-documenting nature of this way of writing your media-queries will also have benefits to yourself and the wider team (if you have one). And finally, these benefits won’t cost you anything in performance terms, and in fact have been shown to have marginal speed gains!

Final Word

Like all development methodologies, it may not be for everyone, but I’ve fallen into Generic First CSS quite naturally, I now see it as a valuable way of working that gives me all the benefits of mobile first with some positive new additions that make the tough job of front-end development that little be easier.

Resources Test Case Repo

If you’d like to fire up the test case and give it a go yourself, you can find it on GitHub, I’d love to see some reports from others.

Tools (dm, ra, yk, il)
Categories: Around The Web

Writing A Multiplayer Text Adventure Engine In Node.js

Smashing Magazine - Thu, 12/20/2018 - 8:05am
Writing A Multiplayer Text Adventure Engine In Node.js Writing A Multiplayer Text Adventure Engine In Node.js Fernando Doglio 2018-12-20T14:05:34+01:00 2019-01-14T08:33:56+00:00

Text adventures were one of the first forms of digital role-playing games out there, back when games had no graphics and all you had was your own imagination and the description you read on the black screen of your CRT monitor.

If we want to get nostalgic, maybe the name Colossal Cave Adventure (or just Adventure, as it was originally named) rings a bell. That was the very first text adventure game ever made.

A picture of an actual text adventure from back in the day. (Large preview)

The image above is how you’d actually see the game, a far cry from our current top AAA adventure games. That being said, they were fun to play and would steal hundreds of hours of your time, as you sat in front of that text, alone, trying to figure out how to beat it.

Understandably so, text adventures have been replaced over the years by games that present better visuals (although, one could argue that a lot of them have sacrificed story for graphics) and, especially in the past few years, the increasing ability to collaborate with other friends and play together. This particular feature is one that the original text adventures lacked, and one that I want to bring back in this article.

Our new book, in which Alla Kholmatova explores how to create effective and maintainable design systems to design great digital products. Meet Design Systems, with common traps, gotchas and the lessons Alla has learned over the years.

Table of Contents → Our Goal

The whole point of this endeavour, as you have probably guessed by now from the title of this article, is to create a text adventure engine that allows you to share the adventure with friends, enabling you to collaborate with them similarly to how you would during a Dungeons & Dragons game (in which, just like with the good ol’ text adventures, there are no graphics to look at).

In creating the engine, the chat server and the client is quite a lot of work. In this article, I’ll be showing you the design phase, explaining things like the architecture behind the engine, how the client will interact with the servers, and what the rules of this game will be.

Just to give you some visual aid of what this is going to look like, here is my goal:

General wireframe for the final UI of the game client (Large preview)

That is our goal. Once we get there, you’ll have screenshots instead of quick and dirty mockups. So, let’s get down with the process. The first thing we’ll cover is the design of the whole thing. Then, we’ll cover the most relevant tools I’ll be using to code this. Finally, I’ll show you some of the most relevant bits of code (with a link to the full repository, of course).

Hopefully, by the end, you’ll find yourself creating new text adventures to try them out with friends!

Design Phase

For the design phase, I’m going to cover our overall blueprint. I’ll try my best not to bore you to death, but at the same time, I think it’s important to show some of the behind-the-scenes stuff that needs to happen before laying down your first line of code.

The four components I want to cover here with a decent amount of detail are:

  • The engine
    This is going to be the main game server. The game rules will be implemented here, and it’ll provide a technologically agnostic interface for any type of client to consume. We’ll implement a terminal client, but you could do the same with a web browser client or any other type you’d like.
  • The chat server
    Because it’s complex enough to have its own article, this service is also going to have its own module. The chat server will take care of letting players communicate with each other during the game.
  • The client
    As stated earlier, this will be a terminal client, one that, ideally, will look similar to the mockup from earlier. It will make use of the services provided by both the engine and the chat server.
  • Games (JSON files)
    Finally, I’ll go over the definition of the actual games. The whole point of this is to create an engine that can run any game, as long as your game file complies with the engine’s requirements. So, even though this will not require coding, I’ll explain how I’ll structure the adventure files in order to write our own adventures in the future.
The Engine

The game engine, or game server, will be a REST API and will provide all of the required functionality.

I went for a REST API simply because — for this type of game — the delay added by HTTP and its asynchronous nature will not cause any trouble. We will, however, have to go a different route for the chat server. But before we start defining endpoints for our API, we need to define what the engine will be capable of. So, let’s get to it.

Feature Description Join a game A player will be able to join a game by specifying the game’s ID. Create a new game A player can also create a new game instance. The engine should return an ID, so that others can use it to join. Return scene This feature should return the current scene where the party is located. Basically, it’ll return the description, with all of the associated information (possible actions, objects in it, etc.). Interact with scene This is going to be one of the most complex ones, because it will take a command from the client and perform that action — things like move, push, take, look, read, to name just a few. Check inventory Although this is a way to interact with the game, it does not directly relate to the scene. So, checking the inventory for each player will be considered a different action. A Word About Movement

We need a way to measure distances in the game because moving through the adventure is one of the core actions a player can take. We will be using this number as a measure of time, just to simplify the gameplay. Measuring time with an actual clock might not be the best, considering these type of games have turn-based actions, such as combat. Instead, we’ll use distance to measure time (meaning that a distance of 8 will require more time to traverse than one of 2, thus allowing us to do things like add effects to players that last for a set amount of “distance points”).

Another important aspect to consider about movement is that we’re not playing alone. For simplicity’s sake, the engine will not let players split the party (although that could be an interesting improvement for the future). The initial version of this module will only let everyone move wherever the majority of the party decides. So, moving will have to be done by consensus, meaning that every move action will wait for the majority of the party to request it before taking place.

Combat

Combat is another very important aspect of these types of games, and one that we’ll have to consider adding to our engine; otherwise, we’ll end up missing on some of the fun.

This is not something that needs to be reinvented, to be honest. Turn-based party combat has been around for decades, so we’ll just implement a version of that mechanic. We’ll be mixing it up with the Dungeons & Dragons concept of “initiative”, rolling a random number in order to keep the combat a bit more dynamic.

In other words, the order in which everyone involved in a fight gets to pick their action will be randomized, and that includes the enemies.

Finally (although I’ll go over this in more detail below), you’ll have items that you can pick up with a set “damage” number. These are the items you’ll be able to use during combat; anything that doesn’t have that property will cause 0 damage to your enemies. We’ll probably add a message when you try to use those objects to fight, so that you know that what you’re trying to do makes no sense.

Client-Server Interaction

Let’s see now how a given client would interact with our server using the previously defined functionality (not thinking about endpoints yet, but we’ll get there in a sec):

(Large preview)

The initial interaction between the client and the server (from the point of view of the server) is the start of a new game, and the steps for it are as follows:

  1. Create a new game.
    The client requests the creation of a new game from the server.
  2. Create chat room.
    Although the name doesn’t specify it, the server is not just creating a chatroom in the chat server, but also setting up everything it needs in order to allow a set of players to play through an adventure.
  3. Return game’s meta data.
    Once the game has been created by the server and the chat room is in place for the players, the client will need that information for subsequent requests. This will mostly be a set of IDs the clients can use to identify themselves and the current game they want to join (more on that in a second).
  4. Manually share game ID.
    This step will have to be done by the players themselves. We could come up with some sort of sharing mechanism, but I will leave that on the wish list for future improvements.
  5. Join the game.
    This one is pretty straightforward. Ince everyone has the game ID, they’ll join the adventure using their client applications.
  6. Join their chat room.
    Finally, the players’ client apps will use the game’s metadata to join their adventure’s chat room. This is the last step required pre-game. Once this is all done, then the players are ready to start adventuring!
Action order for an existing game (Large preview)

Once the prerequisites have all been met, players can start playing the adventure, sharing their thoughts through the party chat, and advancing the story. The diagram above shows the four steps required for that.

The following steps will run as part of the game loop, meaning that they will be repeated constantly until the game ends.

  1. Request scene.
    The client app will request the metadata for the current scene. This is the first step in every iteration of the loop.
  2. Return the meta data.
    The server will, in turn, send back the metadata for the current scene. This information will include things like a general description, the objects found inside it, and how they relate to each other.
  3. Send command.
    This is where the fun begins. This is the main input from the player. It’ll contain the action they want to perform and, optionally, the target of that action (for example, blow candle, grab rock, and so on).
  4. Return the reaction to the command sent.
    This could simply be step two, but for clarity, I added it as an extra step. The main difference is that step two could be considered the beginning of this loop, whereas this one takes into account that you’re already playing, and, thus, the server needs to understand who this action is going to affect (either a single player or all players).

As an extra step, although not really part of the flow, the server will notify clients about status updates that are relevant to them.

The reason for this extra recurring step is because of the updates a player can receive from the actions of other players. Recall the requirement for moving from one place to another; as I said before, once the majority of the players have chosen a direction, then all players will move (no input from all players is required).

The interesting bit here is that HTTP (we’ve already mentioned that the server is going to be a REST API) does not allow for this type of behavior. So, our options are:

  1. perform polling every X amount of seconds from the client,
  2. use some sort of notification system that works in parallel with the client-server connection.

In my experience, I tend to prefer option 2. In fact, I would (and will for this article) use Redis for this kind of behavior.

The following diagram demonstrates the dependencies between services.

Interactions between an client app and the game engine (Large preview) The Chat Server

I will leave the details of the design of this module for the development phase (which is not a part of this article). That being said, there are things we can decide.

One thing we can define is the set of the restrictions for the server, which will simplify our work down the line. And if we play our cards right, we might end up with a service that provides a robust interface, thus allowing us to, eventually, extend or even change the implementation to provide fewer restrictions without affecting the game at all.

  • There will be only one room per party.
    We will not let subgroups be created. This goes hand in hand with not letting the party split. Maybe once we implement that enhancement, allowing for subgroup and custom chat room creation would be a good idea.
  • There will be no private messages.
    This is purely for simplification purposes, but having a group chat is already good enough; we don’t need private messages right now. Remember that whenever you’re working on your minimum viable product, try to avoid going down the rabbit hole of unnecessary features; it’s a dangerous path and one that is hard to get out of.
  • We will not persist messages.
    In other words, if you leave the party, you’ll lose the messages. This will hugely simplify our task, because we won’t have to deal with any type of data storage, nor will we have to waste time deciding on the best data structure to store and recover old messages. It’ll all live in memory, and it will stay there for as long as the chat room is active. Once it’s closed, we’ll simply say goodbye to them!
  • Communication will be done over sockets.
    Sadly, our client will have to handle a double communication channel: a RESTful one for the game engine and a socket for the chat server. This might increase the complexity of the client a bit, but at the same time, it will use the best methods of communication for every module. (There is no real point in forcing REST on our chat server or forcing sockets on our game server. That approach would increase the complexity of the server-side code, which is the one also handling the business logic, so let’s focus on that side for now.)

That’s it for the chat server. After all, it will not be complex, at least not initially. There is more to do when it’s time to start coding it, but for this article, it is more than enough information.

The Client

This is the final module that requires coding, and it is going to be our dumbest one of the lot. As a rule of thumb, I prefer to have my clients dumb and my servers smart. That way, creating new clients for the server becomes much easier.

Just so we’re on the same page, here is the high-level architecture that we should end up with.

Final high level architecture of the entire development (Large preview)

Our simple ClI client will not implement anything very complex. In fact, the most complicated bit we’ll have to tackle is the actual UI, because it’s a text-based interface.

That being said, the functionality that the client application will have to implement is as follows:

  1. Create a new game.
    Because I want to keep things as simple as possible, this will only be done through the CLI interface. The actual UI will only be used after joining a game, which brings us to the next point.
  2. Join an existing game.
    Given the game’s code returned from the previous point, players can use it to join in. Again, this is something you should be able to do without a UI, so this functionality will be part of the process required to start using the text UI.
  3. Parse game definition files.
    We’ll discuss these in a bit, but the client should be able to understand these files in order to know what to show and know how to use that data.
  4. Interact with the adventure.
    Basically, this gives the player the ability to interact with the environment described at any given time.
  5. Maintain an inventory for each player.
    Each instance of the client will contain an in-memory list of items. This list is going to be backed up.
  6. Support chat.
    The client app needs to also connect to the chat server and log the user into the party’s chat room.

More on the client’s internal structure and design later. In the meantime, let’s finish the design stage with the last bit of preparation: the game files.

The Game: JSON Files

This is where it gets interesting because up to now, I’ve covered basic microservices definitions. Some of them might speak REST, and others might work with sockets, but in essence, they’re all the same: You define them, you code them, and they provide a service.

For this particular component, I’m not planning on coding anything, yet we need to design it. Basically, we’re implementing a sort of protocol for defining our game, the scenes inside it and everything inside them.

If you think about it, a text adventure is, at its core, basically a set of rooms connected to each other, and inside them are “things” you can interact with, all tied together with a, hopefully, decent story. Now, our engine will not take care of that last part; that part will be up to you. But for the rest, there is hope.

Now, going back to the set of interconnected rooms, that to me sounds like a graph, and if we also add the concept of distance or movement speed that I mentioned earlier, we have a weighted graph. And that is just a set of nodes that have a weight (or just a number — don’t worry about what it’s called) that represents that path between them. Here is a visual (I love learning by seeing, so just look at the image, OK?):

A weighted graph example (Large preview)

That’s a weighted graph — that’s it. And I’m sure you’ve already figured it out, but for the sake of completeness, let me show you how you would go about it once our engine is ready.

Once you start setting up the adventure, you’ll create your map (like you see on the left of the image below). And then you’ll translate that into a weighted graph, as you can see on the right of the image. Our engine will be able to pick it up and let you walk through it in the right order.

Example graph for a given dungeon (Large preview)

With the weighted graph above, we can make sure players can’t go from the entrance all the way to the left wing. They would have to go through the nodes in between those two, and doing so will consume time, which we can measure using the weight from the connections.

Now, onto the “fun” part. Let’s see how the graph would look like in JSON format. Bear with me here; this JSON will contain a lot of information, but I’ll go through as much of it as I can:

{ "graph": [ { "id": "entrance", "name": "Entrance", "north": { "node": "1stroom", "distance": 1 } }, { "id": "1st room", "name": "1st Room", "south": {"node": "entrance", "distance": 1} , "north": { "node": "bigroom", "distance": 1} } , { "id": "bigroom", "name": "Big room", "south": { "node": "1stroom", "distance": 1}, "north": { "node": "bossroom", "distance": 2}, "east": { "node": "rightwing", "distance": 3} , "west": { "node": "leftwing", "distance": 3} }, { "id": "bossroom", "name": "Boss room", "south": {"node": "bigroom", "distance": 2} } { "id": "leftwing", "name": "Left Wing", "east": {"node": "bigroom", "distance": 3} } { "id": "rightwing", "name": "Right Wing", "west": { "node": "bigroom", "distance": 3 } } ], "game": { "win-condition": { "source": "finalboss", "condition": { "type": "comparison", "left": "hp", "right": "0", "symbol": "<=" } }, "lose-condition": { "source": "player", "condition": { "type": "comparison", "left": "hp", "right": "0", "symbol": "<=" } } }, "rooms": { "entrance": { "description": { "default": "You're at the entrance of the dungeon. There are two lit torches on each wall (one on your right and one on your left). You see only one path: ahead." }, "items": [ { "id": "littorch1", "name": "Lit torch on the right", "triggers": [ { "action": "grab", //grab Lit torch on the right "effect":{ "statusUpdate": "has light", "target": "game", } } ] , "destination": "hand" }, { "id": "littorch2", "name": "Lit torch on the left", "triggers": [ { "action": "grab", //grab Lit torch on the left "effect":{ "statusUpdate": "has light", "target": "game", } } ] , "destination": "hand" } ] }, "1stroom": { "description": { "default": "You're in a very dark room. There are no windows and no source of light, other than the one at the entrance. You get the feeling you're not alone here.", "conditionals": { "has light": "The room you find yourself in appears to be empty, aside from a single chair in the right corner. There appears to be only one way out: deeper into the dungeon." } }, "items": [ { "id": "chair", "name": "Wooden chair", "details": "It's a wooden chair, nothing fancy about it. It appears to have been sitting here, untouched, for a while now.", "subitems": [ { "id": "woodenleg", "name": "Wooden leg", "triggeractions": [ { "action": "break", "target": "chair"}, //break { "action": "throw", "target": "chair"} //throw ], "destination": "inventory", "damage": 2 } ] } ] }, "bigroom": { "description": { "default": "You've reached the big room. On every wall are torches lighting every corner. The walls are painted white, and the ceiling is tall and filled with painted white stars on a black background. There is a gateway on either side and a big, wooden double door in front of you." }, "exits": { "north": { "id": "bossdoor", "name": "Big double door", "status": "locked", "details": "A aig, wooden double door. It seems like something big usually comes through here."} }, "items": [] }, "leftwing": { "description": { "default": "Another dark room. It doesn't look like it's that big, but you can't really tell what's inside. You do, however, smell rotten meat somewhere inside.", "conditionals": { "has light": "You appear to have found the kitchen. There are tables full of meat everywhere, and a big knife sticking out of what appears to be the head of a cow." } }, "items": [ { "id": "bigknife", "name": "Big knife", "destination": "inventory", "damage": 10} ] }, "rightwing": { "description": { "default": "This appear to be some sort of office. There is a wooden desk in the middle, torches lighting every wall, and a single key resting on top of the desk." }, "items": [ { "id": "key", "name": "Golden key", "details": "A small golden key. What use could you have for it?", "destination": "inventory", "triggers": [{ "action": "use", //use on north exit (contextual) "target": { "room": "bigroom", "exit": "north" }, "effect": { "statusUpdate": "unlocked", "target": { "room": "bigroom", "exit": "north" } } } ] } ] }, "bossroom": { "description": { "default": "You appear to have reached the end of the dungeon. There are no exits other than the one you just came in through. The only other thing that bothers you is the hulking giant looking like it's going to kill you, standing about 10 feet from you." }, "npcs": [ { "id": "finalboss", "name": "Hulking Ogre", "details": "A huge, green, muscular giant with a single eye in the middle of his forehead. It doesn't just look bad, it also smells like hell.", "stats": { "hp": 10, "damage": 3 } } ] } } }

I know it looks like a lot, but if you boil it down to a simple description of the game, you have a dungeon comprising six rooms, each one interconnected with others, as shown in the diagram above.

Your task is to move through it and explore it. You’ll find there are two different places where you can find a weapon (either in the kitchen or in the dark room, by breaking the chair). You will also be confronted with a locked door; so, once you find the key (located inside the office-like room), you’ll be able to open it and fight the boss with whatever weapon you’ve collected.

You will either win by killing it or lose by getting killed by it.

Let’s now get into a more detailed overview of the entire JSON structure and its three sections.

Graph

This one will contain the relationship between the nodes. Basically, this section directly translates into the graph we looked at before.

The structure for this section is pretty straightforward. It’s a list of nodes, where every node comprises the following attributes:

  • an ID that uniquely identifies the node among all others in the game;
  • a name, which is basically a human-readable version of the ID;
  • a set of links to the other nodes. This is evidenced by the existence of four possible keys: north”, south, east, and west. We could eventually add further directions by adding combinations of these four. Every link contains the ID of the related node and the distance (or weight) of that relation.
Game

This section will contain the general settings and conditions. In particular, in the example above, this section contains the win and lose conditions. In other words, with those two conditions, we’ll let the engine know when the game can end.

To keep things simple, I’ve added just two conditions:

  • you either win by killing the boss,
  • or lose by getting killed.
Rooms

Here is where most of the 163 lines come from, and it is the most complex of the sections. This is where we’ll describe all of the rooms in our adventure and everything inside them.

There will be a key for every room, using the ID we defined before. And every room will have a description, a list of items, a list of exits (or doors) and a list of non-playable characters (NPCs). Out of those properties, the only one that should be mandatory is the description, because that one is required for the engine to let you know what you’re seeing. The rest of them will only be there if there is something to show.

Let’s look into what these properties can do for our game.

The Description

This item is not as simple as one might think, because your view of a room can change depending on different circumstances. If, for example, you look at the description of the first room, you’ll notice that, by default, you can’t see anything, unless of course, you have a lit torch with you.

So, picking up items and using them might trigger global conditions that will affect other parts of the game.

The Items

These represent all the things” you can find inside a room. Every item shares the same ID and name that the nodes in the graph section had.

They will also have a “destination” property, which indicates where that item should be stored, once picked up. This is relevant because you will be able to have only one item in your hands, whereas you’ll be able to have as many as you’d like in your inventory.

Finally, some of these items might trigger other actions or status updates, depending on what the player decides to do with them. One example of this are the lit torches from the entrance. If you grab one of them, you’ll trigger a status update in the game, which in turn will make the game show you a different description of the next room.

Items can also have “subitems”, which come into play once the original item gets destroyed (through the “break” action, for example). An item can be broken down into several ones, and that is defined in the “subitems” element.

Essentially, this element is just an array of new items, one that also contains the set of actions that can trigger their creation. This basically opens up the possibility to create different subitems based on the actions you perform on the original item.

Finally, some items will have a “damage” property. So, if you use an item to hit an NPC, that value will be used to subtract life from them.

The Exits

This is simply a set of properties indicating the direction of the exit and the properties of it (a description, in case you want to inspect it, its name and, in some cases, its status).

Exits are a separate entity from items because the engine will need to understand if you can actually traverse them based on their status. Exits that are locked will not let you go through them unless you work out how to change their status to unlocked.

The NPCs

Finally, NPCs will be part of another list. They are basically items with statistics that the engine will use to understand how each one should behave. The ones we’ve defined in our example are “hp”, which stands for health points, and “damage”, which, just like the weapons, is the number that each hit will subtract from the player’s health.

That is it for the dungeon I created. It is a lot, yes, and in the future I might consider creating a level editor of sorts, to simplify the creation of the JSON files. But for now, that won’t be necessary.

In case you haven’t realized it yet, the main benefit of having our game defined in a file like this is that we’ll be able to switch JSON files like you did cartridges back in the Super Nintendo era. Just load up a new file and start a new adventure. Easy!

Closing Thoughts

Thanks for reading thus far. I hope you’ve enjoyed the design process I go through to bring an idea to life. Remember, though, that I’m making this up as I go, so we might realize later that something we defined today isn’t going to work, in which case we’ll have to backtrack and fix it.

I’m sure there are a ton of ways to improve the ideas presented here and to make one hell of an engine. But that would require a lot more words than I can put into an article without making it boring for everyone, so we’ll leave it at that for now.

(rb, ra, al, il)
Categories: Around The Web
Syndicate content