Form states without JavaScript
Only the field that has a required input gets the star. The button stays dim while the email is empty or the box is unticked. Type a bad email and click elsewhere to see :user-invalid turn the border red.
:has() matches an element when something inside it, or after it, matches the selector you give; that lets CSS style a form from the state of its inputs, a parent from its children, and a list from how many items it has, all without JavaScript.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write CSS that gives a <figure> a grey background only when it contains a <figcaption>.
Write CSS so a .plan label gets a 2px indigo border when the radio button inside it is checked.
Write a quantity query that makes a .tags list display as a single flex row when it has 3 or fewer items.
Explain it without notes
What does :has() do, and which element does a selector like .card:has(img) style?
Show how :has() can style a form based on its inputs' state, and why :user-invalid is better than :invalid for error styles.
Explain a quantity query that matches lists with at least 4 items and one that matches exactly 3 items.
What are the restrictions and the specificity rules of :has()?
Preview
Console
Nothing logged yet.Expected console output
email label marker: " *"
age label marker: none
button opacity at start: 0.5
button opacity when valid: 1