Syntax
:focus-visible { }
:focus-within { }Examples
:focus-visible - Smarter Focus Rings
Showing a focus ring for keyboard users without cluttering mouse interactions.
.button:focus {
outline: none; /* remove the default outline for ALL focus, including mouse clicks */
}
.button:focus-visible {
outline: 2px solid #3b82f6; /* but restore it specifically for keyboard focus */
outline-offset: 2px;
}:focus-within - Highlighting a Parent Group
Styling an entire form field group when any of its inputs are focused.
.field-group {
border: 1px solid #d1d5db;
transition: border-color 0.15s ease;
}
.field-group:focus-within {
border-color: #3b82f6; /* highlights the whole group, not just the individual input */
}Parameters and values
- :focus-visible (pseudo-class): Focus styling that only appears for keyboard/non-pointer interaction
- :focus-within (pseudo-class): Matches a parent when any descendant has focus
Best practices
- Use :focus-visible instead of :focus for custom focus ring styling - it correctly avoids showing rings on simple mouse clicks while preserving them for keyboard users
- Use :focus-within to visually group and highlight a fieldset or custom dropdown component when any part of it is actively focused
- Never combine outline: none with :focus alone and no :focus-visible fallback - that removes focus indication entirely, a serious accessibility regression
- Test focus behavior with actual keyboard (Tab key) navigation, not just mouse clicks, to confirm the intended pseudo-class is doing what you expect
At a glance
- Purpose
- Presentation and layout
- File extension
- .css
- Runs in
- Web browsers
- Usually used with
- HTML and JavaScript
Specifications & further reading
Related CSS documentation
Interactive Pseudo-classes
These pseudo-classes style elements based on user interaction state. :hover applies while the pointer is over an element, :focus while it has keyboard focus, :active during the moment of being clicked/pressed, and :visited for links the user has already navigated to.Form State Pseudo-classes
CSS can style form elements based on their validation and interaction state without any JavaScript. :checked applies to checked checkboxes/radios, :disabled to disabled fields, :required and :optional based on the required attribute, and :valid/:invalid based on constraint validation results.Pseudo-elements
Pseudo-elements let you style a specific part of an element rather than the whole thing, or insert generated content without adding extra HTML. ::before and ::after insert content before/after an element's actual content. ::first-line and ::first-letter target specific text portions. ::placeholder styles input placeholder text, and ::selection styles user-highlighted text.Structural Pseudo-classes: nth-child()
Structural pseudo-classes select elements based on their position among siblings, without needing extra classes. :first-child and :last-child match the first/last element. :nth-child() accepts a formula (like 2n for even, 2n+1 for odd) or a simple number, letting you target patterns like every third item or striped table rows.
These pseudo-classes style elements based on user interaction state. :hover applies while the pointer is over an element, :focus while it has keyboard focus, :active during the moment of being clicked/pressed, and :visited for links the user has already navigated to.Form State Pseudo-classes
CSS can style form elements based on their validation and interaction state without any JavaScript. :checked applies to checked checkboxes/radios, :disabled to disabled fields, :required and :optional based on the required attribute, and :valid/:invalid based on constraint validation results.Pseudo-elements
Pseudo-elements let you style a specific part of an element rather than the whole thing, or insert generated content without adding extra HTML. ::before and ::after insert content before/after an element's actual content. ::first-line and ::first-letter target specific text portions. ::placeholder styles input placeholder text, and ::selection styles user-highlighted text.Structural Pseudo-classes: nth-child()
Structural pseudo-classes select elements based on their position among siblings, without needing extra classes. :first-child and :last-child match the first/last element. :nth-child() accepts a formula (like 2n for even, 2n+1 for odd) or a simple number, letting you target patterns like every third item or striped table rows.