📣 Requestly API Client – Free Forever & Open Source. A powerful alternative to Postman. Try now ->

CSS Selector in Selenium: Complete Tutorial with Examples

Rohit Rajpal
Learn how to use CSS selectors in Selenium to locate elements, handle dynamic content, and write robust automation tests.
CSS Selector in Selenium Complete Tutorial with Examples

CSS selectors are a method to locate elements on a web page in Selenium WebDriver. They allow targeting elements using IDs, classes, attributes, element hierarchy, or position within the DOM. Compared to other locators, CSS selectors execute faster and have a simpler syntax, making them suitable for writing reliable automation scripts.

CSS selectors in Selenium let testers directly reference specific elements, select multiple elements with shared characteristics, and handle elements nested within complex page structures.

This tutorial explains the types of CSS selectors, their syntax, and provides practical Selenium examples for precise element identification in testing scenarios.

What is a CSS Selector?

A CSS selector is a pattern used to identify elements on a web page. It relies on attributes, element types, classes, IDs, or the position of elements within the HTML structure. Compared to XPath, CSS selectors are simpler and generally execute faster in Selenium tests.

CSS selectors enable targeting single elements or groups of elements based on specific attributes or hierarchy. They are especially useful when elements do not have unique identifiers or when multiple elements share similar properties. This makes them a reliable choice for selecting elements in both simple and complex page layouts.

Types of CSS Selectors in Selenium

CSS selectors allow targeting elements in a web page based on their attributes, hierarchy, or relationships to other elements. They are widely used in Selenium because they are fast, readable, and precise.

Below is an in-depth look at each type.

1. ID Selector

ID selectors target elements using their unique id attribute. They are the fastest and most reliable way to locate elements because IDs are unique in the DOM. Tests using ID selectors are stable and execute quickly, making them ideal for frequently accessed elements such as login fields or buttons.

ID selectors are best suited for elements that appear only once and have consistent identifiers across sessions.

Syntax

				
					#elementID
				
			

Use Case

  • Locate a single, unique element on a page. For example, a username field, a password field, or a login button
  • Perform actions like entering text, clicking, or verifying the element’s state

Example

				
					// Locate the username input field using its ID
WebElement usernameField = driver.findElement(By.cssSelector("#username"));

// Locate the login button using its ID
WebElement loginButton = driver.findElement(By.cssSelector("#loginBtn"));
				
			

2. Class Selector

Class selectors target elements using their class attribute. Multiple elements can share the same class, which makes class selectors ideal for repeated components such as lists, buttons, or table rows. By combining class selectors with tag names or parent hierarchy, testers can precisely identify elements even within complex or repeating structures.

Syntax

				
					.className
				
			

Use Case

  • Locate one or more elements that share a common style or function
  • Interact with buttons, links, or repeated fields in lists and tables
  • Useful when IDs are not available or when targeting multiple similar elements

Example

				
					// Locate all login buttons with the same class
List<WebElement> loginButtons = driver.findElements(By.cssSelector(".login-button"));

// Click the first login button in the list
loginButtons.get(0).click();
				
			

3. Attribute Selector

Attribute selectors locate elements based on any HTML attribute, not just id or class. They provide flexibility for selecting elements that do not have unique identifiers or share common attributes. Attribute selectors can also be combined to target elements with multiple specific attributes, which is useful on dynamic forms or pages with complex structures.

Syntax

				
					[attribute='value']
				
			

Use Case

  • Target elements using attributes like type, name, or placeholder
  • Useful for form fields, input buttons, or elements without unique IDs
  • Can be combined with other selectors for more precise targeting

Example

				
					// Locate the submit button using the type attribute
WebElement submitButton = driver.findElement(By.cssSelector("[type='submit']"));

// Locate an input field using its name attribute
WebElement emailField = driver.findElement(By.cssSelector("[name='email']"));
				
			

4. Combining Attributes

Multiple attributes can be combined in a single selector to precisely target elements. This is especially useful when a single attribute is not unique, allowing testers to avoid interacting with unintended elements in complex pages.

Syntax

				
					[attribute1='value1'][attribute2='value2']
				
			

Use Case

  • Target elements with multiple attributes, such as type and name together
  • Useful for forms or tables where multiple inputs share the same class or type
  • Ensures only the intended element is selected in dynamic layouts

