CSS selectors find elements by their HTML structure and attributes. They are useful for browser investigation and automation when user-facing locators are not available.

Basic selectors

SelectorMatches
buttonEvery button element.
.errorElements with class error.
#checkoutElement with ID checkout.
button.primaryButtons with class primary.
.card, .panelEither selector.
*Every element. Use carefully.

Attributes

[data-testid="save"]Exact value.
[disabled]Attribute is present.
[href^="https://"]Value starts with text.
[href$=".pdf"]Value ends with text.
[class*="warning"]Value contains text.
[class~="active"]Space-separated value contains the word.
[lang|="en"]en or value starting en-.

Relationships

form inputAny input inside a form.
form > inputInput that is a direct child.
label + inputInput immediately after a label.
h2 ~ pParagraph siblings after an h2.

Pseudo-classes

li:first-childFirst item among siblings.
li:last-childLast item among siblings.
tr:nth-child(2)Second row.
input:checkedChecked checkbox or radio.
button:disabledDisabled button.
input:not([type="hidden"])Inputs except hidden ones.
form:has(.error)Form containing an error element.

Console testing

// First match document.querySelector('[data-testid="save"]') // All matches and count document.querySelectorAll('form input').length // Highlight every match document.querySelectorAll('a[href$=".pdf"]') .forEach(el => el.style.outline = '2px solid red');
  • Confirm the selector matches the intended element.
  • Check it is unique when the test expects one element.
  • Test with repeated rows, translations and dynamic data.
  • Avoid generated classes, positional selectors and long DOM chains.
  • Prefer Playwright role or label locators for user-facing controls.

Useful links