Explore My Notes

Convert Markdown to RTF online | Markdown Live Preview

A brilliant tool: paste in some Markdown and it will display the converted Rich Text in the preview window. You can then copy this and paste into any RTF editor and hey presto, no more annoying manual editing 🎉

WCAG 2.2 simplified | Mike Gower

A useful overview of the new success criteria coming in WCAG 2.2 (though the author is quick to note that changes are still at least a little likely).

[I wouldn't normally copy such a large block of text, but as this is a Medium article I don't trust it to stay online.]

Focus Not Obscured (Minimum)

Goal: Keep the focused item visible
What to do: Ensure the item receiving keyboard focus is at least partially visible in the viewport

Focus Not Obscured (Enhanced)

Goal: Keep the focused item entirely visible
What to do: Ensure no content obstructs the item receiving keyboard focus

Focus Appearance

Goal: Make it easier to spot the keyboard focus
What to do: Use a focus indicator of sufficient size and contrast

Dragging Movements

Goal: Don’t rely on dragging for user actions
What to do: Provide a simple pointer alternative to any action that involves dragging

Target Size (Minimum)

Goal: Make controls easier to activate
What to do: Ensure targets meet a minimum size or have sufficient spacing around them

Consistent Help

Goal: Make it easier to find help and support
What to do: Consistently locate any user help that appears on multiple pages

Redundant Entry

Goal: Make it easier for users to complete multi-step processes
What to do: Don’t ask for the same information twice in the same session

Accessible Authentication (Minimum)

Goal: Make logins possible with less mental effort
What to do: Don’t make people memorize or transcribe something in order to log in

Accessible Authentication (Enhanced)

Goal: Make logins possible with less mental effort
What to do: Don’t make people recognize objects or personal information to log in

Performative performance | Adactio

A thoughtful look at the idea of sustainability in web development and design, particularly in terms of whether worrying about an individual design choice's carbon footprint is meaningful or simply obfuscating the much larger issues around server farms, package size, etc.

On greenwashing in web design:

She said that real impact isn’t going to come from individual websites changing their colour schemes. Real impact is going to come from making server farms run on renewable energy.
Most of the important work around energy usage on websites is invisible. It’s the work done to not add more images, more JavaScript or more web fonts.

On why defaults matter and how the invisible work is often more important:

I suspect there might be a similar mindset at work when it comes to interface toggles for low-carbon mode. It might make you feel good. It might make you look good. But it’s a poor substitute for making your website carbon-neutral by default.

The worst programmer | Dan North

A story about how individually-driven KPIs rarely consider team-driven work, despite the fact that the latter is often the key ingredient in building efficient and effective departments.

Specifically, a look at Tim, who consistently scored zero on their internal developer KPI, because they spent their entire time pairing with other developers, and how this work directly improved team morale and code quality across the board in ways that would have not been possible without Tim around:

You see, the reason that Tim’s productivity score was zero, was that he never signed up for any stories. Instead he would spend his day pairing with different teammates.
Tim wasn’t delivering software; Tim was delivering a team that was delivering software. The entire team became more effective, more productive, more aligned, more idiomatic, more fun, because Tim was in the team.

On how moving from individual KPIs to team-focused ones often provide better business value:

... we quietly dropped the individual productivity metrics in favour of team accountability, where we tracked—and celebrated—the business impact we were delivering to the organisation as a high-performing unit.
Just don’t try to measure the individual contribution of a unit in a complex adaptive system, because the premise of the question is flawed.

Contextual advertising | LoFi Codes

A high-level overview of the differences between behavioural and contextual advertising, and some of the (many) advantages of the latter.

I've always felt this was a no-brainer benefit. I remember the days of early online advertising, and the few times those ads worked on me were (in hindsight) all about strong contextual relevance. I wanted to buy certain brands of tech hardware and office equipment because I associated them with specific review sites. The first web host I properly explored purchasing server space with was a regular advertiser on the industry staple A List Apart. I bought my Wacom tablet as a teenager because a webcomic I followed would regularly advertise them, and wouldn't you know it, I wanted to make a webcomic myself. Whereas in the land of behavioural advertising, I'm not sure I can think of a single instance of it truly working.

On the different approaches to online advertising:

Creating profiles about users based on their cookies is called Behavioural Advertising. There's an alternative called Contextual Advertising.
In a nutshell Contextual Advertising looks at the content on the page and allows advertisers to target that, instead of users.

On some of the benefits of removing cookie-based advertising:

With contextual targeting, the publisher would run a single script whenever they create or update content. This means that only once per content change, one script runs and updates one database. Notice this is done on the publisher end, so a user never has to take this cost.
Because no cookies are needed to track the user, this removes a use case for needing a cookie notice.

Zero JavaScript CSS-in-JS | Linaria

One of the core downsides to CSS-in-JS is that you have to compile it on the client, which means increased bundle sizes and slower rendering. Linaria is an attempt to fix that, by providing all of the typical CSS-in-JS DX – nesting, props, functions, exports etc. – but then transpiling that to CSS files during the build step.

