Tag: read

Read Your Website

When’s the last time you read your website? Like out loud in the lobby of a Starbucks on a weekday afternoon, over the phone to your parents, or perhaps even as a bedtime story for your kids.

No worries, this isn’t a trick question or anything—just a gut check.

If there’s only one thing you can do to make your website better, then you could do a heckuva lot worse than taking some time to read it. Seriously, do more than look at the words—read them and take in everything that’s being said from the top to the very bottom. And really get in there. I’m talking about opening up everything in the navigation, expanding accordions, opening modals, and taking it all in. Read it the way Wendy’s makes their burgers: no cut corners or nothing.

Top view of a grill showing 12 square burger patties cooking.
Credit: mashed.com

Content: All hail the… king?

I’ve heard for years that content is capital “K” King of the capital “W” Web. In my personal experience, though, I routinely see content treated more as a pauper in projects; the lowest rung of the web ladder saved as an afterthought for when everything else is done. FPO all over. It’s not so much that no one cares about what the website says, but that a great deal of attention and effort is placed on design and architecture (among other things, of course), to the extent that there’s little-to-no time to drive an effective strategy for content.

But again, that’s just my experience, and there have certainly been exceptions to that rule.

The problem, I think, is that we know just how effective good content is but often lack the confidence, tooling, and even a clear understanding of content’s role on the web.

Content is problem solving

When crafted with care, content becomes much more than strings of text. That’s because content is more than what we see on the front end. It is in the alt attributes we write. It’s also the structured data in the document <head>. Heck, we sometimes even generate it in the CSS content property.

We start to see the power of content when we open up our understanding of what it is, what it does, and where it’s used. That might make content one of the most extensible problem-solving tools in your metaphorical shed—it makes sites more accessible, extracts Google-juicing superpowers, converts sales, and creates pathways for users to accomplish what they need to do.

Content wants to be seen

Content is like my five-year old daughter: it hates being in the dark. I’d argue there’s little else that’s more defeating to content than hiding it. Remember our metaphorical tool shed? Content is unable to solve problems when it’s out of sight. Content is that cool dorm room poster you couldn’t wait to hang up the moment you stepped foot on campus—show it off, let it do its thing.

The way I see it, if something is important enough to type, then it’s probably important enough to show it too. That means avoiding anything that might obstruct it from a user’s view, like against a background with poor contrast or content that overflows a container. Content is only as good as it is presented. Your website could sport the greatest word-smithing of all time, but it’s no good if it’s hidden. Content wants to be seen.

Are there times when it’s legitimately fine for content to be unseen? You betcha. Skip to content links, for one. I’m not once of those armchair designers (wait, aren’t all designers in some sort of chair?) who is going to tell you certain UI elements—like modals, accordions, and carousels—are evil. It’s more about knowing the best way to present content, and sometimes containing it in a collapsed <details>/<summary> element is the best call.

But please, for the sake of all virtual humanity, use elements to enhance content, not mask its issues.

Content is efficient

They say a picture is worth a thousand words, right? I mean, that’s cool, I guess. But what exactly are those words and who decides what they are? The end-user, of course! Images are mostly subjective like that, which is what makes them a great complement for content. But images as complete content replacement? I imagine there are way more times where pairing content with imagery is more effective than an image alone.

It depends, of course.

Something we can all agree on is that content is way more efficient than most images. For one, there’s less room for ambiguity, making content more efficient to get a point across. Who needs the representation of a thousand words when we can communicate the same thing just as effectively in a few typed words?

Then there are plenty of accessibility considerations to take into account with images. A background image is unable to convey an idea to a screen reader; that is, unless we inline it, set the alt attribute, and use crafty CSS positioning to create some sort of faux background (faukground?). Even then, we’re already dealing with the alt attribute, so we may as well put that content to real use and display it! That’s way more efficient than coding around it.

We haven’t even gotten into how much larger the kilobytes and megabytes of an image file are compared to content bytes, even in an article that’s chock-full of content like this one. And, sure, this warrants a big ol’ caveat in the form of web fonts and the hit those can have on performance, but such is life.

