Skip to content

CSS Selectors

The CSS selectors are based off of the CSS specification and includes not only stable selectors, but also selectors currently under development from the draft specifications. Primarily support has been added for selectors that were feasible to implement and most likely to get practical use.

When speaking about namespaces, they only apply to XML, XHTML, or when dealing with recognized foreign tags in HTML5. Currently, Beautiful Soup's html5lib parser is the only parser that will return the appropriate namespaces for a HTML5 document. If you are using XHTML, you have to use the Beautiful Soup's lxml-xml parser (or xml for short) to get the appropriate namespaces in an XHTML document. In addition to using the correct parser, you must provide a dictionary of namespaces to Soup Sieve in order to use namespace selectors. See the documentation on namespaces to learn more.

While an effort is made to mimic CSS selector behavior, there may be some differences or quirks, please report issues if any are found.

Symbol Description
Some selectors are dependent upon certain states in a web browser or other context which is simply not present outside a web browser. An example would be the :focus selector. In Soup Sieve, :focus will match nothing because elements cannot be focused outside of a browser without simulation, or somehow connecting to a browser. These types of selectors, that provide no meaningful information in Soup Sieve, will be marked with .
Some selectors are very specific to HTML and either have no meaningful representation in XML, or such functionality has not been implemented. Selectors that are HTML only will be noted with , and will match nothing if used in XML.
Soup Sieve has implemented a couple non-standard selectors. These can contain useful selectors that were rejected from the official CSS specifications, selectors implemented by other systems such as JQuery, or even selectors specifically created for Soup Sieve. If a selector is considered non standard, it will be marked with .
All selectors that are from the current working draft of CSS4 are considered experimental and are marked with . Additionally, if there are other immature selectors, they may be marked as experimental as well. Experimental may mean we are not entirely sure if our implementation is correct, that things may still be in flux as they are part of a working draft, or even both.

Additional Reading

If usage of a selector is not clear in this documentation, you can find more information by reading these specification documents:

CSS Level 3 Specification
Contains the latest official document outlying official behaviors of CSS selectors.
CSS Level 4 Working Draft
Contains the latest published working draft of the CSS level 4 selectors which outlines the experimental new selectors and experimental behavioral changes.
HTML5
The HTML 5.0 specification document. Defines the semantics regarding HTML.
HTML Living Standard
The HTML Living Standard document. Defines semantics regarding HTML.

Working Draft Selectors

If at anytime a working draft drops a selector from the current draft, it will most likely also be removed here, most likely with a deprecation path, except where there may be a conflict that requires a less graceful transition. One exception is in the rare case that the selector is found to be far too useful despite being rejected. In these cases, we may adopt them as "custom" selectors.

Not Implemented

Pseudo elements are not supported as they do not represent real elements.

At-rules (@page, etc.) are also not supported.

Escapes

Soup Sieve selectors support using CSS escapes. So if you need provide Unicode, or non-standard characters, you can use CSS style escapes.

Escapes can be specified with a backslash followed by 1 - 6 hexadecimal digits: \20AC, \0020AC, etc. If you need to terminate an escape to avoid it accumulating unintended hexadecimal characters, you can use a space: \0020AC dont-escape-me. You can also escape any non-hexadecimal character, and it will be treated as that character: \++. The one exception is that you cannot escape the form feed, newline, or carriage return.

Basic Selectors

Type Selectors

Type selectors match elements by node name.

If a default namespace is defined in the namespace dictionary, and no namespace is explicitly defined, it will be assumed that the element must be in the default namespace.

Type Example

The following would select all <div> elements.

div

Universal Selectors

The Universal selector (*) matches elements of any type.

Example

The following would match any element: div, a, p, etc.

*

ID Selectors

The ID selector matches an element based on its id attribute. The ID must match exactly.

Example

The following would select the element with the id some-id.

#some-id

Class Selectors

The class selector matches an element based on the values contained in the class attribute. The class attribute is treated as a whitespace separated list, where each item is a class.

Example

The following would select the elements with the class some-class.

.some-class

Attribute Selectors

The attribute selector matches an element based on its attributes. When specifying a value of an attribute, if it contains whitespace or special characters, you should quote them with either single or double quotes.

[attribute]

Represents elements with an attribute named attribute.

Example

The following would select all elements with a target attribute.

[target]
[attribute=value]

Represents elements with an attribute named attribute that also has a value of value.

Example

The following would select all elements with the target attribute whose value was _blank.

