Contents

    Guides

    CSS Selectors in Selenium: Examples and Best Practices

    Published on

    September 11, 2025
    CSS Selectors in Selenium: Examples and Best Practices

    CSS selectors are a key way to locate elements on a web page when automating tests with Selenium. They provide a simple and efficient method to target elements by ID, class, tag, or other attributes. Using CSS selectors correctly can make test scripts faster and easier to maintain.

    With CSS selectors, testers can handle both basic and complex scenarios, such as selecting child elements, siblings, or elements with specific attribute values. 

    This article explores CSS selectors in Selenium with examples and best practices.

    Understanding CSS Selectors

    CSS selectors are patterns used to select HTML elements based on their attributes, hierarchy, or relationships in the DOM. In Selenium, they serve as a way to precisely identify elements for actions like clicking, typing, or verifying content. Compared to XPath, CSS selectors are generally faster and easier to read, especially for simple element selections.

    CSS selectors can target elements using IDs, classes, tags, attributes, or combinations of these. They also support relationships such as parent–child, siblings, and pseudo-classes, allowing testers to handle complex web structures. Correct usage ensures stable and maintainable test scripts.

    Core CSS Selector Patterns in Selenium

    CSS selectors in Selenium provide a flexible way to locate elements for automation scripts. By using different patterns, testers can target elements precisely, reduce flakiness in tests, and make scripts easier to maintain. The following core patterns cover the most common selection methods used in real-world Selenium automation.

    1. By ID

    The ID of an element is unique within a page, making it the most precise selector. Using IDs ensures the selection is fast and reliable.

    Syntax: #elementID

    Example: #username

    This selects the element <input id="username">. In Selenium:

    driver.findElement(By.cssSelector("#username")).sendKeys("testuser");

    2. By Class

    Classes can be shared across multiple elements, so using class selectors is useful when you want to target a group of elements or a specific one with a unique combination.

    Syntax: .className

    Example: .login-button

    This selects all elements with class="login-button". In Selenium:

    driver.findElement(By.cssSelector(".login-button")).click();

    3. By Tag

    Tag selectors are useful when elements have no unique ID or class but are identified by their HTML tag. This is often combined with other selectors for precision.

    Syntax: tagname

    Example: input

    This selects all <input> elements on the page. In Selenium:

    driver.findElements(By.cssSelector("input"));

    4. By Attribute

    Attribute selectors allow targeting elements based on any attribute, not just ID or class. This is useful for forms, buttons, and links.

    Syntax: [attribute='value']

    Example: [type='submit']

    This selects <input type="submit">. In Selenium:

    driver.findElement(By.cssSelector("[type='submit']")).click();

    5. By Multiple Attributes

    Sometimes a single attribute is not enough to uniquely identify an element. Combining attributes increases specificity.

    Syntax: [attr1='value1'][attr2='value2']

    Example: [type='text'][name='email']

    This selects <input type="text" name="email">. In Selenium:

    driver.findElement(By.cssSelector("[type='text'][name='email']")).sendKeys("user@example.com");

    Extended CSS Selector Strategies

    Advanced CSS selectors help handle elements that are difficult to locate using simple patterns. Using these strategies in Selenium improves test reliability, especially for dynamic or complex web pages.

    1. Substring Matching

    This approach targets elements based on partial attribute values, useful when IDs or classes change dynamically. For example, [id^='user'] selects any element whose ID starts with "user", such as <input id="user123">. 

    Similarly, [class*='btn'] matches elements containing "btn" in their class name, like <button class="submit-btn">. Substring matching ensures tests continue to work even if small changes occur in attribute values.

    2. Parent–Child and Descendant Relationships

    Selecting elements based on hierarchy allows precise targeting. The child selector (>) selects elements directly under a parent, e.g., div > input finds input fields immediately inside a <div>. 

    Descendant selectors (space) capture elements at any depth, e.g., form input selects all input fields within a form. These relationships help handle nested structures without relying on fragile attributes.

    3. Sibling Selectors

    When elements appear sequentially, sibling selectors locate elements relative to others. The adjacent sibling selector (+) targets the next element, e.g., label + input finds an input immediately after a label. The general sibling selector (~) selects all following siblings, useful for grouped form controls or list items.

    4. Grouping Selectors

    Grouping combines multiple selectors to reduce repetition and improve readability. For example, input, select, and textarea selects all standard form fields in a single expression. Grouping simplifies scripts and makes them easier to maintain when multiple elements need the same action.

    5. Pseudo-classes

    Pseudo-classes allow selection based on position or state. Examples include :first-child, :last-child, and :nth-of-type(n). For instance, ul li:nth-of-type(2) selects the second list item in every unordered list. Pseudo-classes are valuable when elements lack unique IDs or consistent attributes, letting testers rely on structure instead.

    CSS Selector Examples in Selenium Test Scripts

    Using CSS selectors in Selenium test scripts helps locate elements quickly and perform actions efficiently. Here are practical examples demonstrating common scenarios:

    1. Selecting Elements by ID

    When an element has a unique ID, it is the most reliable selector. For example, to enter a username in a login form:

    driver.findElement(By.cssSelector("#username")).sendKeys("testuser");

    This selects <input id="username"> directly and ensures the action targets the correct field.

    2. Selecting Elements by Class

    Classes are useful when multiple elements share the same styling or behavior. For instance, clicking a submit button with class login-button:

    driver.findElement(By.cssSelector(".login-button")).click();

    If multiple buttons exist, combining the class with another attribute improves specificity.

    3. Selecting Elements by Attribute

    Attribute selectors handle elements without IDs or unique classes. For example, selecting a submit input field by its type attribute:

    driver.findElement(By.cssSelector("input[type='submit']")).click();

    This works reliably even if the element has dynamic classes.

    4. Combining Multiple Attributes

    Combining attributes increases precision when a single attribute is insufficient. For example:

    driver.findElement(By.cssSelector("input[type='text'][name='email']")).sendKeys("user@example.com");

    This ensures only the input field intended for the email is selected, reducing the risk of interacting with the wrong element.

    5. Using Advanced Selectors

    Advanced selectors like child, descendant, and pseudo-classes handle complex page structures. For example, selecting the second item in a list inside a form:

    driver.findElement(By.cssSelector("form ul li:nth-of-type(2)")).click();

    This approach is particularly useful for dynamic lists or repeated elements without unique identifiers.

    Best Practices for CSS Selectors in Selenium

    Following best practices ensures that CSS selectors remain reliable, maintainable, and efficient in Selenium test scripts.

    • Prioritize unique identifiers like IDs: IDs are the fastest and most stable way to locate elements. When possible, rely on IDs over classes or attributes to reduce the risk of selecting the wrong element. If the application doesn’t provide unique IDs, request them from developers for critical fields.
    • Combine classes with attributes for precision: Classes alone can be ambiguous if multiple elements share the same styling. Combining class selectors with other attributes (e.g., [class='btn'][type='submit']) ensures accurate selection and reduces flakiness in tests.
    • Avoid long, deeply nested selectors: Deep hierarchies like div > ul > li > span > a are brittle. Instead, focus on minimal selectors that are still unique. Target elements by stable attributes or shorter relationships to make tests more maintainable.
    • Use substring matching strategically for dynamic elements: Attributes like id or class can change dynamically. Substring matching (^=, $=, *=) allows tests to adapt, e.g., [id^='user_'] selects user_123 and user_456. Avoid overusing it on elements with many similar matches to prevent accidental selections.
    • Leverage structure-based selectors cautiously: Child (>), descendant (space), and sibling (+/~) selectors help when elements lack unique identifiers. Use them to reflect the page structure, but validate that structural changes in the DOM won’t break tests.
    • Incorporate pseudo-classes for repeated or positional elements: Pseudo-classes like :nth-of-type() or :first-child are essential when IDs/classes are missing. Use them for lists, tables, or dynamically generated content, ensuring they remain stable even if the number of elements changes.

    Conclusion

    Effective use of CSS selectors in Selenium is key to creating robust and maintainable automation scripts. By leveraging IDs, classes, attributes, and advanced strategies like substring matching, pseudo-classes, and parent–child relationships, testers can accurately target elements even in complex or dynamic web pages.

    For teams looking to scale testing across multiple browsers and devices, BrowserStack Automate provides a cloud-based platform to execute Selenium scripts reliably. It supports real-device and browser testing, enabling verification of CSS selectors in diverse environments without the overhead of maintaining local infrastructure.

    Run Selenium Tests on Cloud

    Data-rich bug reports loved by everyone

    Get visual proof, steps to reproduce and technical logs with one click

    Make bug reporting 50% faster and 100% less painful

    Rating LogosStars
    4.6
    |
    Category leader

    Liked the article? Spread the word

    Put your knowledge to practice

    Try Bird on your next bug - you’ll love it

    “Game changer”

    Julie, Head of QA

    star-ratingstar-ratingstar-ratingstar-ratingstar-rating

    Overall rating: 4.7/5

    Try Bird later, from your desktop