Content and design work better together

Just because I mentioned content being king earlier doesn’t mean I believe it rules everything else. In fact, I find that content relies on design just as much as design relies on content. There is no cage match pitting one against the other in a fight to the death.

The two work hand-in-hand. I’d even go so far as to say that a lot of design is about enhancing what is communicated on a page. There is no upstaging one or the other. Think of content and design as supporting one another, where the sum of both creates a compelling call-to-action, long-form post, hero banner, and so on. We often think of patterns in a design system as a collection of components that are stitched together to create something new. Pairing content and design works much the same way.

So, why are you reading this?

Go read your site… like now. Belt it out loud. Bring it into the light of day and let it be seen and heard. That’s what it’s there for. It’s your friend for making a better site—whether it’s to be more accessible, profitable, performant, findable, and personable. It gets users from Point A to Point B. It’s how we move on the web and how the web is inextricably linked together.

And, please please please, record yourself reading your site out loud. How cool would it be for the comments in this post to be a living collection of celebrating content and letting it be heard!



Some React Blog Posts I’ve Bookmarked and Read Lately

  • The React Hooks Announcement In Retrospect: 2 Years Later — Ryan Carniato considers hooks to be the most significant turning point in front end in the past five years, but he also says hooks have muddied the waters as well.
  • Mediator Component in React — Robin Wieruch’s article made me think just how un-opinionated React is and how architecturally on-your-own you are. It’s tough to find the right abstractions.
  • No One Ever Got Fired for Choosing React — Jake Lazaroff’s article is a good balance to the above. Sometimes you pick a library like React because it solves problems you’re likely to run into and lets you get to work.
  • A React “if component — I kinda like how JSX does conditional rendering, but hey, a lightweight abstraction like this might just float your boat.
  • State of the React Ecosystem in 2021 — Hooks are big. State management is all over the place, and state machines are growing in popularity. webpack is still the main bundler. Everyone is holding their breath about Suspense… so suspenseful.
  • Blitz.js — “The Fullstack React Framework” — interesting to see a framework built on top of another framework (Next.js).
  • Introducing Zero-Bundle-Size React Server Components — Feels like it will be a big deal, but will shine brightest when frameworks and hosts zero-in on offerings around it. I’m sure Vercel and Netlify are all  👀.

The post Some React Blog Posts I’ve Bookmarked and Read Lately appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.


, , , , , , ,

Some Typography Blog Posts I’ve Bookmarked and Read Lately

  • Font-size: An Unexpectedly Complex CSS Property — From Manish Goregaokar in 2017. Of many oddities, I found the one where font: medium monospace renders at 13px where font: medium sans-serif renders at 16px particularly weird.
  • The good line-height — Since CSS supports unitless line-height, you probably shouldn’t be setting a hard number anyway.
  • Time to Say Goodbye to Google Fonts — Simon Wicki doesn’t mean don’t use them, they mean self-host them. Browsers are starting to isolate cache on a per-domain basis so that old argument that you buy speed because “users probably already have it cached” doesn’t hold up. I expected to hear about stuff like having more control over font loading, but this is just about the cache.
  • My Favorite Typefaces of 2020 — John Boardley’s picks for the past year. Have you seen these “color fonts”? They are so cool. Check out LiebeHeide, it looks like real pen-on-paper.
  • How to avoid layout shifts caused by web fonts — We’ve got CLS (Cumulative Layout Shift) now and it’s such an important performance metric that will soon start affecting SEO. And because we have CSS control over font loading via font-display, that means if we set things up such that font loading shifts the page, that’s bad. I like Simon Hearne’s suggestion that we tweak both our custom font and fallback font to match perfectly. I think perfect fallback fonts are one of the best CSS tricks.
  • How to pick a Typeface for User Interface and App Design? — Oliver Schöndorfer makes the case for “functional text” which is everything that isn’t body text (e.g. paragraphs of text) or display text (e.g. headers). “Clarity is key.”