[target=_blank]
[attribute~=value]

Represents elements with an attribute named attribute whose value is a space separated list which contains value.

Example

The following would select all elements with a title attribute containing the word flower.

[title~=flower]
[attribute|=value]

Represents elements with an attribute named attribute whose value is a dash separated list that starts with value.

Example

The following would select all elements with a lang attribute value starting with en.

[lang|=en]
[attribute^=value]

Represents elements with an attribute named attribute whose value starts with value.

Example

The following selects every <a> element whose href attribute value begins with https.

a[href^="https"]
[attribute$=value]

Represents elements with an attribute named attribute whose value ends with value.

Example

The following would select every <a> element whose href attribute value ends with .pdf.

a[href$=".pdf"]
[attribute*=value]

Represents elements with an attribute named attribute whose value containing the substring value.

Example

The following would select every <a> element whose href attribute value contains the substring sometext.

a[href*="sometext"]
[attribute!=value]

Equivalent to :not([attribute=value]).

Example

Selects all elements who do not have a target attribute or do not have one with a value that matches _blank.

[target!=_blank]
[attribute operator value i]

Represents elements with an attribute named attribute and whose value, when the operator is applied, matches value without case sensitivity.

Example

The following would select any element with a title that equals flower regardless of case.

[title=flower i]
[attribute operator value s]

Represents elements with an attribute named attribute and whose value, when the operator is applied, matches value with case sensitivity.

Example

The following would select any element with a type that equals submit. Case sensitivity will be forced.

[type=submit s]

Namespace Selectors

Namespace selectors are used in conjunction with type selectors. They are specified with by declaring the namespace and the type separated with |: namespace|type. namespace in this context is the prefix defined via the namespace dictionary. The prefix does not need to match the prefix in the document as it is the namespace that is compared, not the prefix.

The universal selector (*) can be used to represent any namespace as it can with type.

Namespaces can be used with attribute selectors as well except that when [|attribute] is used, it is equivalent to [attribute].

*|*

Represents any element with or without a namespace.

Example

The following would select the <div> element with or without a namespace.

*|div
namespace|*

Represents any element with a namespace that is associated with the prefix namespace as defined in the namespace dictionary.

Example

The following would select the <circle> element with the namespace svg.

svg|circle
|*

Represents any element with no defined namespace.

Example

The following would select a <div> element that has no namespace.

|div

Combinators and Selector Lists

CSS employs a number of tokens in order to represent lists or to provide relational context between two selectors.

Selector Lists

Selector lists use the comma (,) to join multiple selectors in a list.

Example

The following would select both <div> elements and <h1> elements.

div, h1

Descendant Combinator

Descendant combinators combine two selectors with whitespace ( ) in order to signify that the second element is matched if it has an ancestor that matches the first element.

Example

The following would select all <p> elements inside <div> elements.

div p

Child combinator

Child combinators combine two selectors with > in order to signify that the second element is matched if it has a parent that matches the first element.

Example

The following would select all <p> elements where the parent is a <div> element.

div > p

General sibling combinator

General sibling combinators combine two selectors with ~ in order to signify that the second element is matched if it has a sibling that precedes it that matches the first element.

Example

The following would select every <ul> element that is preceded by a <p> element.

p ~ ul

Adjacent sibling combinator

Adjacent sibling combinators combine two selectors with + in order to signify that the second element is matched if it has an adjacent sibling that precedes it that matches the first element.

Example

The following would select all <p> elements that are placed immediately after <div> elements.

div + p

Pseudo-Classes

:active

Selects active elements.

Example

Active states are not applicable, so this will never match.

a:active

Selects every <a>, <area>, or <link> element that has an href attribute, independent of whether it has been visited.

Example

All links are treated as unvisited, so this will match every <a> element with an href attribute.

a:any-link

:checked

Selects any <input type="radio"/>, <input type="checkbox"/>, or <option> element (in a <select> element) that is checked or toggled to an on state.

Example

Selects every checked <input> element.

input:checked

:contains()

Selects elements that contain the provided text. Text can be found in either itself, or its descendants.

Contains was originally included in a CSS early draft, but was in the end dropped from the draft. Soup Sieve implements it how it was originally proposed in the draft with the addition that :contains() can accept either a single value, or a comma separated list of values. An element needs only to match at least one of the items in the comma separated list to be considered matching.

Contains

