W3docs

CSS :indeterminate Pseudo Clase

La pseudo-clase CSS :indeterminate selecciona elementos en estado indeterminado. Lee sobre ella y practica con ejemplos.

La pseudo-clase CSS :indeterminate coincide con controles de formulario que están en un estado indeterminado — un tercer estado que no es ni "activado" ni "desactivado". Este capítulo explica qué elementos pueden entrar en ese estado, cómo activarlo y cómo darle estilo, con ejemplos ejecutables para checkboxes, grupos de radio y barras de progreso.

Qué significa "indeterminate"

Algunos controles de formulario normalmente tienen dos estados (marcado / desmarcado, o un valor de progreso conocido). El estado indeterminado representa una tercera condición "indefinida". La pseudo-clase :indeterminate apunta a tres tipos de elementos:

  • Checkboxes (<input type="checkbox">) cuya propiedad DOM indeterminate está establecida en true. Este es el clásico checkbox tri-estado "algunos, pero no todos, los elementos hijos están seleccionados".
  • Botones de radio (<input type="radio">) — cada botón en un grupo con el mismo nombre coincide mientras ninguna opción de ese grupo esté seleccionada.
  • Barras de progreso (<progress>) que no tienen atributo value, lo que significa que la duración de la tarea es desconocida y la barra se anima sin un relleno fijo.
Información

El estado indeterminado se establece en JavaScript, no en CSS — no puedes entrar en él solo con una regla CSS. Para los checkboxes se establece element.indeterminate = true mediante JavaScript. Establecer esa propiedad no cambia checked; ambas son independientes. La apariencia visual indeterminada (normalmente un guion en lugar de una marca) y la coincidencia con :checked son cosas separadas. Reiniciar el formulario con form.reset() restablece el indicador indeterminate de un checkbox a false.

La pseudo-clase :checked da estilo al estado marcado, mientras que :indeterminate da estilo al estado indefinido. Un control puede estar en uno, en el otro, o en ninguno, pero nunca en ambos al mismo tiempo. Puedes combinar :indeterminate con otras pseudo-clases como :hover para dar estilo a un elemento indeterminado solo mientras el puntero está sobre él, o con :focus para resaltarlo cuando recibe el foco del teclado.

Sintaxis

:indeterminate {
  /* css declarations */
}

Delimita el selector a un tipo de elemento específico para evitar coincidencias no deseadas:

/* Only checkboxes */
input[type="checkbox"]:indeterminate { outline: 2px dashed orange; }

/* Only radio buttons */
input[type="radio"]:indeterminate { opacity: 0.7; }

/* Only progress bars */
progress:indeterminate { opacity: 0.5; }

También puedes invertir la coincidencia con :not para apuntar a controles que han salido del estado indeterminado:

/* Style a progress bar once it has a known value */
progress:not(:indeterminate) { border: 2px solid green; }

Ejemplo: dar estilo a un checkbox indeterminado

Un checkbox solo se vuelve indeterminado cuando JavaScript establece la propiedad indeterminate en true. La regla CSS se activa en el momento en que se establece esa propiedad, y se borra en el momento en que se devuelve a false. Este ejemplo resalta el control con un box-shadow de color.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      input:indeterminate {
        box-shadow: 0 0 2px 2px #666;
      }
    </style>
  </head>
  <body>
    <h2>Indeterminate selector example</h2>
    <form>
      <input type="checkbox" id="box" /> Checkbox
      <script>
        var checkbox = document.getElementById("box");
        checkbox.indeterminate = true;
      </script>
    </form>
  </body>
</html>

Caso de uso común: un checkbox tri-estado "seleccionar todo"

La aplicación más práctica de :indeterminate es un checkbox maestro que resume una lista de opciones: marcado cuando todos los hijos están seleccionados, desmarcado cuando ninguno lo está, e indeterminado cuando algunos lo están. Este patrón es común en gestores de archivos, clientes de correo electrónico y tablas de datos.

La lógica JavaScript mantiene las propiedades indeterminate y checked del checkbox maestro sincronizadas con los checkboxes hijos. CSS se encarga del resto.

<!DOCTYPE html>
<html>
  <head>
    <title>Tri-state checkbox</title>
    <style>
      /* Highlight master while in partial-selection state */
      #all:indeterminate {
        outline: 2px solid #8ebf42;
      }
    </style>
  </head>
  <body>
    <label><input type="checkbox" id="all" /> Select all</label>
    <ul>
      <li><label><input type="checkbox" class="child" /> Apples</label></li>
      <li><label><input type="checkbox" class="child" /> Bananas</label></li>
      <li><label><input type="checkbox" class="child" /> Cherries</label></li>
    </ul>
    <script>
      var all = document.getElementById("all");
      var children = document.querySelectorAll(".child");

      function syncParent() {
        var checked = [...children].filter(function (c) { return c.checked; }).length;
        all.checked = checked === children.length;
        all.indeterminate = checked > 0 && checked < children.length;
      }

      all.addEventListener("change", function () {
        children.forEach(function (c) { c.checked = all.checked; });
      });
      children.forEach(function (c) {
        c.addEventListener("change", syncParent);
      });
      syncParent();
    </script>
  </body>
</html>

Marca uno de los checkboxes hijos: el checkbox "Select all" se vuelve indeterminado y aparece el contorno verde. Marca los tres: el contorno desaparece y pasa al estado completamente marcado.