The post Some Typography Blog Posts I’ve Bookmarked and Read Lately appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.


, , , , , , ,

Some Performance Blog Posts I’ve Bookmarked and Read Lately

  • Back/forward cache — I always assumed browsers just do fancy stuff with the back/forward buttons and us developers had very little control. Philip Walton tells us it’s critical that we understand “what makes pages eligible (and ineligible) for bfcache to maximize their cache-hit rates.” For example, if you use the unload event, the page is instantly disqualified from the cache.
  • Big picture performance analysis using Lighthouse Parade — Lighthouse only tests one page of your site. Lighthouse Parade tests all the URLs of a site, and aggregates the results.
  • Beyond fast with new performance features — Jake Archibald gets into the CSS content-visibility property (and a few other things) and how it can lead to incredible performance boosts (you use it to tell the browser that it’s straight-up OK not to render things). Right this minute, content-visiblity makes me nervous as it has issues with scrollbar jankiness and accessiblity problems. I found it a smidge confusing at first glance, and Tim Kadlec has reservations.
  • Image Decode & Visual Timings — Image performance isn’t only about the size of the image. Different formats take different amounts of time to decode and render. GIF never wins.
  • How to increase CSS-in-JS performance by 175x — The trick, readers, is shipping CSS. You can still use CSS-in-JS as you author, and have the build process create the CSS. They call that “Zero-Runtime” like Linaria.
  • Testing Performance — Kelly Sutton: “The best approach that I have found to preventing performance regressions is to employ qualitative assessments of the code.” Performance is such an unwieldy beast, that only in production will you truly know what happens.
  • Front-End Performance Checklist 2021 — If you’re going to get serious about performance this year, you’d do well to dig into Vitaly’s guide.
  • We rendered a million web pages to find out what makes the web slow — HTTP/2 is a huge indicator of good performance.

The post Some Performance Blog Posts I’ve Bookmarked and Read Lately appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.


, , , , , , ,

Read Me!

A fancy experiential essay from the team at Readymag, which is a tool for building… fancy experiential essays, about fancy experiential essays:

With all the technology addressing readability issues, it’s still design basics that distinguish a readable text from one that isn’t. Here are some simple rules we use ourselves when developing engaging texts and layouts.

I like this advice:

Always start with quality writing.

I find that it’s not only longform that inspires a fancy “art directed” post around here, but quality writing.

I can’t decide if I like that the URL changes as you scroll down the article. Seems a little better suited to hash links.

Direct Link to ArticlePermalink

The post Read Me! appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.



​​Avoiding those dang cannot read property of undefined errors

​​​​Uncaught TypeError: Cannot read property 'foo' of undefined.​ The dreaded error we all hit at some point in JavaScript development. Could be an empty state from an API that returns differently than you expected. Could be something else. We don’t know because the error itself is so general and broad.

​​I recently had an issue where certain environment variables weren’t being pulled in for one reason or another, causing all sorts of funkiness with that error staring me in the face. Whatever the cause, it can be a disastrous error if it’s left unaccounted for, so how can we prevent it in the first place?

​​Let’s figure it out.

​​Utility library

​​If you are already using a utility library in your project, there is a good chance that it includes a function for preventing this error. _.get​ in lodash​ (docs) or R.path in Ramda​ (docs) allow accessing the object safely.
​​If you are already using a utility library, this is likely the simplest solution. If you are not using a utility library, read on!


Short-circuiting with &&

​​​​One interesting fact about logical operators in JavaScript is that they don’t always return a boolean. According to the spec, “the value produced by a &&​ or ||​ operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.”
​​​​In the case of the &&​ operator, the first expression will be used if it a “falsy” value. Otherwise, the second expression will be used. This means that the expression 0 && 1​ will be evaluated as 0​ (a falsy value), and the expression 2 && 3​ will be evaluated as 3​. If multiple &&​ expressions are chained together, they will evaluate to either the first falsy value or the last value. For example, 1 && 2 && 3 && null && 4​ will evaluate to null​, and 1 && 2 && 3​ will evaluate to 3​.