:contains() is an expensive operation as it scans all the text nodes of an element under consideration, which includes all descendants. Using highly specific selectors can reduce how often it is evaluated.

Example

Select all <p> elements that contain "text" in their content.

p:contains(text)

:current

:current

Selects the element, or an ancestor of the element, that is currently being displayed.

Example

Time-dimensional pseudo-classes require a user agent which is not present in Beautiful Soup, so this will match nothing.

p:current
:current(sel1, sel2, ...)

The functional form is like :is() and takes a selector list:

Example

Time-dimensional pseudo-classes require a user agent which is not present in Beautiful Soup, so this will match nothing.

:current(p, li, dt, dd)

:default

Selects any form element that is the default among a group of related elements, including: <button>, <input type="checkbox">, <input type="radio">, <option> elements.

Example

Selects all <inputs> elements that are the default among their related elements.

input:default

:defined

Normally, this represents normal elements (names without hyphens) and custom elements (names with hyphens) that have been properly added to the custom element registry. Since elements cannot be added to a custom element registry in Beautiful Soup, this will select all elements that are not custom tags. :defined is a HTML specific selector, so it doesn't apply to XML.

Example

Selects all defined elements under body.

body :defined

:dir()

Selects elements based on text directionality. Accepts either ltr or rtl for "left to right" and "right to left" respectively.

Example

Selects all <div> elements that have a text direction of left to right.

div:dir(ltr)

:disabled

Selects any element that is disabled.

Example

Selects every disabled <input> element.

input:disabled

:empty

Selects elements that have no children and no text (whitespace is ignored).

Example

Selects every <p> element that has no children and either no text.

p:empty

:enabled

Selects any element that is enabled.

Example

Selects every enabled <input> element.

input:enabled

:first-child

Selects the first child in a group of sibling elements.

Example

Selects every <p> that is also the first child of its parent.

p:first-child

:first-of-type

Selects the first child of a given type in a group of sibling elements.

Example

Selects every <p> element that is the first <p> element of its parent.

p:first-of-type

:focus

Represents an an element that has received focus.

Example

Focus states are not possible in Beautiful Soup, so this will never match.

input:focus

:focus-visible

Selects an element that matches :focus and the user agent determines that the focus should be made evident on the element.

Example

Focus states are not possible in Beautiful Soup, and since a user agent also needs to raise that the focus should be made evident, this will never match.

a:focus-visible

:focus-within

Selects an element that has received focus or contains an element that has received focus.

Example

Focus states are not possible in Beautiful Soup, so this will never match.

div:focus-within

:future

Selects an element that is defined to occur entirely after a :current element.

Example

Time-dimensional pseudo-classes require a user agent which is not present in Beautiful Soup, so this will match nothing.

p:future

:has()

Selects an element if any of the relative selectors passed as parameters (which are relative to the :scope of the given element), match at least one element.

Example

Selects elements that have a direct child that is a <div> or that have a sibling of <p> immediately following it.

:has(> div, + p)

:host

:host

Select the element hosting a shadow tree.

Example

Matches nothing as there is no Shadow DOM in Beautiful Soup.

:host
:host(sel1, sel2, ...)

The functional form of :host takes a selector list and matches the shadow host only if it matches one of the selectors in the list.

Example

Matches nothing as there is no Shadow DOM in Beautiful Soup.

:host(h1)

:host-context()

Selects the element hosting shadow tree, but only if one of the element's ancestors match a selector in the selector list.

Example

Matches nothing as there is no Shadow DOM in Beautiful Soup.

:host-context(main article)

:hover

Selects an element when the user interacts with it by hovering over it with a pointing device.

Example

Hovering is not possible in Beautiful Soup, so this will match nothing.

a:hover

:in-range

Selects all <input> elements whose values are in range according to their type, min, and max attributes.

Example

Matches all <input type="number"/> elements whose values are in range.

input[type="number"]:in-range

:indeterminate

Selects all form elements whose are in an indeterminate state.

Example

Matches all <input type="radio"/> elements that are in a form and none of the other radio controls with the same name are selected.

input[type="radio"]:indeterminate

:is()

Selects an element, but only if it matches at least one selector in the selector list.

Example

Matches <div> elements and <p> elements.

:is(div, p)

:lang()

:lang(language)

Selects an element whose associated language matches the provided language or whose language starts with the provided language followed by a -. Language is determined by the rules of the document type.

Example

Selects all elements with language en. Will also match languages of en-US, en-GB, etc.

:lang(en)
:lang(language1, language2, ...)

