diff --git a/hell/adventcalendar/2025/5/index.md b/hell/adventcalendar/2025/5/index.md
index 7ac093d5..b1a8c9e2 100644
--- a/hell/adventcalendar/2025/5/index.md
+++ b/hell/adventcalendar/2025/5/index.md
@@ -1,35 +1,349 @@
---
-title: "Idrefs: What they are and how to use them"
-author: "Your Name"
-author_bio: "Your short bio"
+title: "IDREFs: What they are and how to use them"
+author: "Kilian Valkhof"
+author_bio: "Web developer and creator of Polypane.app, the browser for developers."
date: 2025-12-05
author_links:
- - label: "Site"
- url: "https://linktoyourblog123.com"
- link_label: "linktoyourblog123.com"
-intro: "
Short introductory text
"
+ - label: "Personal site"
+ url: "https://kilianvalkhof.com"
+ link_label: "kilianvalkhof.com"
+ - label: "Polypane"
+ url: "https://polypane.app"
+ link_label: "polypane.app"
+intro: "Specifing the right relationships between elements is a key part of building websites well. Often these relationships are implicit and depend on the source order or structure, such as a heading followed by a paragraph or a list element inside of a ``. And while this gets you far, there are times when you need to be more explicit about the relationships between elements.
"
image: "advent25_5"
---
-Some text.
-Some text.
-Some text. Some text.
+Take the following HTML for example:
-## Heading
+```html
+
+ Email address
+
+
+```
+
+Here, the `` element is associated with the ` ` element because the input is nested inside of the label, and the browser now knows to offer additional behavior: when the user clicks on the label, the input will be focused. That's not behavior that you had to specify with an onclick handler, the browser just infers it from the relationship between the elements.
-Some text.
+But what if it can't infer the relationship? While your Firefox, Chrome or [Polypane browser](https://polypane.app) can all figure this out, some assistive technologies can't. Both Dragon Naturally Speaking and VoiceOver on macOS have trouble associating labels with inputs when they are nested, according to [a11ysupport tests](https://a11ysupport.io/tests/html_label_element_implicit). So while clicking the label will focus the input, giving the voice command "Focus Email address" might not work. That said, support might have improved since the tests were last conducted: My editor Zoë tested this in Safari 26.0.1 on macOS 15.7.1 where it now works. Make sure to test before relying on this behavior!
-## Heading
+Additionally, this association only works when the input is nested inside the label. If you wanted to have the label and input be siblings, for example for styling purposes, then that implicit association is lost.
-Some text.
+To solve this, we can use the `IDREF` you probably already know, the `for` attribute on the `` element:
+```html
+ Email address
+
+```
-Note: Some text.
+Now we're _explicitly_ associating the label with the input, by referencing the input's `id` from the label's `for` attribute. That's all an `IDREF` really is: a reference to another element's `id`.
+
+Note, there's also nothing keeping you from using the `for` attribute and nesting both at the same time:
```html
-
+
+ Email address
+
+
+```
+
+Now you know what an `IDREF` is! In HTML there are many other places where you can use `IDREF`s to create explicit relationships between elements, many of which are ARIA attributes that help with accessibility and with describing more complex relationships than HTML can express. We'll get to those in a bit, because there's more to be said about `IDREF`s themselves.
+
+## IDs need to be unique
+
+In a well-structured HTML document, each `id` is only used once. This is important for `IDREF`s to work properly, since the browser or assistive technology needs to be able to find the single right element when following an `IDREF`. If there are multiple elements with the same `id`, this can lead to unexpected behavior.
+
+Making sure IDs are unique can be tricky: you might have multiple forms on a page that reuse the same naming, or another repeated structure that requires ARIA attributes. When that happens, consider a programmatic way to generate unique IDs, for example by prefixing them with the component name.
+
+## IDs need to exist
+
+This might seem obvious, but the majority of issues that occur around `IDREF`s is that the referenced ID simply doesn't exist in the document. This can happen when you make a typo in the `id` or `IDREF`, or when you remove an element but forget to update the references to it.
+
+Linters and validators can help catch these issues, as can browser developer tools that highlight broken references. In Polypane, for example, broken `IDREF`s are [highlighted in the Element panel](https://polypane.app/docs/elements-panel/#idrefs), making it easy to spot and fix them.
+
+
+
+In other browsers you can check for missing IDs using this little console snippet that gathers all `for` attributes on labels and checks if the referenced ID exists:
+
+```js
+document.querySelectorAll("[for]").forEach((label) => {
+ const id = label.getAttribute("for");
+ if (!document.getElementById(id)) {
+ console.error(
+ `Label with for="${id}" has no matching element with that ID.`,
+ label
+ );
+ }
+});
```
+
+## Other HTML IDREF attributes
+
+HTML has quite a few attributes that use `IDREF`s to create relationships between elements, including some _very_ new ones.
+
+### The `for` attribute on `` elements
+
+As we've seen above.
+
+A neat trick that `for` has: you can link as many labels as you want to a single input:
+
+```html
+ Email address
+
+ required
+```
+
+These will all focus the same input, and their combinined text will be used as the accessible name for the input: `Email address required`. Of course, that's the _theory_. In practice, support for inputs with multiple labels is inconsistent. Some assistive technologies will use all labels but some only use the first or the last one (see [ this research](https://github.com/dequelabs/axe-core/issues/689#issuecomment-490176712) done by Deque). So while it's valid HTML, you're better off sticking to a single label per input for now.
+
+### The `form` attribute on form-associated elements
+
+You can add a `form` attribute to form-associated elements like ` `, ``, ``, `` and `