​​​​How is this useful for safely accessing nested object properties? Logical operators in JavaScript will “short-circuit.” In this case of &&​, this means that the expression will cease moving forward after it reaches its first falsy value.


​​const foo = false && destroyAllHumans(); ​​console.log(foo); // false, and humanity is safe

​​In this example, destroyAllHumans is never called because the &&​ operand stopped all evaluation after false​.

​​This can be used to safely access nested properties.


​​const meals = { ​​  breakfast: null, // I skipped the most important meal of the day! :( ​​  lunch: { ​​    protein: 'Chicken', ​​    greens: 'Spinach', ​​  }, ​​  dinner: { ​​    protein: 'Soy', ​​    greens: 'Kale', ​​  }, ​​}; ​​ ​​const breakfastProtein = meals.breakfast && meals.breakfast.protein; // null ​​const lunchProtein = meals.lunch && meals.lunch.protein; // 'Chicken'

​​Aside from its simplicity, one of the main advantages of this approach is its brevity when dealing with small chains. However, when accessing deeper objects, this can be quite verbose.


const favorites = { ​​  video: { ​​    movies: ['Casablanca', 'Citizen Kane', 'Gone With The Wind'], ​​    shows: ['The Simpsons', 'Arrested Development'], ​​    vlogs: null, ​​  }, ​​  audio: { ​​    podcasts: ['Shop Talk Show', 'CodePen Radio'], ​​    audiobooks: null, ​​  }, ​​  reading: null, // Just kidding -- I love to read ​​}; ​​ ​​const favoriteMovie = favorites.video && favorites.video.movies && favorites.video.movies[0]; ​​// Casablanca ​​const favoriteVlog = favorites.video && favorites.video.vlogs && favorites.video.vlogs[0]; ​​// null

​​The more deeply nested an object is, the more unwieldy it gets.


The “Maybe Monad”

​​Oliver Steele came up with this method and goes through it in much more detail in his blog post, “Monads on the Cheap I: The Maybe Monad.” I will attempt to give a brief explanation here.


const favoriteBook = ((favorites.reading||{}).books||[])[0]; // undefined ​​const favoriteAudiobook = ((favorites.audio||{}).audiobooks||[])[0]; // undefined ​​const favoritePodcast = ((favorites.audio||{}).podcasts||[])[0]; // 'Shop Talk Show'

​​Similar to the short-circuit example above, this method works by checking if a value is falsy. If it is, it will attempt to access the next property on an empty object. In the example above, favorites.reading​ is null​, so the books​ property is being accessed from an empty object. This will result in an undefined​, so the 0​ will likewise be accessed from an empty array.

​​The advantage of this method over the &&​ method is that it avoids repetition of property names. On deeper objects, this can be quite a significant advantage. The primary disadvantage would be readability — it is not a common pattern, and may take a reader a moment to parse out how it is working.​



​​​​try...catch​ statements in JavaScript allow another method for safely accessing properties.


try { ​​  console.log(favorites.reading.magazines[0]); ​​} catch (error) { ​​  console.log("No magazines have been favorited."); ​​}

​​Unfortunately, in JavaScript, try...catch​ statements are not expressions. They do not evaluate to a value as they do in some languages. This prevents a concise try​ statement as a way of setting a variable.

​​One option is to use a let​ variable that is defined in the block above the try...catch​.


let favoriteMagazine; ​​try {  ​​  favoriteMagazine = favorites.reading.magazines[0];  ​​} catch (error) {  ​​  favoriteMagazine = null; /* any default can be used */ ​​};

​​Although it’s verbose, this works for setting a single variable (that is, if the mutable variable doesn’t scare you off). However, issues can arise if they’re done in bulk.


let favoriteMagazine, favoriteMovie, favoriteShow; ​​try { ​​  favoriteMovie = favorites.video.movies[0]; ​​  favoriteShow = favorites.video.shows[0]; ​​  favoriteMagazine = favorites.reading.magazines[0]; ​​} catch (error) { ​​  favoriteMagazine = null; ​​  favoriteMovie = null; ​​  favoriteShow = null; ​​}; ​​ ​​console.log(favoriteMovie); // null ​​console.log(favoriteShow); // null ​​console.log(favoriteMagazine); // null

​​If any of the attempts to access the property fails, this will cause all of them to fall back into their defaults.

​​An alternative is to wrap the try...catch​ in a reusable utility function.


const tryFn = (fn, fallback = null) => { ​​  try { ​​    return fn(); ​​  } catch (error) { ​​    return fallback; ​​  } ​​}  ​​ ​​const favoriteBook = tryFn(() => favorites.reading.book[0]); // null ​​const favoriteMovie = tryFn(() => favorites.video.movies[0]); // "Casablanca"

​​By wrapping the access to the object in a function, you can delay the “unsafe” code and pass it into a try...catch​.

​​A major advantage of this method is how natural it is to access the property. As long as properties are wrapped in a function, they are safely accessed. A default value can also be specified in the case of a non-existent path.

​​Merge with a default object

By merging an object with a similarly shaped object of “defaults,” we can ensure that the path that we are trying to access is safe.

const defaults = { ​​  position: "static", ​​  background: "transparent", ​​  border: "none", ​​}; ​​ ​​const settings = { ​​  border: "1px solid blue", ​​}; ​​ ​​const merged = { ...defaults, ...settings }; ​​ ​​console.log(merged);  ​​/* ​​  { ​​    position: "static", ​​    background: "transparent", ​​    border: "1px solid blue" ​​  } ​​*/

​​Careful, though, because the entire nested object can be overwritten rather than a single property.

const defaults = { ​​  font: { ​​    family: "Helvetica", ​​    size: "12px", ​​    style: "normal", ​​  },         ​​  color: "black", ​​}; ​​ ​​const settings = { ​​  font: { ​​    size: "16px", ​​  } ​​}; ​​ ​​const merged = {  ​​  ...defaults,  ​​  ...settings, ​​}; ​​ ​​console.log(merged.font.size); // "16px" ​​console.log(merged.font.style); // undefined

​​Oh no! To fix this, we’ll need to similarly copy each of the nested objects.


const merged = {  ​​  ...defaults,  ​​  ...settings, ​​  font: { ​​    ...defaults.font, ​​    ...settings.font, ​​  }, ​​}; ​​ ​​console.log(merged.font.size); // "16px" ​​console.log(merged.font.style); // "normal"

​​Much better!

​​This pattern is common with plugins or components that accept a large settings object with included defaults.

​​A bonus about this approach is that, by writing a default object, we’re including documentation on how an object should look. Unfortunately, depending on the size and shape of the data, the “merging” can be littered with copying each nested object.


The future: optional chaining

​​There is currently a TC39 proposal for a feature called “optional chaining.” This new operator would look like this:

​​console.log(favorites?.video?.shows[0]); // 'The Simpsons' ​​console.log(favorites?.audio?.audiobooks[0]); // undefined

​​The ?.​ operator works by short-circuiting: if the left-hand side of the ?.​ operator evaluates to null​ or undefined​, the entire expression will evaluate to undefined​ and the right-hand side will remain unevaluated.

​​To have a custom default, we can use the ||​ operator in the case of an undefined.


console.log(favorites?.audio?.audiobooks[0] || "The Hobbit");


Which method should you use?

​​The answer, as you might have guessed, is that age-old answer… “it depends.” If the optional chaining operator has been added to the language and has the necessary browser support, it is likely the best option. If you are not from the future, however, there are more considerations to take into account. Are you using a utility library? How deeply nested is your object? Do you need to specify defaults? Different cases may warrant a different approach.

The post ​​Avoiding those dang cannot read property of undefined errors appeared first on CSS-Tricks.


, , , , , , ,