View All CSS Tutorials

Attribute Selectors CSS Guide

Learn how attribute selectors work in CSS and how to target elements based on HTML attributes. This beginner-friendly guide explains attribute selector syntax, exact matches, input types, required fields, link attributes, external links, file downloads, data attributes, selector operators, specificity, and common mistakes.

Infographic explaining CSS attribute selectors, including square bracket syntax, input type selectors, href patterns, data attributes, selector operators, specificity, and common mistakes.

Introduction

CSS selectors tell the browser which HTML elements to style.

You can select elements by tag name:

CSS
button {  padding: 10px 16px;}

You can select elements by class:

CSS
.button {  padding: 10px 16px;}

You can select elements by ID:

CSS
#main-content {  max-width: 1000px;}

CSS also lets you select elements by their HTML attributes.

These are called attribute selectors.

For example, you can select inputs by their type attribute:

CSS
input[type=”email”] {  border-color: blue;}

You can select links by their href attribute:

CSS
a[href] {  text-decoration: underline;}

You can select links that open in a new tab using the target attribute:

CSS
a[target=”_blank”] {  font-weight: bold;}

Attribute selectors are useful when you want to style elements based on information already written in the HTML.

What Is an Attribute?

An attribute adds extra information to an HTML element.

For example:

HTML
<input type=”email” name=”email”>

This input has two attributes:

TEXT
typename

The type attribute says what kind of input it is.

The name attribute gives the form field a name when form data is submitted.

Another example:

HTML
<a href=”https://example.com” target=”_blank”>Visit Example</a>

This link has two attributes:

TEXT
hreftarget

The href attribute says where the link goes.

The target attribute says how the link should open.

CSS attribute selectors let you target elements based on these attributes.

What Is an Attribute Selector?

An attribute selector selects elements by looking at their attributes.

A basic attribute selector uses square brackets:

CSS
[attribute] {  property: value;}

For example:

CSS
[target] {  font-weight: bold;}

This selects any element that has a target attribute.

You can also combine an attribute selector with an element selector:

CSS
a[target] {  font-weight: bold;}

This selects only <a> elements that have a target attribute.

That is usually safer than selecting every element with the attribute.

Selecting Elements That Have an Attribute

The simplest attribute selector checks whether an attribute exists.

Example:

CSS
a[target] {  font-weight: bold;}

HTML:

HTML
<a href=”about.html”>About</a> <a href=”https://example.com” target=”_blank”>External site</a>

The CSS selects the second link because it has a target attribute.

It does not select the first link because the first link does not have target.

This kind of selector does not care what the attribute value is.

It only checks whether the attribute is present.

Selecting Elements by Exact Attribute Value

You can select elements when an attribute has an exact value.

The syntax is:

CSS
element[attribute=”value”] {  property: value;}

Example:

CSS
input[type=”email”] {  border-color: blue;}

HTML:

HTML
<input type=”text” name=”name”><input type=”email” name=”email”><input type=”password” name=”password”>

This CSS selects only the email input:

HTML
<input type=”email” name=”email”>

It does not select the text input or password input.

The attribute value must match exactly.

Attribute Selectors with Input Types

Form inputs often use the type attribute.

Examples:

HTML
<input type=”text”><input type=”email”><input type=”password”><input type=”search”><input type=”checkbox”><input type=”radio”><input type=”submit”>

You can style each type differently:

CSS
input[type=”text”],input[type=”email”],input[type=”password”],input[type=”search”] {  width: 100%;  padding: 10px;}

This selector list targets text-like inputs.

You can style submit buttons separately:

CSS
input[type=”submit”] {  padding: 10px 16px;  cursor: pointer;}

Attribute selectors are useful here because many form controls use the same <input> element but behave differently depending on type.

Why Input Attribute Selectors Are Useful

Without attribute selectors, this CSS would affect every input:

CSS
input {  width: 100%;}

That may be a problem.

It would also affect checkboxes and radio buttons.

For example:

HTML
<input type=”checkbox” id=”terms”><label for=”terms”>I agree to the terms</label>

A checkbox should not usually be width: 100%.

A more careful approach is:

CSS
input[type=”text”],input[type=”email”],input[type=”password”],input[type=”search”] {  width: 100%;}

This targets the larger text-entry fields without affecting checkboxes and radio buttons.