Theoretically works with every front-end framework, but there seem to be issues with Next.js, unfortunately.

An open source Postman alternative | Recipe UI

An open-source tool for API testing, with automatic type safety baked in and a much more advanced output UI that highlights contained images, code blocks, messaging etc. whilst still providing the raw response. Best of all: there are both desktop and web interfaces, all free. Effectively a better version of Postman in every way.

Making sense of React Server Components | Josh W. Comeau

A superb breakdown of the changes being made in React 18+ around the new React Server Components paradigm. Josh has a knack for explaining complex problems in simpler ways, and this is no exception; the little graphs showing data flows in the various React paradigms are particularly useful.

On the difference between CSR and SSR, with a bonus explanation of hydration that is clearer than I've ever seen before:

Server Side Rendering was designed to improve this experience. Instead of sending an empty HTML file, the server will render our application to generate the actual HTML. The user receives a fully-formed HTML document.

That HTML file will still include the <script> tag, since we still need React to run on the client, to handle any interactivity. But we configure React to work a little bit differently in-browser: instead of conjuring all of the DOM nodes from scratch, it instead adopts the existing HTML. This process is known as hydration.

On SSR and hydration:

A server generates the initial HTML so that users don't have to stare at an empty white page while the JS bundles are downloaded and parsed. Client-side React then picks up where server-side React left off, adopting the DOM and sprinkling in the interactivity.
The way I see it, “Server Side Rendering” is an umbrella term that includes several different rendering strategies. They all have one thing in common: the initial render happens in a server runtime like Node.js, using the ReactDOMServer APIs. It doesn't actually matter when this happens, whether it's on-demand or at compile-time. Either way, it's Server Side Rendering.

On how SSR feels like it is helping (by presenting a loading state faster) but ultimately doesn't always improve the actual UX (and, arguably, can degrade it in certain scenarios e.g. where loading state is not well conveyed):

[SSR] is an improvement — a shell is better than a blank white page — but ultimately, it doesn't really move the needle in a significant way. The user isn't visiting our app to see a loading screen, they're visiting to see the content (restaurants, hotel listings, search results, messages, whatever).

On how SSR feels a little illogical once you start to graph out the data flows involved:

But doesn't this flow feel a bit silly? When I look at the SSR graph, I can't help but notice that the request starts on the server. Instead of requiring a second round-trip network request, why don't we do the database work during that initial request?

On how Server Components can't have side effects or mutations – they only render once:

The key thing to understand is this: Server Components never re-render. They run once on the server to generate the UI. The rendered value is sent to the client and locked in place. As far as React is concerned, this output is immutable, and will never change.

On the impact of moving logic to a single-render paradigm:

This means that a big chunk of React's API is incompatible with Server Components. For example, we can't use state, because state can change, but Server Components can't re-render. And we can't use effects because effects only run after the render, on the client, and Server Components never make it to the client.

On why the term "Client Component" is a bit confusing:

The name “Client Component” implies that these components only render on the client, but that's not actually true. Client Components render on both the client and the server.

On the fact that "client" is no longer the default:

In this new “React Server Components” paradigm, all components are assumed to be Server Components by default. We have to “opt in” for Client Components.
That standalone string at the top, "use client", is how we signal to React that the component(s) in this file are Client Components

On when to use Client vs. Server Components:

As a general rule, if a component can be a Server Component, it should be a Server Component.
Some of our components will need to run on the client, because they use state variables or effects.

On how state works now, particularly in high-level components like page layouts:

In order to prevent this impossible situation, the React team added a rule: Client Components can only render other Client Components. When we convert a component to a Client Component, it automatically converts its descendants.

