Following a ‘Tip’ suggestion to improve the code (Section 3.2.4) I added a checked attribute to a radio button input so that the buttons correctly represent the model’s initial state on page load. And it works.
However, when I use Chromium’s inspector, my radio inputs all look like this: <input type="radio" name="size">
None of them, including the one generated with checked True, have a checked attribute.
My question is:
What determines which attributes (and tags?) appear in the viewable page elements, and which will only exist in the DOM? Or am I misinterpreting what’s happening?
You’ve encountered one of those confusing parts of the HTML/DOM specification: the subtle differences between the properties and attributes of a node.
HTML/DOM
Roughly speaking, attributes are values that are set using the regular HTML attribute syntax checked ="checked" on a tag. Some (all?) of these are eventually converted into internal properties on the DOM node. Some (all?) properties can also be set directly using JavaScript like myNode.checked = true.
This means some values can be set via both attributes or properties but the resulting behavior can be slightly different depending on how it’s set
All this brings us to Elm. All the functions in Html.Attributes are built on top of either Html.Attributes.attribute or Html.Attributes.property allowing attributes and properties respectively to be set.
In particular, Html.Attributes.checked is built in terms of property which has the effect of not showing checked="checked" when you inspect the DOM. If you implemented it in terms of attribute then it would show up:
Here’s an Ellie example of building checked inputs with the checked helper, directly with attribute and directly with property. Run it and inspect the DOM for each of those to get a feel for the difference