The level 4 :lang() adds the ability to define multiple languages, the ability to use * for wildcard language matching.

Example

Select all elements with language de-CH, it-CH, fr-CH, and rm-CH. Will also match en, en-US, and en-GB. See CSS4 specification for more info on wildcard matching rules.

:lang('*-CH', en)

:last-child

Selects the last element among a group of sibling elements.

Example

Selects every <p> element that is also the last child of its parent.

p:last-child

:last-of-type

Selects the last child of a given type in a group of sibling elements.

Example

Selects every <p> element that is the last <p> element of its parent.

p:last-of-type

Selects a link (every <a>, <link>, and <area> element with an href attribute) that has not yet been visited.

Example

Selects all <a> elements since Beautiful Soup does not have visited states.

a:link

Selects link (every <a>, <link>, and <area> element with an href attribute) elements whose absolute URL matches the element’s own document URL.

Example

Since documents in Beautiful Soup are not live documents, they do not contain the context of the document's URL, so this will not match anything.

a:local-link

:not()

:not(selector)

Selects all elements that do not match the selector.

Example

Selects all <p> elements that do not have class exclude.

p:not(.exclude)
:not(selector1, selector2, ...)

Selects all elements that do not match any of the selectors in the selector list.

Example

Selects all <p> elements that do not have class exclude and attribute style.

p:not(.exclude, [style])

:nth-child()

:nth-child(keyword)

:nth-child allows the keywords even and odd, and will respectively select elements whose position is either even or odd amongst a group of siblings.

Example

Select every odd element that is also a <p> element.

p:nth-child(odd)
:nth-child(an+b)

Selects elements based on their position in a group of siblings, using the pattern an+b, for every positive integer or zero value of n. The index of the first element is 1. The values a and b must both be integers.

Example

Selects the first three elements: 1 = 1*0+3, 2 = -1*1+3, 3 = -1*2+3.

:nth-child(-n+3)
:nth-child(an+b [of S]?)

Selects from a sub-group of sibling elements that all match the selector list ([of S]?), based on their position within that sub-group, using the pattern an+b, for every positive integer or zero value of n. The index of the first element is 1. The values a and b must both be integers.

Essentially, img:nth-of-type(2) would be equivalent to :nth-child(2 of img). The advantage of this of using :nth-child(an+b [of S]?) is that :nth-of-type is restricted to types, while :nth-child(an+b [of S]?) can use compound selectors.

Example

Selects the second element of a group of sibling elements that match all match img.

:nth-child(2 of img)

:nth-last-child()

:nth-last-child(keyword)

:nth-last-child allows the keywords even and odd, and will respectively select elements whose position is either even or odd amongst a group of siblings, counting from the end.

Example

Select every odd element that is also a <p> element, counting from the end.

p:nth-child(odd)
:nth-last-child(an+b)

Counting from the end, selects elements based on their position in a group of siblings, using the pattern an+b, for every positive integer or zero value of n. The index of the first element is 1. The values a and b must both be integers.

Example

Selects the last three elements: 1 = 1*0+3, 2 = -1*1+3, 3 = -1*2+3.

:nth-child(-n+3)
:nth-last-child(an+b [of S]?)

Counting from the end, selects from a sub-group of sibling elements that all match the selector list ([of S]?), based on their position within that sub-group, using the pattern an+b, for every positive integer or zero value of n. The index of the first element is 1. The values a and b must both be integers.

Essentially, img:nth-last-of-type(2) would be equivalent to :nth-last-child(2 of img). The advantage of this of using :nth-last-child(an+b [of S]?) is that :nth-last-of-type is restricted to types, while :nth-last-child(an+b [of S]?) can use compound selectors.

Example

Selects the second element (counting from the end) of a group of sibling elements that match all match img.

:nth-last-child(2 of img)

:nth-last-of-type()

:nth-last-of-type(keyword)

:nth-last-of-type allows the keywords even and odd, and will respectively select elements, from a sub-group of sibling elements that all match the given type, whose position is either even or odd amongst that sub-group of siblings, counting from the end.

Example

Counting from the end, selects every even <p> amongst sibling <p> elements.

p:nth-last-of-type(even)
:nth-last-of-child(an+b)

Counting from the end, selects from a sub-group of sibling elements that all match the given type, based on their position within that sub-group, using the pattern an+b, for every positive integer or zero value of n. The index of the first element is 1. The values a and b must both be integers.

