|$ curl https://forge-ai.dev/api/markdown?path=docs/css/selectors
$cat docs/selectors-&-combinators.md
updated Yesterday·10 min read·published

Selectors & Combinators

CSSSelectorsFundamentalsBeginner
Type, Class & ID Selectors

Selectors are the foundation of CSS — they determine which elements receive your styles. The three most fundamental selector types are type (element name), class (prefixed with .), and ID (prefixed with #).

Type selectors match all elements of a given tag name. Class selectors match any element with a specific class attribute. ID selectors match a single element with a given ID — and should be used sparingly due to their high specificity and the constraint that IDs must be unique per page.

basic-selectors.css
CSS
1/* Type selector — targets all <article> elements */
2article {
3 padding: 24px;
4 border-bottom: 1px solid #222222;
5}
6
7/* Class selector — reusable, low specificity */
8.card {
9 background: #0D0D0D;
10 border-radius: 8px;
11 padding: 16px;
12}
13
14/* ID selector — high specificity, use sparingly */
15#primary-nav {
16 position: sticky;
17 top: 0;
18 z-index: 100;
19}
20
21/* Combining type + class */
22button.primary {
23 background: #00FF41;
24 color: #0D0D0D;
25 font-weight: 600;
26}
27
28/* Multiple classes */
29.card.highlighted {
30 border: 1px solid #00FF41;
31}
preview
Attribute Selectors

Attribute selectors match elements based on the presence or value of HTML attributes. They are extremely powerful for styling form elements, links, and data-driven components without adding extra classes.

