
Finding elements using CSS selectors
The Cascading Style Sheets (CSS) is a style sheet language used to describe the presentation semantics (the looks and formatting) of a document written in a markup language such as HTML or XML.
Major browsers implement CSS parsing engines to format or style the pages using CSS syntax. CSS was introduced to keep the presentation information separate from the markup or content. For more information on CSS and CSS selectors, visit http://en.wikipedia.org/wiki/Cascading_Style_Sheets.
In CSS, the pattern-matching rules determine which style should be applied to elements in the DOM. These patterns, called selectors, may range from simple element names to rich contextual patterns. If all conditions in the pattern are true for a certain element, the selector matches the element, and the browser applies the defined style in CSS syntax.
In this recipe, we will explore some basic CSS selectors and then, later on, we will dive into advanced CSS selectors.
How to do it...
Let's explore some basic CSS selectors that can be used in Selenium WebDriver. Selenium WebDriver's By
class provides the cssSelector()
method to find elements using CSS selectors.
CSS absolute paths refer to the very specific location of the element considering its complete hierarchy in the DOM. Here is an example where the Username Input field is located using the absolute path. When providing an absolute path, a space is given between the elements, as shown in the following code example:
WebElement userName = driver.findElement(By.cssSelector("html body div div form input"));
You can also use the previous selector in the following way by describing the direct parent-to-child relationships with the >
separator:
WebElement userName = driver.findElement(By.cssSelector("html > body > div > div > form > input"));
However, this strategy has limitations as it depends on the structure or hierarchy of the elements on a page. If this changes, the locator will fail to find the element.
With a relative path, we can find an element directly, irrespective of its location in the DOM. For example, we can find the Username Input field in the following way, assuming it is the first <input>
element in the DOM:
WebElement userName = driver.findElement(By.cssSelector("input"));
The following CSS selectors use Class and ID attributes to find elements using relative paths. This is the same as the className()
and id()
locator methods. However, there is another strategy where we can use any other attribute of the element that is not covered in the By
class.
While finding elements using the CSS selector, we can use the Class
attribute to locate an element. This can be done by specifying the type of HTML tag, then adding a dot followed by the value of the class
attribute in the following way:
WebElement loginButton = driver.findElement(By.cssSelector("input.login"));
This will find the Login button's <input>
tag whose Class
attribute is login
.
Sometimes, multiple CSS classes are given for an element. For example:
<input type="text" class="username textfield" />
In this case, we can use multiple class names, as shown in the following example:
WebElement loginButton = driver.findElement(By.cssSelector("input.login.textfield"));
There is also a shortcut where you can put a ".
" (period) and class attribute value and ignore the HTML tag. However, this will return all the elements with the class as login
and the test may not return the correct element, as shown in the following code example:
WebElement loginButton = driver.findElement(By.cssSelector(".login"));
This method is similar to the className()
locator method.
We can find an element using the ID attribute. This can be done by specifying the type of HTML tag, then entering a # (hash) followed by the value of the Class
attribute, as shown in the following code:
WebElement userName = driver.findElement(By.cssSelector("input#username"));
This will return the username <input>
element using its id
attribute.
There is also a shortcut where you can enter #
and a class attribute value and ignore the HTML tag. However, this will return all the elements with the id
set as username
and the test may not return the correct element. This has to be used very carefully:
WebElement userName = driver.findElement(By.cssSelector("#username"));
This method is similar to the id
locator strategy.
Apart from the class
and id
attributes, CSS selectors also enable the finding of elements using other attributes of the element. In the following example, the Name
attribute is used to locate an <input>
element:
WebElement userName = driver.findElement(By.cssSelector("input[name=username]"));
Using the name
attribute to locate an element is similar to the name()
locator method of the By
class.
Let's use some other attributes to find an element. In the following example, the <img>
element is located by using its alt
attribute:
WebElement previousButton = driver.findElement(By.cssSelector("img[alt='Previous']"));
You might come across situations where one attribute may not be sufficient to find an element and you need to combine additional attributes for a precise match. In the following example, multiple attributes are used to locate the Login button's <input>
element:
WebElement previousButton = driver.findElement(By.cssSelector("input[type='submit'][value='Login']"));
This strategy is a bit different from the earlier strategy where we want to find elements based on only the specific attribute defined for them but not attribute values. For example, we want to look up all the <img>
elements that have the alt
attribute specified:
List<WebElement> imagesWithAlt = driver.findElements(By.cssSelector("img[alt]"));
A Boolean not()
pseudo-class can also be used to find elements not matching the specified criteria. For example, to find all the <img>
elements that do not have the alt
attribute, the following method can be used:
List<WebElement> imagesWithoutAlt = driver.findElements(By.cssSelector("img:not([alt])"));
Using the or
selector ",
" in CSS selectors, we can select a single or several elements matching the given criteria, as shown in the following code:
List<WebElement> elements = driver.findElements(By.cssSelector("div, p"));
This will select all the <div>
and all the <p>
elements:
List<WebElement> elements = driver.findElements(By.cssSelector("div.first, div.last"));
This will select <div>
with class first and last.
CSS selector provides a way to find elements matching partial attribute values. This is very useful for testing applications where attribute values are dynamically assigned and change every time a page is requested. For example, ASP.NET applications exhibit this kind of behavior, where IDs are generated dynamically. The following table explains the use of CSS partial match syntax:

How it works...
CSS selector is a pattern and the part of a CSS rule that matches a set of elements in an HTML or XML document.
The majority of browsers support CSS parsing for applying styles to these elements. Selenium WebDriver uses a CSS parsing engine to locate the elements on a page. CSS selectors provide various methods, rules, and patterns to locate the element on a page.
Using CSS selector, the test can find elements in multiple ways using Class, ID, attribute values, and text contents, as described in this recipe.
See also
- The Finding elements using advanced CSS selectors recipe