Example

Counting from the end, selects every <p> element that is the second <p> element of its parent.

p:nth-last-of-type(2)

:nth-of-type()

:nth-of-type(keyword)

:nth-of-type allows the keywords even and odd, and will respectively select elements, from a sub-group of sibling elements that all match the given type, whose position is either even or odd amongst that sub-group of siblings.

Example

Selects every even <p> amongst sibling <p> elements.

p:nth-last-of-type(even)
:nth-of-type(an+b)

Selects from a sub-group of sibling elements that all match the given type, based on their position within that sub-group, using the pattern an+b, for every positive integer or zero value of n. The index of the first element is 1. The values a and b must both be integers.

Example

Selects every <p> element that is the second <p> element of its parent.

p:nth-of-type(2)

:only-child

Selects element without any siblings.

Example

Selects any <p> element that is the only child of its parent.

p:only-child

:only-of-type

Selects element without any siblings that matches a given type.

Example

Selects every <p> element that is the only <p> element of its parent.

p:only-of-type

:optional

Selects any <input>, <select>, or <textarea> element that does not have the required attribute set on it.

Example

Select every <input> element without a required attribute.

input:optional

:out-of-range

Selects all <input> elements whose values are out of range according to their type, min, and max attributes.

Example

Matches all <input type="number"/> elements whose values are out of range.

input[type="number"]:out-of-range

:past

Selects an element that is defined to occur entirely prior to a :current element.

Example

Time-dimensional pseudo-classes require a user agent which is not present in Beautiful Soup, so this will match nothing.

p:past

:paused

Selects an element that is capable of being played or paused (such as an audio, video, or similar resource) and is currently "paused".

Example

It is not possible to play or pause a media element in Beautiful Soup, so this will match nothing.

:paused

:placeholder-shown

Selects any <input> or <textarea> element that is currently displaying placeholder text via the placeholder attribute.

Example

Matches all <input> elements that have placeholder text that is shown.

input:placeholder-shown

:playing

Selects an element that is capable of being played or paused (such as an audio, video, or similar resource) and is currently “playing”.

Example

It is not possible to play or pause a media element in Beautiful Soup, so this will match nothing.

:playing

:read-only

Selects elements (such as <input> or <textarea>) that are not editable by the user. This does not just apply to form elements with readonly set, but it applies to any element that cannot be edited by the user.

Example

Selects every <input> element that is not editable by the user.

input:read-only

:read-write

Selects elements (such as <input> or <textarea>) that are editable by the user. This does not just apply to form elements as it applies to any element that can be edited by the user, such as a <p> element with contenteditable set on it.

Example

Selects every <input> element that is editable by the user.

input:read-only

:required

Selects any <input>, <select>, or <textarea> element that has the required attribute set on it.

Example

Select every <input> element with a required attribute.

input:required

:root

Selects the root element of a document tree.

Example

For HTML, this would select the <html> element.

:root

:scope

:scope represents the the element a match, select, or filter is being called on. If we were, for instance, using :scope on a div (sv.select(':scope > p', soup.div)) :scope would represent that div element, and no others. If called on the Beautiful Soup object which represents the entire document, it would simply select :root.

Example

Assuming that the following selector was called on a div element, it would select all <p> elements that are direct children of that associated <div> element.

:scope > p

:target

Selects a unique element (the target element) with an id matching the URL's fragment.

Example

Since there is no concept of a "targeted" element outside a user agent/browser without simulation, this will match nothing.

h1:target

:target-within

Selects a unique element with an id matching the URL's fragment or an element which contains the element.

Example

Since there is no concept of a "targeted" element outside a user agent/browser without simulation, this will match nothing.

div:target-within

:user-invalid

Selects an element with incorrect input, but only after the user has significantly interacted with it.

Example

Since a user cannot interact with the HTML outside a user agent (or some simulated environment), this will match nothing.

input:user-invalid

:visited

Selects links that have already been visited.

Example

In the Beautiful Soup, links cannot be "visited", that is a concept that only applies with a user agent/browser. As all links in Beautiful Soup are considered to be unvisited, this will match nothing.

a:visited

:where()

Selects an element, but only if it matches at least one selector in the selector list. In browsers, this also has zero specificity, but this only has relevance in a browser environment where you have multiple CSS styles, and specificity is used to see which applies. Beautiful Soup and Soup Sieve don't care about specificity.

Example

Matches <div> elements and <p> elements.

:where(div, p)