On how the React DOM now repopulates itself with the content of Server Components (this feels, well, quite clunky in some ways, and does mean that you still have to ship some JS even though you're fully rendering on the server):

Typically, when React hydrates on the client, it speed-renders all of the components, building up a virtual representation of the application. It can't do that for Server Components, because the code isn't included in the JS bundle.

And so, we send along the rendered value, the virtual representation that was generated on the server. When React loads on the client, it re-uses that description instead of re-generating it.

On some of the core benefits of React Server Components (and the benefits of tools like Bright built to work on the server only):

A proper syntax-highlighting library, with support for all popular programming languages, would be several megabytes, far too large to stick in a JS bundle. As a result, we have to make compromises, trimming out languages and features that aren't mission-critical.

But, suppose we do the syntax highlighting *in a Server Component.* In that case, none of the library code would actually be included in our JS bundles. As a result, we wouldn't have to make any compromises, we could use all of the bells and whistles.

📆 07 Sep 2023  | 🔗

React server components tips | Alex Anderson

A quick overview of React Server Components and some of the mental models that are useful when thinking about how they might be applied, in context.

On how server components now need to be much more granular in what gets put in each file, and how splitting is the new paradigm:

Don’t try to build everything in one component, or even in one file. As soon as you get an inkling that some markup or logic should be in its own component, don’t hesitate - just split it out

On when to use client components rather than server ones:

If you need interactivity, like event handlers, useState, useRef, or useEffect, don’t hesitate to break that component into its own file, and add use client to the top.

On the new hierarchy of server > client components:

Once a client component is rendered on the client, how does it execute that server code? Is the client magically able to make calls to the database? No, that’s silly. One of the immutable rules of RSC is that client components can’t render server components.

On how you can get around that hierarchy (sort of):

But there is a literal loophole in this: Using component composition, you can render a server component on the server, but as a child of a client component. Just like you can pass server-fetched data as props from a server component to a client component, you can pass rendered server components as props to client components too.

On how static components shouldn't automatically be regarded as client components, but rather client status should be a last resort only used where absolutely necessary:

So even if a component isn’t fetching any data, there’s no need to slap a use client at the top of the file. In fact, you should only do that if the component is explicitly using client-only features

Intro to design token schema | James Nash, Louis Chenais

An interesting look at the early draft proposal for an official design token specification and file format. The pitch is a strong one: standardise design tokens so that every tool can understand them, and display them in the most appropriate way. An IDE could show the underlying code; a design tool like Figma could show visual widgets like colour swatches and type hierarchies. Better still, you have one file that all systems ingest, so a change in one place should flood throughout the system: a designer changes a colour token in Figma, the live code updates.

Josh's custom CSS reset | Josh W. Comeau

Josh has added some additional thoughts to Andy's CSS reset. Personally, I like a combination of the two (with a dash of Stephanie's best practices thrown in for good measure), but wanted to capture both for posterity.

On the grandfather of CSS resets by Eric Meyer (which has been my go-to for a while now as well):

For a long time, I used Eric Meyer's famous CSS Reset. It's a solid chunk of CSS, but it's a bit long in the tooth at this point; it hasn't been updated in more than a decade, and a lot has changed since then!

On why images should be block-level rather than inline:

Typically, I treat images the same way I treat paragraphs or headers or sidebars; they're layout elements.
By setting display: block on all images by default, we sidestep a whole category of funky issues.

On a more sensible default for interactive element font styles. Also TIL about the font shorthand property – very clever:

If we want to avoid this auto-zoom behavior, the inputs need to have a font-size of at least 1rem / 16px.
This fixes the auto-zoom issue, but it's a band-aid. Let's address the root cause instead: form inputs shouldn't have their own typographical styles!
font is a rarely-used shorthand that sets a bunch of font-related properties, like font-size, font-weight, and font-family.

And the reset itself:

/*
  Josh's Custom CSS Reset
  https://www.joshwcomeau.com/css/custom-css-reset/
*/

*, *::before, *::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

body {
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}

input, button, textarea, select {
  font: inherit;
}

p, h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}

#root, #__next {
  isolation: isolate;
}

📆 05 Sep 2023  | 🔗

  • HTML & CSS
  • CSS resets
  • form
  • iOS
  • font
  • responsive design 

A modern CSS reset | Andy Bell

Andy always has some interesting thoughts about CSS, and this reset is no exception. Lots of interesting things here that fit very nicely with both my own experience and other resets that I've seen.

On the evolution of CSS resets:

In this modern era of web development, we don’t really need a heavy-handed reset, or even a reset at all, because CSS browser compatibility issues are much less likely than they were in the old IE 6 days.

On line-heights and optimising text rendering:

I only set two text styles. I set the line-height to be 1.5 because the default 1.2 just isn’t big enough to have accessible, readable text. I also set text-rendering to optimizeSpeed.

Using optimizeLegibility makes your text look nicer, but can have serious performance issues such as 30 second loading delays, so I try to avoid that now. I do sometimes add it to sections of microcopy though.
/* Box sizing rules */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Remove default margin */
body,
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd {
  margin: 0;
}

/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
ul[role='list'],
ol[role='list'] {
  list-style: none;
}

/* Set core root defaults */
html:focus-within {
  scroll-behavior: smooth;
}

/* Set core body defaults */
body {
  min-height: 100vh;
  text-rendering: optimizeSpeed;
  line-height: 1.5;
}

/* A elements that don't have a class get default styles */
a:not([class]) {
  text-decoration-skip-ink: auto;
}

/* Make images easier to work with */
img,
picture {
  max-width: 100%;
  display: block;
}

/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
  font: inherit;
}

/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */
@media (prefers-reduced-motion: reduce) {
  html:focus-within {
   scroll-behavior: auto;
  }
  
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Made By Me, But Made Possible By:

CMS:

Build: Gatsby

Deployment: GitHub

Hosting: Netlify

Connect With Me:

Twitter Twitter

Instagram Instragram

500px 500px

GitHub GitHub

Keep Up To Date:

All Posts RSS feed.

Articles RSS feed.

Journal RSS feed.

Notes RSS feed.