attribute-selectors.css
CSS
1/* Presence — matches if attribute exists */
2[disabled] { opacity: 0.5; cursor: not-allowed; }
3[hidden] { display: none; }
4
5/* Exact match */
6[type="text"] { border-color: #333; }
7[data-theme="dark"] { background: #0D0D0D; }
8
9/* Substring match — contains */
10[class*="btn-"] { font-weight: 600; }
11
12/* Prefix match — starts with */
13[href^="https"] { color: #00FF41; }
14[href^="/api"] { font-family: monospace; }
15
16/* Suffix match — ends with */
17[src$=".svg"] { padding: 4px; }
18[href$=".pdf"]::after { content: " PDF"; }
19
20/* Space-separated — matches whole word in list */
21[rel~="external"] { target: _blank; }
22
23/* Case-insensitive flag */
24[data-type="primary" i] { background: #00FF41; }
preview
Combinators

Combinators define relationships between selectors. They allow you to target elements based on their position relative to other elements in the DOM tree.

CombinatorSymbolExampleDescription
Descendant(space)article p<p> anywhere inside <article>
Child>article > p<p> as a direct child of <article>
Adjacent Sibling+h2 + p<p> immediately after <h2>
General Sibling~h2 ~ p<p> anywhere after <h2>
Column||col || td<td> that belongs to a column
combinators.css
CSS
1/* Descendant — any level of nesting */
2.card p { color: #A0A0A0; line-height: 1.6; }
3
4/* Child — only direct children */
5nav > ul { display: flex; gap: 16px; list-style: none; }
6
7/* Adjacent sibling — immediately following */
8h2 + p {
9 margin-top: 0;
10 font-size: 1.125em;
11 color: #00FF41;
12}
13
14/* General sibling — all following siblings */
15h2 ~ p { color: #808080; }
16
17/* Chaining combinators */
18.sidebar > .nav-item > a.active {
19 color: #00FF41;
20 border-left: 2px solid #00FF41;
21}
22
23/* Complex targeting */
24main.content article.card:hover {
25 border-color: #00FF41;
26}
preview
Pseudo-Classes

Pseudo-classes select elements based on their state, position, or user interaction. They begin with a single colon : and are appended to a selector.

1/* User interaction states */2button:hover { background: #00FF41; color: #0D0D0D; }3input:focus { outline: 2px solid #00FF41; }4a:active { color: #00FF41; }5a:visited { color: #666; }6 7/* Position-based */8li:first-child { font-weight: bold; }9li:last-child { border-bottom: none; }10li:nth-child(odd) { background: #0D0D0D; }11li:nth-child(3n+1) { color: #00FF41; }12li:nth-last-child(2) { color: #FFB000; }13 14/* Structural */15:root { --accent: #00FF41; }16:empty { display: none; }17:only-child { margin: 0; }18 19/* Functional pseudo-classes */20button:not(.primary) { opacity: 0.7; }21:is(h1, h2, h3) { line-height: 1.3; }22:where(.card, .panel) { padding: 1.5rem; }23form:has(input:invalid) { border-color: #EF4444; }24 25/* Form states */26input:checked { accent-color: #00FF41; }27input:disabled { opacity: 0.4; }28input:required { border-color: #00FF41; }29input:invalid { border-color: #EF4444; }30input:valid { border-color: #22C55E; }

info

The :has() pseudo-class is a CSS relational selector — it lets you style a parent element based on its children. This was revolutionary when browsers added support, enabling parent selection that CSS had lacked for decades.
Pseudo-Elements

Pseudo-elements target specific parts of an element or generate virtual content. They use the double-colon :: syntax to distinguish them from pseudo-classes.

pseudo-elements.css
CSS
1/* Generated content — before and after */
2.card::before {
3 content: "◆ ";
4 color: #00FF41;
5}
6
7.card::after {
8 content: "";
9 display: block;
10 width: 100%;
11 height: 1px;
12 background: linear-gradient(90deg, #00FF41, transparent);
13 margin-top: 12px;
14}
15
16/* Typography pseudo-elements */
17p::first-line {
18 font-size: 1.25em;
19 font-weight: 600;
20 color: #E0E0E0;
21}
22
23p::first-letter {
24 font-size: 3em;
25 float: left;
26 line-height: 0.8;
27 margin-right: 6px;
28 color: #00FF41;
29}
30
31/* Selection styling */
32::selection {
33 background: #00FF41;
34 color: #0D0D0D;
35}
36
37/* Placeholder styling */
38input::placeholder {
39 color: #525252;
40 font-style: italic;
41}
42
43/* Marker for list items */
44li::marker {
45 color: #00FF41;
46 font-size: 0.8em;
47}
48
49/* File selector button */
50input[type="file"]::file-selector-button {
51 background: #00FF41;
52 color: #0D0D0D;
53 border: none;
54 padding: 8px 16px;
55 border-radius: 4px;
56}
preview
Specificity Calculation

When multiple selectors target the same element, the browser uses specificity to determine which declaration wins. Understanding specificity is crucial for debugging and writing maintainable CSS.

LevelSelector TypeWeight
AInline styles (style="")1, 0, 0, 0
BID selectors (#id)0, 1, 0, 0
CClasses, attributes, pseudo-classes0, 0, 1, 0
DElements, pseudo-elements0, 0, 0, 1
specificity.css
CSS
1/* Specificity: 0,0,0,1 */
2p { color: #A0A0A0; }
3
4/* Specificity: 0,0,1,0 — beats type selector */
5.text { color: #E0E0E0; }
6
7/* Specificity: 0,1,1,0 — beats class alone */
8#main .text { color: #00FF41; }
9
10/* Specificity: 0,1,2,1 — highest normal specificity */
11#main p.text.highlight { color: #FFB000; }
12
13/* The :where() pseudo-class zeroes specificity */
14:where(.card) p { color: #808080; }
15/* Equivalent to: p { color: #808080; } (specificity: 0,0,0,1) */
16
17/* The :is() pseudo-class takes highest argument specificity */
18:is(h1, #title) { color: #00FF41; }
19/* Specificity: 0,1,0,0 (from #title, ignoring h1) */

warning

Always aim for low specificity selectors. High specificity creates inheritance problems and forces you to use even higher specificity or !important to override. Prefer classes over IDs for styling.
CSS Nesting

CSS nesting lets you nest selectors inside other selectors, mirroring the HTML structure. This feature landed natively in browsers in 2024, reducing the need for preprocessors like Sass for basic nesting.

nesting.css
CSS
1/* Without nesting */
2.card { background: #0D0D0D; border-radius: 8px; }
3.card .title { color: #E0E0E0; font-size: 1.25rem; }
4.card .body { color: #A0A0A0; line-height: 1.6; }
5.card .footer { border-top: 1px solid #222; padding-top: 12px; }
6.card .footer .meta { color: #525252; font-size: 0.75rem; }
7
8/* With native CSS nesting */
9.card {
10 background: #0D0D0D;
11 border-radius: 8px;
12
13 .title {
14 color: #E0E0E0;
15 font-size: 1.25rem;
16 }
17
18 .body {
19 color: #A0A0A0;
20 line-height: 1.6;
21 }
22
23 .footer {
24 border-top: 1px solid #222;
25 padding-top: 12px;
26
27 .meta { color: #525252; font-size: 0.75rem; }
28 }
29}
30
31/* Using & for compound selectors */
32.button {
33 &.primary { background: #00FF41; color: #0D0D0D; }
34 &:hover { opacity: 0.9; }
35 & .icon { margin-right: 8px; }
36}
37
38/* Nesting at-rules */
39.card {
40 @media (max-width: 768px) {
41 padding: 12px;
42 .title { font-size: 1rem; }
43 }
44}

best practice

Use native CSS nesting for simple parent-child relationships. Avoid nesting deeper than 3 levels — excessive nesting creates overly specific selectors and makes debugging harder. Keep it shallow and readable.
$Blueprint — Engineering Documentation·Section ID: CSS-02·Revision: 1.0