Update CSS Attribute Selectors from JavaScript

CSS attribute selectors react when the matching DOM attribute changes. Set a real attribute such as data-state, and make the selector match the exact value stored in the markup.

Last updated: October 14, 2026.

<style>
  .status-button[data-state="ready"] { background: #1769aa; color: white; }
  .status-button[data-state="busy"]  { opacity: 0.55; }
</style>

<button class="status-button" data-state="ready">Run</button>

<script>
  const button = document.querySelector('.status-button');
  button.addEventListener('click', () => {
    button.dataset.state = 'busy';
  });
</script>

The dataset.state property writes the data-state attribute, so the browser recalculates selector matching automatically. Inspect the element in developer tools to confirm the final attribute name and value.

Distinguish attributes from JavaScript properties

MDN documents that setAttribute() updates an existing attribute or creates it. Custom JavaScript properties such as element.state = "busy" do not create a matching HTML attribute. Use dataset for data-* state or setAttribute() when the attribute name is dynamic.

For boolean attributes such as disabled, presence means true regardless of the string value. Remove the attribute or set the corresponding DOM property to false to turn it off.

Match the serialized value exactly

MDN’s attribute-selector reference describes exact, word, prefix, suffix, and substring matching. Values of custom data-* attributes are normally case-sensitive, so [data-state="Ready"] does not match ready.

Prefer a small vocabulary such as ready, busy, and error. Keep accessibility state synchronized when it has meaning: a disabled control should use the actual disabled property, while expanded widgets should update aria-expanded.

If the attribute changes correctly but the appearance does not, inspect the Computed Styles panel. A more specific selector, a later rule, an inline style, or an !important declaration may win the cascade. Selector matching can be correct even when another declaration supplies the final value.

Continue with shared CSS stylesheets, accessible tabs, and tracing JavaScript errors.

Related Web Cheat Sheet guides

Sergey Kornilov

Sergey Kornilov