Example

				
					// Locate the email input field using type and name attributes
WebElement emailField = driver.findElement(By.cssSelector("[type='text'][name='email']"));

// Locate the submit button using type and value attributes
WebElement submitButton = driver.findElement(By.cssSelector("[type='submit'][value='Login']"));
				
			

5. Substring Matching

Substring matching allows selecting elements based on partial matches of attribute values. This is useful for elements with dynamic IDs, names, or classes that contain variable parts, such as session-specific or auto-generated identifiers.

Syntax

				
					[attribute^='value']  /* starts with */
[attribute$='value']  /* ends with */
[attribute*='value']  /* contains */
				
			

Use Case

  • Handle dynamic elements where the full attribute value may change
  • Target input fields, buttons, or links with predictable patterns in their attributes
  • Reduce test failures caused by changing IDs or dynamic content

Example

				
					// Locate input fields whose name starts with 'user'
WebElement userField = driver.findElement(By.cssSelector("[name^='user']"));

// Locate buttons whose value ends with 'Login'
WebElement loginButton = driver.findElement(By.cssSelector("[value$='Login']"));

// Locate elements whose class contains 'error'
WebElement errorMsg = driver.findElement(By.cssSelector("[class*='error']"));
				
			

6. Tag and Universal Selector

Tag selectors target elements by their HTML tag name. The universal selector * can match all elements in the DOM. Tag selectors are often combined with other selectors to narrow down elements when IDs or classes are absent.

Syntax

				
					tagName      /* Tag selector */
*            /* Universal selector */
				
			

Use Case

  • Tag selectors target all elements of a specific type, like input or button
  • Useful for applying actions to multiple elements sharing a tag
  • A universal selector can be combined with attributes for a broad selection

Example

				
					// Select all input fields on the page
List<WebElement> allInputs = driver.findElements(By.cssSelector("input"));

// Select all elements with a placeholder attribute using a universal selector
List<WebElement> placeholders = driver.findElements(By.cssSelector("*[placeholder]"));
				
			

7. Grouping Selectors

Grouping selectors combine multiple selectors using a comma, allowing the same operation on multiple unrelated elements. This simplifies test scripts and reduces repetition.

Syntax

				
					selector1, selector2
				
			

Use Case

  • Apply actions to multiple elements that do not share hierarchy or attributes
  • Useful for clearing multiple fields, clicking multiple buttons, or verifying several elements at once

Example

				
					// Select both username and password fields
List<WebElement> loginFields = driver.findElements(By.cssSelector("#username, #password"));

// Perform an action on both elements
for(WebElement field : loginFields) {
    field.clear();
}
				
			

8. Descendant and Child Combinators

Descendant and child combinators allow selecting elements based on parent-child relationships in the DOM. Descendant combinators select all nested elements inside a parent, while child combinators select only direct children.

Syntax

				
					ancestor descendant   /* Descendant combinator */
parent > child        /* Child combinator */
				
			

Use Case

  • Target elements without relying on unique IDs or classes
  • Useful for forms, tables, or nested layouts where hierarchy is consistent
  • Enables stable selection even when unrelated elements are added elsewhere in the DOM

Example

				
					// Descendant: select all <input> elements inside a <form>
WebElement inputField = driver.findElement(By.cssSelector("form input"));

// Child: select only <input> elements that are direct children of <form>
WebElement directInput = driver.findElement(By.cssSelector("form > input"));
				
			

9. Adjacent and Sibling Combinators

Adjacent and sibling combinators allow targeting elements based on their position relative to other elements. Adjacent combinators select the immediate next element, while general sibling combinators select all following siblings.

Syntax

				
					element1 + element2    /* Adjacent sibling */
element1 ~ element2    /* General sibling */
				
			

Use Case

  • Target elements in lists, menus, or repeated structures based on order
  • Useful when IDs and classes are not unique, but relative positions are predictable

Example

				
					// Adjacent sibling: select the first <p> after an <h2>
WebElement firstParagraph = driver.findElement(By.cssSelector("h2 + p"));

// General sibling: select all <p> elements after an <h2>
List<WebElement> allParagraphs = driver.findElements(By.cssSelector("h2 ~ p"));
				
			