Styling Required Fields

HTML form controls can use the required attribute:

HTML
<input type=”email” name=”email” required>

You can select required fields:

CSS
input[required],textarea[required],select[required] {  border-color: #0055cc;}

This targets form controls that have the required attribute.

You can also combine this with a type selector:

CSS
input[type=”email”][required] {  border-color: navy;}

This selects only required email inputs.

Combining Multiple Attribute Selectors

You can use more than one attribute selector on the same element.

Example:

CSS
input[type=”email”][required] {  border-color: navy;}

This means:

TEXT
select input elementswhere type=”email”and required is present

HTML:

HTML
<input type=”email” required><input type=”email”><input type=”text” required>

Only the first input matches both conditions.

The second has type="email" but is not required.

The third is required but is not an email input.

Links use the href attribute.

Example:

HTML
<a href=”about.html”>About</a>

You can select links that have an href attribute:

CSS
a[href] {  color: #0055cc;}

This targets links with destinations.

It does not target an <a> element without href:

HTML
<a>Placeholder link</a>

In most real cases, links should have meaningful href values if they are intended to navigate somewhere.

You can use attribute selectors to target links based on the start of the href value.

For example:

CSS
a[href^=”https://”] {  font-weight: bold;}

The ^= operator means “starts with”.

This selects links whose href starts with https://.

HTML:

HTML
<a href=”about.html”>About</a><a href=”https://example.com”>External website</a>

The second link matches.

The first link does not.

This can be useful for styling external links differently.

Links can use target="_blank" to open in a new browsing context.

Example:

HTML
<a href=”https://example.com” target=”_blank”>Visit Example</a>

You can select these links:

CSS
a[target=”_blank”] {  font-weight: bold;}

This targets links where the target attribute is exactly _blank.

You might use this to add a visual cue:

CSS
a[target=”_blank”]::after {  content: ” ↗”;}

This adds a small symbol after links that open in a new tab.

Use this kind of visual cue carefully so it improves clarity rather than adding clutter.

Attribute Selector Operators

CSS supports several attribute selector patterns.

The most common ones are:

TEXT
[attr] selects elements with the attribute[attr=”value”] selects an exact value[attr^=”value”] selects values that start with something[attr$=”value”] selects values that end with something[attr*=”value”] selects values that contain something[attr~=”value”] selects a word in a space-separated list[attr|=”value”] selects a value or value followed by a hyphen

You do not need to memorise every operator immediately.

Start with [attr] and [attr="value"].

Then learn the others when you need more flexible matching.

Exact Match: [attr="value"]

The exact match selector checks whether the attribute value matches exactly.

Example:

CSS
input[type=”password”] {  letter-spacing: 0.05em;}

HTML:

HTML
<input type=”password”><input type=”text”>

Only the password input matches.

Another example:

CSS
a[target=”_blank”] {  font-weight: bold;}

This selects links where target is exactly _blank.

Exact match selectors are clear and common.

Starts With: [attr^="value"]

The ^= operator means the attribute value starts with a certain string.

Example:

CSS
a[href^=”https://”] {  color: darkgreen;}

This matches:

HTML
<a href=”https://example.com”>Secure external link</a>

It does not match:

HTML
<a href=”about.html”>Internal page</a>

This can be useful when styling links by URL pattern.

Another example:

CSS
a[href^=”mailto:”] {  color: purple;}

This selects email links:

HTML
<a href=”mailto:[email protected]”>Email us</a>

Ends With: [attr$="value"]

The $= operator means the attribute value ends with a certain string.

Example:

CSS
a[href$=”.pdf”] {  font-weight: bold;}

This matches:

HTML
<a href=”files/report.pdf”>Download report</a>

It does not match:

HTML
<a href=”files/report.docx”>Download document</a>

This can be useful for styling links to file types.

Other examples:

CSS
a[href$=”.zip”] {  font-weight: bold;}
CSS
img[src$=”.svg”] {  max-width: 100%;}

Use this carefully because URLs may include query strings that change what the value ends with.

Contains: [attr*="value"]

The *= operator means the attribute value contains a certain string.

Example:

CSS
a[href*=”example.com”] {  font-weight: bold;}

This matches:

HTML
<a href=”https://example.com/page”>Example page</a>

It also matches:

HTML
<a href=”https://docs.example.com”>Example docs</a>

The value only needs to appear somewhere inside the attribute.

This is flexible, but it can also match more than you expect.

Use contains selectors carefully.

Space-Separated Word Match: [attr~="value"]

The ~= operator checks for a word inside a space-separated attribute value.

This is commonly useful for attributes that contain lists of words.

Example:

CSS
[data-tags~=”featured”] {  border: 2px solid navy;}

HTML:

HTML
<article data-tags=”featured tutorial css”>  Featured article</article>

This matches because featured is one of the space-separated words.

It would not match:

HTML
<article data-tags=”featured-tutorial”>  Different article</article>

because featured is not a separate word there.

Hyphen Match: [attr|="value"]

The |= operator matches an exact value or a value followed by a hyphen.

It is often associated with language codes.

Example:

CSS
[lang|=”en”] {  font-family: Arial, sans-serif;}

This matches:

HTML
<p lang=”en”>English text.</p>

It also matches:

HTML
<p lang=”en-GB”>British English text.</p>

It does not match:

HTML
<p lang=”fr”>French text.</p>

This selector is less common than exact, starts-with, ends-with, and contains selectors, but it is useful in specific cases.

Attribute Selectors with Data Attributes

HTML supports custom data attributes.

They start with data-.

Example:

HTML
<article data-featured=”true”>  Featured article</article>

You can select them with CSS:

CSS
[data-featured=”true”] {  border: 2px solid navy;}

Another example:

HTML
<button data-variant=”primary”>Save</button><button data-variant=”secondary”>Cancel</button>

CSS:

CSS
button[data-variant=”primary”] {  background-color: navy;  color: white;} button[data-variant=”secondary”] {  background-color: white;  color: navy;}

Data attributes can be useful for styling, scripting, and storing small pieces of custom information.

Attribute Selectors and Case Sensitivity

Attribute selector matching can be case-sensitive or case-insensitive depending on the attribute, document language, and selector flags.

For normal learning projects, the safest approach is to keep attribute values consistent.

For example, prefer:

HTML
<input type=”email”>

rather than mixing:

HTML
<input type=”Email”>

You can also use a case-insensitive flag in some selectors:

CSS
a[href$=”.pdf” i] {  font-weight: bold;}

The i means case-insensitive matching.

This can match .pdf, .PDF, or .Pdf.

You do not need this often at first, but it is useful to know it exists.

Attribute Selectors and Specificity

An attribute selector has similar specificity to a class selector.

For example:

CSS
input[type=”email”] {  border-color: blue;}

has more specificity than:

CSS
input {  border-color: gray;}

HTML:

HTML
<input type=”email”>

If both rules apply, the email-specific rule can override the general input rule.

Attribute selectors are not as specific as ID selectors, but they are more specific than simple type selectors.

Combining Attribute Selectors with Classes

You can combine attribute selectors with class selectors.

HTML:

HTML
<input class=”form-control” type=”email” required>

CSS:

CSS
.form-control[type=”email”] {  border-color: blue;}

This means:

TEXT
select elements with class=”form-control”that also have type=”email”

You can also write:

CSS
.form-control[required] {  border-left: 4px solid navy;}

This targets required form controls with the form-control class.

Combining Attribute Selectors with Pseudo-Classes

Attribute selectors can work with pseudo-classes.

Example:

CSS
input[type=”email”]:focus {  outline: 2px solid #0055cc;}

This selects an email input when it has focus.

Another example:

CSS
a[target=”_blank”]:hover {  text-decoration: underline;}

This styles links that open in a new tab when the user hovers over them.

These combinations are common when styling form states and link states.

Attribute Selectors with Forms

Here is a form example:

HTML
<form>  <label for=”name”>Name</label>  <input type=”text” id=”name” name=”name”>   <label for=”email”>Email</label>  <input type=”email” id=”email” name=”email” required>   <label for=”password”>Password</label>  <input type=”password” id=”password” name=”password”>   <input type=”submit” value=”Create account”></form>

CSS:

CSS
input[type=”text”],input[type=”email”],input[type=”password”] {  width: 100%;  padding: 10px;} input[required] {  border-left: 4px solid navy;} input[type=”submit”] {  padding: 10px 16px;  cursor: pointer;}

This uses attribute selectors to style different inputs appropriately.

Here is a link example:

HTML
<p>  <a href=”about.html”>About us</a></p> <p>  <a href=”https://example.com” target=”_blank”>External resource</a></p> <p>  <a href=”files/guide.pdf”>Download the guide</a></p>

CSS:

CSS
a[href^=”https://”] {  font-weight: bold;} a[target=”_blank”]::after {  content: ” ↗”;} a[href$=”.pdf”]::after {  content: ” PDF”;}

This styles external links, links opening in new tabs, and PDF links.

Be careful with generated content.

If a label is important for understanding, consider including it in the HTML rather than only in CSS.

Attribute Selectors with Target

The target attribute commonly appears on links.

Example:

HTML
<a href=”https://example.com” target=”_blank”>Visit Example</a>

CSS:

CSS
a[target=”_blank”] {  font-weight: bold;}

This can help indicate that the link behaves differently.

However, opening links in new tabs or windows can affect user experience.

When you use target="_blank", it is often good practice to make that behaviour clear to users.

A visible cue can help:

CSS
a[target=”_blank”]::after {  content: ” opens in new tab”;}

This may be too long for some designs, but it shows the idea.

The download attribute can be used on links.

Example:

HTML
<a href=”files/template.zip” download>Download template</a>

You can select download links:

CSS
a[download] {  font-weight: bold;}

This selects links that have a download attribute.

You can also combine it with file extension matching:

CSS
a[href$=”.zip”][download] {  color: darkgreen;}

This selects download links that point to .zip files.

A Complete Example

HTML:

HTML
<!DOCTYPE html><html lang=”en”><head>  <meta charset=”UTF-8″>  <title>Attribute Selectors Example</title>  <link rel=”stylesheet” href=”styles.css”></head><body>   <main class=”container”>    <h1>Attribute Selectors</h1>     <form class=”signup-form”>      <label for=”name”>Name</label>      <input type=”text” id=”name” name=”name”>       <label for=”email”>Email address</label>      <input type=”email” id=”email” name=”email” required>       <label for=”password”>Password</label>      <input type=”password” id=”password” name=”password”>       <input type=”submit” value=”Create account”>    </form>     <section>      <h2>Useful Links</h2>       <p>        <a href=”about.html”>About this website</a>      </p>       <p>        <a href=”https://example.com” target=”_blank”>External resource</a>      </p>       <p>        <a href=”files/css-guide.pdf”>Download the CSS guide</a>      </p>    </section>  </main> </body></html>

CSS:

CSS
/* Text-like form fields */input[type=”text”],input[type=”email”],input[type=”password”] {  width: 100%;  padding: 10px;  margin-bottom: 16px;} /* Required fields */input[required] {  border-left: 4px solid navy;} /* Submit input */input[type=”submit”] {  padding: 10px 16px;  cursor: pointer;} /* External links */a[href^=”https://”] {  font-weight: bold;} /* Links that open in a new tab */a[target=”_blank”]::after {  content: ” ↗”;} /* PDF links */a[href$=”.pdf”] {  font-weight: bold;}

This example uses attribute selectors for form controls, required fields, external links, new-tab links, and PDF links.

How the Complete Example Works

This selector targets text-like input fields:

CSS
input[type=”text”],input[type=”email”],input[type=”password”] {  width: 100%;}

This selector targets required inputs:

CSS
input[required] {  border-left: 4px solid navy;}

This selector targets submit inputs:

CSS
input[type=”submit”] {  cursor: pointer;}

This selector targets links that start with https://:

CSS
a[href^=”https://”] {  font-weight: bold;}

This selector targets links that open in a new tab:

CSS
a[target=”_blank”]::after {  content: ” ↗”;}

This selector targets PDF links:

CSS
a[href$=”.pdf”] {  font-weight: bold;}

Each rule selects elements based on attributes already present in the HTML.

Common Mistake: Forgetting Square Brackets

Incorrect:

CSS
input type=”email” {  border-color: blue;}

Correct:

CSS
input[type=”email”] {  border-color: blue;}

Attribute selectors use square brackets.

The attribute condition goes inside the brackets.

Common Mistake: Confusing Classes with Attributes

This selects a class:

CSS
.email {  color: blue;}

This selects an attribute value:

CSS
input[type=”email”] {  color: blue;}

They are not the same.

HTML for the class selector:

HTML
<p class=”email”>Email us today.</p>

HTML for the attribute selector:

HTML
<input type=”email”>

Use class selectors for class names.

Use attribute selectors for attributes and attribute values.

Common Mistake: Using Exact Match When the Value Can Vary

This selector matches only exactly .pdf at the end:

CSS
a[href$=”.pdf”] {  font-weight: bold;}

It may not match a URL like:

HTML
<a href=”files/guide.pdf?download=true”>Download guide</a>

because the value ends with true, not .pdf.

In this case, a contains selector may be more useful:

CSS
a[href*=”.pdf”] {  font-weight: bold;}

But use *= carefully because it can match more than expected.

Common Mistake: Overusing Attribute Selectors Instead of Classes

This works:

CSS
button[data-variant=”primary”] {  background-color: navy;}

But for many simple styling patterns, a class may be clearer:

HTML
<button class=”button button-primary”>Save</button>
CSS
.button-primary {  background-color: navy;}

Attribute selectors are useful when the attribute itself is meaningful.

Classes are often clearer for general styling.

Use the tool that best describes the purpose.

Common Mistake: Making Selectors Too Specific

This may be more specific than needed:

CSS
form.signup-form input[type=”email”][required] {  border-color: navy;}

A simpler selector may be enough:

CSS
input[type=”email”][required] {  border-color: navy;}

or:

CSS
.form-control[required] {  border-color: navy;}

Overly specific selectors can make CSS harder to override later.

Use enough specificity to target the element, but not more than necessary.

Common Mistake: Using Generated Content for Essential Information

This can add a visual note:

CSS
a[target=”_blank”]::after {  content: ” ↗”;}

That may be fine as a visual cue.

However, do not put essential information only in CSS if users need it to understand the page.

Important content should usually be present in the HTML.

CSS should support presentation, not become the only source of meaning.

Common Mistake: Forgetting Attribute Values Must Match

CSS:

CSS
input[type=”email”] {  border-color: blue;}

HTML:

HTML
<input type=”text” name=”email”>

This does not match because the input type is text, not email.

The name attribute is email, but the selector checks the type attribute.

To select by name, you would write:

CSS
input[name=”email”] {  border-color: blue;}

Make sure the selector checks the correct attribute.

Common Mistake: Styling All Inputs the Same

This can cause layout problems:

CSS
input {  width: 100%;}

It affects text inputs, checkboxes, radio buttons, submit buttons, hidden inputs, and more.

A better approach:

CSS
input[type=”text”],input[type=”email”],input[type=”password”],input[type=”search”] {  width: 100%;}

This targets text-entry fields more carefully.

Attribute selectors help prevent broad input rules from affecting controls that should look different.

Best Practices

Use [attr] to select elements that have an attribute.

Use [attr="value"] to select exact attribute values.

Use input[type="..."] to style different form controls appropriately.

Use a[href] to target real links.

Use a[target="_blank"] to style links that open in a new tab.

Use a[href^="https://"] for links that start with a URL pattern.

Use a[href$=".pdf"] for links ending with a file extension.

Use *= carefully because it can match more than expected.

Combine attribute selectors with element or class selectors for clearer targeting.

Avoid making selectors more specific than necessary.

Use classes when they communicate styling intent more clearly.

Keep important content in HTML, not only in CSS-generated content.

Use browser developer tools to check whether an attribute selector matches.

Summary

Attribute selectors let CSS target elements based on HTML attributes.

The simplest form checks whether an attribute exists:

CSS
a[href] {  color: blue;}

An exact match checks for a specific value:

CSS
input[type=”email”] {  border-color: blue;}

You can also match parts of attribute values:

CSS
a[href^=”https://”] {  font-weight: bold;}
CSS
a[href$=”.pdf”] {  font-weight: bold;}
CSS
a[href*=”example.com”] {  font-weight: bold;}

Attribute selectors are especially useful for forms and links.

They let you style email fields, password fields, required fields, submit inputs, external links, download links, and links that open in new tabs.

The main idea is simple:

TEXT
Attribute selectors style elements based on information already written in the HTML.

Used carefully, they help you write more precise CSS without adding unnecessary classes.