Ejemplo: un grupo de radio indeterminado

Un grupo de radio está en estado indeterminado mientras ninguna de sus opciones está seleccionada. La pseudo-clase :indeterminate coincide con cada <input type="radio"> del grupo hasta que el usuario elige una respuesta. Una vez que se elige cualquier opción, todo el grupo sale del estado indeterminado y el estilo se elimina.

Esto es útil para indicar a los usuarios que deben hacer una elección — por ejemplo, puedes usarlo en la validación de formularios junto con :invalid y :valid para guiar visualmente a los usuarios hacia las preguntas obligatorias sin responder.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      label {
        margin-right: .5em;
        position: relative;
        top: 1px;
      }
      input[type="radio"]:indeterminate + label {
        color: #8ebf42;
      }
    </style>
  </head>
  <body>
    <h2>:indeterminate selector example</h2>
    <form>
      <input type="radio" name="option" value="yes" id="yes" />
      <label for="yes">Yes</label>
      <input type="radio" name="option" value="no" id="no" />
      <label for="no">No</label>
      <input type="radio" name="option" value="dont-know" id="dont-know" />
      <label for="dont-know">Don’t know</label>
    </form>
  </body>
</html>

Ejemplo: una barra de progreso indeterminada

Un elemento <progress> sin atributo value no tiene porcentaje de finalización conocido, por lo que coincide con :indeterminate. Los navegadores renderizan una barra animada de "trabajando" por defecto. Añadir un atributo value (y opcionalmente max) mueve el elemento al estado determinado y la regla CSS deja de aplicarse.

<!DOCTYPE html>
<html>
  <head>
    <title>Indeterminate progress</title>
    <style>
      progress:indeterminate {
        opacity: 0.6;
        width: 200px;
      }
      /* Once a value is set, show a green accent */
      progress:not(:indeterminate) {
        accent-color: #2a9d8f;
        width: 200px;
      }
    </style>
  </head>
  <body>
    <p>Indeterminate (no value): <progress></progress></p>
    <p>Determinate (value set): <progress value="60" max="100"></progress></p>
  </body>
</html>
Información

La propiedad accent-color controla el color de relleno de <progress> en los navegadores que la admiten (Chrome 93+, Firefox 92+, Safari 15.4+). Para compatibilidad con navegadores más antiguos puede que necesites pseudo-elementos con prefijo de proveedor como ::-webkit-progress-bar y ::-moz-progress-bar, pero estos no forman parte de la especificación CSS estándar.

Combinación con otras pseudo-clases

:indeterminate se puede encadenar con otras pseudo-clases de estado para crear selectores precisos:

/* Indeterminate checkbox that is also focused */
input[type="checkbox"]:indeterminate:focus {
  outline: 3px solid royalblue;
}

/* Indeterminate and disabled checkbox — show a muted style */
input[type="checkbox"]:indeterminate:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

Consulta :focus, :disabled y :enabled para más detalles sobre esas pseudo-clases.

Accesibilidad

El indicador indeterminado es puramente visual en el nivel CSS; no cambia el valor enviado con el formulario. Un checkbox tri-estado se sigue enviando como marcado o desmarcado, dependiendo del estado actual de checked.

Para la tecnología de asistencia, debes exponer el tercer estado explícitamente usando el atributo aria-checked="mixed" en el control maestro. Sin él, los lectores de pantalla anuncian el control simplemente como marcado o desmarcado y los usuarios que dependen de AT no sabrán el significado de la selección parcial.

<!-- Accessible tri-state master checkbox -->
<input
  type="checkbox"
  id="all"
  aria-checked="mixed"
  aria-label="Select all items"
/>

Mantén aria-checked sincronizado con la propiedad indeterminate en tu JavaScript:

function syncParent() {
  var checked = [...children].filter(function (c) { return c.checked; }).length;
  if (checked === 0) {
    all.indeterminate = false;
    all.checked = false;
    all.setAttribute("aria-checked", "false");
  } else if (checked === children.length) {
    all.indeterminate = false;
    all.checked = true;
    all.setAttribute("aria-checked", "true");
  } else {
    all.indeterminate = true;
    all.checked = false;
    all.setAttribute("aria-checked", "mixed");
  }
}

Para grupos de radio :required donde no se ha elegido ninguna opción, considera también usar aria-required="true" en cada input para que la tecnología de asistencia pueda identificar el grupo sin responder.

Compatibilidad con navegadores

La pseudo-clase :indeterminate es compatible con todos los navegadores modernos (Chrome, Edge, Firefox, Safari). Los tres tipos de elementos — checkboxes, grupos de radio y barras de progreso — coinciden en las versiones actuales de los navegadores.

ElementoNotas
input[type="checkbox"]:indeterminateCompatible con todos los navegadores modernos. Requiere JS para establecer la propiedad indeterminate.
input[type="radio"]:indeterminateCompatible con todos los navegadores modernos. Se aplica automáticamente hasta que el usuario selecciona una opción.
progress:indeterminateCompatible con todos los navegadores modernos. Se aplica automáticamente cuando el atributo value está ausente.

Especificaciones

Práctica

Práctica
¿Cuál de las siguientes afirmaciones sobre el atributo indeterminate en CSS es correcta?
¿Cuál de las siguientes afirmaciones sobre el atributo indeterminate en CSS es correcta?
Was this page helpful?