10. Pseudo-classes

Pseudo-classes allow selecting elements based on their position, state, or structural characteristics. They provide advanced control when IDs, classes, or attributes are insufficient.

Syntax

				
					:nth-child(n)
:first-child
:last-child
				
			

Use Case

  • Target elements by position within a parent, such as the first or last item in a list
  • Useful for tables, lists, and dynamic components where elements cannot be uniquely identified by attributes

Example

				
					// Select the third row in a table
WebElement thirdRow = driver.findElement(By.cssSelector("table tr:nth-child(3)"));

// Select the first item in an unordered list
WebElement firstItem = driver.findElement(By.cssSelector("ul li:first-child"));

// Select the last input field in a form
WebElement lastInput = driver.findElement(By.cssSelector("form input:last-child"));
				
			

CSS Selector Examples in Selenium

CSS selectors can be used individually or combined to target elements in various real-world scenarios. Below are examples that illustrate practical usage in Selenium automation.

Example 1: Login Form

In a login form, multiple selectors may be used to locate username, password, and login button elements.

				
					// Locate username field by ID
WebElement usernameField = driver.findElement(By.cssSelector("#username"));

// Locate password field by attribute
WebElement passwordField = driver.findElement(By.cssSelector("[type='password']"));

// Locate login button by class
WebElement loginButton = driver.findElement(By.cssSelector(".login-button"));

// Enter credentials and click login
usernameField.sendKeys("testuser");
passwordField.sendKeys("Test@123");
loginButton.click();
				
			

This example shows using ID, attribute, and class selectors together to interact with form elements efficiently.

Example 2: Table Interaction

Tables often have repeated structures, making attribute and pseudo-class selectors essential for targeting specific rows or cells.

				
					// Select the third row of a table
WebElement thirdRow = driver.findElement(By.cssSelector("table tr:nth-child(3)"));

// Select the last cell in the third row
WebElement lastCell = driver.findElement(By.cssSelector("table tr:nth-child(3) td:last-child"));

// Print text from the last cell
System.out.println(lastCell.getText());
				
			

Using pseudo-classes like :nth-child and :last-child allows precise selection in tables without relying on unique IDs for every cell.

Example 3: Dynamic Lists

Dynamic content, such as lists generated at runtime, can be targeted using substring matching and combinators.

				
					// Select list items where class contains 'item'
List<WebElement> dynamicItems = driver.findElements(By.cssSelector("[class*='item']"));

// Select the first paragraph immediately following a heading
WebElement firstParagraph = driver.findElement(By.cssSelector("h2 + p"));

// Select all input fields that are direct children of a form
List<WebElement> formInputs = driver.findElements(By.cssSelector("form > input"));
				
			

These selectors handle elements with varying attributes or positions and allow tests to remain stable when the DOM changes.

Example 4: Grouping Multiple Elements

Grouping selectors simplifies interactions with multiple elements that require the same action.

				
					// Clear both username and password fields at once
List<WebElement> loginFields = driver.findElements(By.cssSelector("#username, #password"));
for(WebElement field : loginFields) {
    field.clear();
}

// Click multiple checkboxes at once
List<WebElement> checkboxes = driver.findElements(By.cssSelector(".terms, .newsletter"));
for(WebElement box : checkboxes) {
    if(!box.isSelected()) {
        box.click();
    }
}
				
			

Grouping selectors reduces repetitive code and improves readability when multiple unrelated elements need similar actions.

Conclusion

CSS selectors in Selenium offer precise and flexible ways to locate elements, handle dynamic content, and interact with complex web page structures. Using IDs, classes, attributes, combinators, pseudo-classes, and substring matching ensures that automation scripts remain accurate, maintainable, and resilient to changes in the DOM.

For teams running Selenium tests at scale, tools like BrowserStack offer a reliable cloud-based platform for executing these tests across multiple browsers and devices, eliminating the need to manage local infrastructure. Testers can validate web applications in real-world conditions, catch cross-browser issues early, and ensure consistent functionality across environments.

Written by
Rohit Rajpal
Rohit Rajpal is a B2B Content Strategist at BrowserStack, helping SaaS brands build AI-first strategies that drive authority and revenue. He writes about content, strategy, and the future of search in the zero-click era.

Related posts