I have a lot of private notes regarding all kinds of topics: web development, my hobbies, finances, things to buy, work-related tasks, and so on. These notes are probably the most important things I have digitally (besides thousands of pictures) and up until recently they were stored in a PostgreSQL database. This had always been a compromise though. What I actually wanted was to store them in Markdown files on my computer.
Collecting some frontend related notes, thoughts, bookmarks and tips.
- all
- accessibility
- animations
- css
- favicons
- grid
- html
- internationalisation
- javascript
- performance
- svg
- typography
- ux
There is a
change
event that can be used to listen to media query changes:const mediaQuery = window.matchMedia("…");
mediaQuery.addEventListener("change", (e) => {
…
});TIL: translate attribute
There is a
translate
attribute telling browsers not to translate the content if using"no"
: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/translatewindow.addEventListener("keydown", detectCapsLock);
window.addEventListener("keyup", detectCapsLock);
function detectCapsLock(e) {
if (e.getModifierState("CapsLock")) {
// caps lock is on
} else {
// caps lock is off
}
}TIL: Web Share API
There is an API to trigger the native sharing function of the OS: https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API
https://github.com/alphagov/wcag-primer/wiki "outlines some approaches for testing websites and applications against the Web Content Accessibility Guidelines (WCAG) 2.1 AA Level".
Modals are not another noun for dialogs, but an adjective describing certain types of dialogs:
Basically, when a modal component is open, it is the only thing that is not inert. Only the modal content can be interacted rest with, the rest of the page or application is made inert. Inert content is content that users cannot interact with. It is only really there visually, but you cannot Tab to it, click it, scroll it or access the content via assistive technologies.
— Hidde de Vries
If an element is hidden via
visibility: hidden
, its subtree can be made visible by usingvisibility: visible
:parent {
visibility: hidden;
}
child {
visibility: visible;
}Without rounded corners:
border: solid 0.25rem;
border-image: linear-gradient(to bottom right, darkmagenta, aquamarine);With rounded corners:
border: solid 0.25rem transparent;
background:
linear-gradient(white, white) padding-box,
linear-gradient(to bottom right, darkmagenta, aquamarine) border-box;Drawback: You need to set a solid color as background, so it cannot be transparent.
https://randoma11y.com creates random accessible color combinations.
<meta name=twitter:card content=summary_large_image>
<meta property=og:title content="This is a test title">
<meta property="og:description" name="description" content="This is a test description.">
<meta property="og:image" content="https://hell.meiert.org/core/png/test.png">Youtube embeds are not very performant, so here is a web component with focus on performance: https://github.com/paulirish/lite-youtube-embed
Quickly analyze landmarks, headings and links of a website: https://xi.github.io/a11y-outline/
My favourite bookmarklet.
@media (forced-colors: active) {
svg {
fill: CanvasText;
}
a svg {
fill: LinkText;
}
}This to consider for screen readers when implementing dynamic search results: https://www.scottohara.me/blog/2022/02/05/dynamic-results.html
<meta />
<title>
preconnect
<script async></script>
CSS with @imports
sync JS
sync CSS
preload
<script defer></script>
prefetch / prerender
everything else (SEO, icons, open graph)SVG Crop: https://svgcrop.com
A few questions to help you decide if an image should have an
alt
value or not: https://www.w3.org/WAI/tutorials/images/decision-tree/The inputmode attribute allows to define the type of keyboard which is shown when focusing an input.
Values:
- none
- text
- decimal
- numeric
- tel
- search
- url
With the following CSS we can make sure that numbers are all rendered using the same width (similar to monospaced fonts):
font-variant-numeric: tabular-nums;
This can be helpful for example for tables or when displaying prices below each other.
Table about loading priorities of render blocking, async, defer, prefetched etc scripts in Chrome: https://addyosmani.com/blog/script-priorities/
The
enterkeyhint
content attribute is an attribute that specifies what action label (or icon) to present for the enter key on virtual keyboards.Values:
- enter
- done
- go
- next
- previous
- search
- send
The following principles are valid for all kinds of animations:
- Appearing: ease-out, longer animation
- Disappearing: ease-in, shorter animation
- Moving: ease-in-out
- Long distance / big screen: longer animation
- Short distance / small screen: shorter animation
When fading in list items, that means multiple items:
- overlapping, not one after, not at the same time
- vertical: top to bottom
- grid: top left to bottom right
blockquote::before {
content: open-quote;
}
blockquote::after {
content: close-quote;
}@media print {
@page {
size: landscape;
}
}At the time of the tweet, it worked in blink only.
https://www.magentaa11y.com/web/ lets you create a comprehensive testing guide for all elements on your page.
<link rel="icon" href="/favicon.ico" sizes="any"><!-- 32×32 -->
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png"><!-- 180×180 -->
<link rel="manifest" href="/manifest.webmanifest">// manifest.webmanifest
{
"icons": [
{ "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
{ "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
]
}I can never remember this snippet:
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));This will create equally sized columns, where
20rem
is the minimum width of the columns. When they would become smaller than this, the last entry in a row moves to the next row.We use
min(100%, 20rem)
to avoid overflow when the container is smaller than20rem
.Hiding elements visually, but keeping them for screen readers:
.u-hiddenVisually {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
border: 0;
padding: 0;
white-space: nowrap;
clip-path: inset(100%);
clip: rect(0 0 0 0);
overflow: hidden;
}My by far most used utility class.
If you want to use an inline SVG in a CSS file: https://yoksel.github.io/url-encoder/
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
Arial, sans-serif;or
font: 1rem/1.2 BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Helvetica,
Arial, sans-serif;The shorthand version cannot start with
-apple-system
!Google Fonts can and should be served locally instead of from google. This tool can be used to download the font files: https://google-webfonts-helper.herokuapp.com/fonts
I was recently working on the relaunch of my website and wanted to include the open source font Inter. Unfortunately, even the woff2 versions of each different font style were at least 100kb large. As I wanted to use three font styles, this was, of course, way too much.
Probably the most popular way of organizing your components is Atomic Design which was introduced by Brad Frost. I recently talked to a client of mine who said that they were succesfully using this methodology in all their projects and that it works really well for them. We had a short discussion about it as I was using it for a little bit as well, but was realizing pretty quickly that it would just not work for me. One reason for that is the following example: let's say you have two atoms; a button and an icon. If a button could also have an icon included, you would include an atom in another atom. While you could of course do that, it simply feels wrong to me (there are also no atoms in atoms in the nature, are there?).
That is just one example for why I came up with my own way of organizing my components.