I keep forgetting, but the alt attribute of the <img> element is not just useful for users who are visually impaired. It is also useful when the image is not displayed in the browser for whatever reason. For example: the src attribute does not contain a valid path to an image.
John Mayer on how trying and not doing it well enough is a wonderful technique for being yourself:
Failing to sound exactly like the person you want to sound like is a wonderful way to sound like yourself. So I’m not necessarily thinking this thing from scratch, going, Okay, I’m gonna, like, do Jerry-esque things, but I’m still gonna sound like me. No, it’s more like, I want to sound just like Jerry, and then the way I naturally, obviously don’t — that’s your personality. Music doesn’t let you lie. […] You try to sound like who you want to sound like, and you just will always end up sounding like you.
I like this advice. It is an interesting take on the learning by copying method.
While you’re fixing the fun stuff, fix the important stuff too - Piccalilli
Initially, I thought this was just an article on how to fix the janky hover state of a card component. But it also goes over the HTML markup for a typical card component in the context of semantics and accessibility.
Adactio: Journal—Mind set
Ah! Good old Jeremy Keith, insightful and funny.
If I really want to change someone’s mind, then I need to make the effort to first understand their mind. That’s going to be far more productive than declaring that my own mind is made up. After all, if I show no willingness to consider alternative viewpoints, why should they?
There’s an old saying that before criticising someone, you should walk a mile in their shoes. I’m going to try to put that into practice, and not for the two obvious reasons:
- If we still disagree, now we’re a mile away from each other, and
- I’ve got their shoes.
I just purchased Josh Comeau’s new course, Whimsical Animations. The course page itself has some delightful animations.
PS: I also discovered Gochi Hand, a cute handwritten font, on the course page.
Jimmy Kimmel & the FCC: Last Week Tonight with John Oliver (HBO) - YouTube
John Oliver on drawing the line:
Giving the bully your lunch money doesn’t make him go away. It just makes him come back hungrier each time.
Browsing the web - Learn web development | MDN
I really like this explanation of what happens in between the user entering a web address into the browser and the browser displaying the result.
- The web browser requests the resource you want to access from the web server it is stored on.
- If the request is successful, the web server sends a response back to the web browser containing the requested resource.
- In some cases, the requested resource will then fire off more requests, which will result in more responses.
- When all of the resources have been requested, the web browser parses and renders them as required, before displaying the result to the user.
Just like a word document can be displayed in a word processing application, a web page is simply an HTML document that can be displayed in a web browser. The only difference is that a web page can embed a variety of different types of resources such as styles, fonts, images, scripts, and so on.
Stupid #CSS question because I’m losing my mind here: why isn’t calc(.5*a) working? What am I missing? It doesn’t seem to be working in any browser.
Ana is trying to use
calc(.5 * a)as a part of the relative color syntax, presumably to create semi transparent outlines. But it is not working becausecalc(.5 * a)is an invalid property value. As Valtteri Laitinen replied, it should actually bealphain there instead ofa..class {outline-color: rgb(from currentcolor r g b / calc(0.5 * a)); /* ❌ invalid */outline-color: rgb(from currentcolor r g b / calc(0.5 * alpha)); /* ✅ valid */}I re-read Heydon Pickering’s post on the HTML article element in the middle of writing the markup for a new website.
Heydon’s writing is so sharp and funny. Unmistakably theirs. No one else writes quite like them, and I’m here for it.
I was reading Manuel Matuzovic’s article on meta theme color and came across this snippet:
index.html <style>:root {--theme: blue;}</style><meta name="theme-color" content="var(--theme)" />I wish it was possible to access custom properties outside the
<style>tag in the<head>. It would keep things DRY.Sorting strings that contain numbers in JavaScript
Recently, I was reading Jan Miksovsky’s article on how he built a basic static site generator using plain JS with zero dependencies.
While exploring the source code, I noticed the following bit of code:
// For sorting in natural orderconst naturalOrder = new Intl.Collator(undefined, {numeric: true,}).compare;I was totally unaware of the
Intl.CollatorAPI and that it can be used for sorting. This sent me down a bit of a rabbit hole.I learned that my mental model of how JavaScript’s default array
sort()works is wrong. I also learned a counter-intuitive detail about its behavior with numbers. But, most importantly, I learned about better ways to handle sorting correctly in JavaScript, including the neatIntl.CollatorAPI that Jan’s code led me to discover.Consider the following array of numbers:
const array = [9, 8, 7, 60, 5];array.sort();Now, what do you think is the result?
As someone who is not a JavaScript expert, I thought the output would be the following:
Terminal window [5, 7, 8, 9, 60]I was wrong. The correct output is the following:
Terminal window [5, 60, 7, 8, 9]Now, it was important to understand why I was wrong.
The default sorting behaviour
By default, when no compare function is provided, the
sort()method converts each element into a string and then compares these strings character by character based on their sequences of UTF-16 code unit values. (JavaScript strings use the UTF-16 character encoding).When we sort the array in my example using the default
sort(), the numbers are first converted to strings. Then, the comparison starts with the UTF-16 code unit value of the first character of each string. The character ‘6’ in ‘60’ has a UTF-16 code unit value of 54, which is lower than the code unit values for ‘7’ (55), ‘8’ (56), and ‘9’ (57). The rest of the string (‘0’ in ‘60’) is only considered if the first characters are the same. This is why ‘60’ appears before ‘7’, ‘8’, and ‘9’ in the sorted output."5".charCodeAt(0); // Output: 53"60".charCodeAt(0); // Output: 54"7".charCodeAt(0); // Output: 55"8".charCodeAt(0); // Output: 56"9".charCodeAt(0); // Output: 57Sorting Numbers Correctly
If you are specifically sorting an array that contains only numbers, the standard way to achieve correct numeric sorting is to provide a simple compare function:
const numbersArray = [9, 8, 7, 60, 5];numbersArray.sort((a, b) => a - b);// Output: [5, 7, 8, 9, 60]This compare function subtracts
bfroma. If the result is negative,acomes first. If positive,bcomes first. If zero, their order doesn’t change relative to each other. This correctly orders numbers based on their mathematical value.Natural Sorting with the Intl.Collator API
However, the simple
(a - b)approach works reliably only for pure numbers. What about sorting strings that contain numbers, like filenames? This is where theIntl.CollatorAPI with thenumeric: trueoption shines. It provides the natural sorting behavior that correctly handles numbers alongside other characters.const naturalOrder = new Intl.Collator(undefined, {numeric: true,}).compare;// Note: Passing `undefined` as the locale uses the default locale of the browser's runtime.// You could specify a locale string like 'en-US' here if needed.const array = [9, 8, 7, 60, 5];array.sort((a, b) => naturalOrder(a, b));// Output: [5, 7, 8, 9, 60]By passing the
comparemethod of theIntl.Collatorinstance tosort(), we override the default string comparison. TheIntl.Collatorobject, configured withnumeric: true, knows how to compare ‘60’ and ‘7’ such that 60 is treated as a single number and correctly placed after 7, 8, and 9.This API is incredibly useful for sorting strings that contain numbers in a human-expected way, such as lists of filenames like
IMG_1.png,IMG_2.png,IMG_10.png,IMG_20.png.const files = ["IMG_2.png", "IMG_1.png", "IMG_10.png", "IMG_20.png"];files.sort();// Output: ['IMG_1.png', 'IMG_10.png', 'IMG_2.png', 'IMG_20.png']files.sort((a, b) => naturalOrder(a, b));// Output: ['IMG_1.png', 'IMG_2.png', 'IMG_10.png', 'IMG_20.png']How numeric: true works under the hood
When
numeric: trueis set, the collator detects numeric substrings inside the strings and parses those substrings as actual numbers, not as sequences of digits. And then it compares the numbers numerically, not character by character.Conclusion
For simple numeric arrays,
(a, b) => a - bis your go-to. For more complex natural sorting needs with strings containing numbers, theIntl.CollatorAPI provides a robust and locale-aware solution.Missed Connections - Jim Nielsen’s Blog
Jim Nielsen on the personal connections formed on the internet.
You could search the world and find someone who saw what you see, felt what you feel, went through what you’re going through.
And how these connections are increasingly being lost when we prompt an impersonal LLM instead.
Today I learned,
grid-auto-columnsandgrid-auto-rowssize implicit tracks as well as any explicit tracks that are not explicitly sized by bygrid-template-rowsorgrid-template-columns.Until now, I was under the impression that
grid-auto-rowsandgrid-auto-columnssize only implicit grid tracks.Why is `grid-row: 1/-1` not working?
The
grid-rowgrid-placement property is shorthand forgrid-row-startandgrid-row-end..grid-item {grid-row: 1/-1;/* is equivalent to */grid-row-start: 1;grid-row-end: -1;}In the above declaration, we use integers to position and size the grid item by line numbers.
As per the spec:
Numeric indexes in the grid-placement properties count from the edges of the explicit grid. Positive indexes count from the start side (starting from 1 for the start-most explicit line), while negative indexes count from the end side (starting from -1 for the end-most explicit line).
The important bit is the explicit grid. This begs the question …
What is the explicit grid?
As per the spec:
The three properties
grid-template-rows,grid-template-columns, andgrid-template-areastogether define the explicit grid of a grid container by specifying its explicit grid tracks.Simply put, the explicit grid consists of manually defined rows and columns.
The size of the explicit grid is determined by the larger of the number of rows/columns defined by
grid-template-areasand the number of rows/columns sized bygrid-template-rows/grid-template-columns. Any rows/columns defined bygrid-template-areasbut not sized bygrid-template-rows/grid-template-columnstake their size from thegrid-auto-rows/grid-auto-columnsproperties. If these properties don’t define any explicit tracks the explicit grid still contains one grid line in each axis.That last bit is what leads to line -1 being the same line as 1 because the explicit grid still contains one grid line in each axis.
What is the implicit grid?
As Manuel Matuzovic puts it:
If there are more grid items than cells in the grid or when a grid item is placed outside of the explicit grid, the grid container automatically generates grid tracks by adding grid lines to the grid. The explicit grid together with these additional implicit tracks and lines forms the so called implicit grid.
Conclusion
Paraphrasing Jen Simmons:
- -1 is the last line of the explicit grid
- If you haven’t defined any explicit rows, then all your rows are implicit
- For implicit rows, -1 is the same line as 1
- Define explicit rows and
grid-row: 1/-1will work as expected
Further Reading
Why Swiss Trains are the Best in Europe - YouTube
I love this bit from the video where Jason quotes Enrique Peñalosa, the former mayor of Bogotá, Colombia:
A developed country is not where the poor have cars. It’s where the rich use public transportation.
But why is it important that wealthy people take public transportation? Because, as Jason mentions,
[…] for better or for worse, these people are likely to have the power and political influence to demand efficient service.
An idea to power your personal brand’s content game | beastoftraal.com
Karthik Srinivasan discusses how to use curation to build a personal brand and shares some steps to get started.
An underrated tip for personal branding | beastoftraal.com
Karthik Srinivasan uses his experience with running as an analogy to emphasize the importance of consistently showing up in the context of personal branding.
I found the analogy effective and relatable, as I had a similar experience when I started running.
Just Build Websites - Jim Nielsen’s Blog
Jim Nielsen uses his experience with golf as a metaphor to explain that the key to success in web development comes from actual practice — building websites — rather than obsessing over what tools, frameworks and technologies others are using.
Personal branding is like your credit score
Personal branding is about bringing focus to your touchpoints with the world (of strangers) so that the right kinds of people can find you and remember you. You make use of the attention when you really need it. But it is good to be in the consideration set.