Desplegable de selección

Los desplegables muestran una lista de opciones permitiendo que una persona usuaria pueda seleccionar una o varias en simultáneo. Una opción seleccionada puede usarse como una acción para filtrar u ordenar el contenido existente.


Uso

Cuándo usar

  • Utilizar los desplegables para navegación o filtros, en donde se inicia una acción basada en la selección.
  • Las opciones no son lo suficientemente importantes como para mostrarlas siempre visibles.
  • La cantidad de opciones es extensa y requiere un elemento compacto.

Cuándo no usar

  • No utilizar un desplegable si solo hay dos opciones para elegir. En ese caso, utilizar el componente Botón de radio
  • No utilizar un desplegable si la mayor parte de su experiencia se basa en formularios. En ese caso, considere usar un Campo de Selección (select)
  • No usar los desplegables para mostrar información demasiado compleja. Mantenga las opciones lo más sencillas posible.

Tipos

De selección única

Las opciones de selección única permiten a las personas usuarias elegir una opción a la vez. De manera predeterminada, el desplegable muestra el nombre de la lista que agrupa las opciones. Cuando la persona usuaria selecciona una opción de la lista, el desplegable se cierra y el texto de la opción seleccionada reemplaza el nombre de la lista.

Tipos Dropdown

De selección múltiple

Permiten seleccionar varias opciones para filtrar rápidamente el contenido que desean ver. Cada opción posee una casilla de verificación del lado izquierdo del texto. El desplegable permanece abierto mientras la persona usuaria selecciona las opciones. El componente se cierra si la persona hace clic en el encabezado del mismo o fuera del desplegable, indicando entre paréntesis la cantidad de ítems que fueron seleccionados.

Tipos Dropdown

Estilos

Despegable sin borde

Se utilizan para componer grupos donde se establezcan múltiples desplegables dentro de un mismo contenedor. Al no tener bordes visibles, se integran de manera más fluida en el diseño general.

Tipos Dropdown

Despegable con borde

Se utilizan para entrar en secciones con jerarquías más importantes y suelen usarse junto con otros desplegables del mismo estilo para agrupar información de la misma temática. Este componente presenta un borde visible a su alrededor otorgándole un aspecto más distintivo y resaltado dentro del diseño.

Tipos Dropdown

Despegable con incono

El ícono utilizado puede ser una referencia visual para complementar el título del desplegable y así darle más información sobre el contexto a la persona usuaria.

Tipos Dropdown

Contexto de uso

Contenidos de los desplegables

Se aconseja mantener los textos de los desplegables y de las opciones cortos y concisos. Los textos no deben ocupar más de una línea. El ancho máximo determinado para los desplegables es de 4 (cuatro) columnas.

Tipos Dropdown

El tamaño del desplegable se adaptará a la cantidad de caracteres que contenga el mismo. En caso de no poder resumir la información, superando esta el ancho máximo de 4 columnas, se truncará el texto cortando la última palabra y agregando tres (3) puntos que denoten la continuidad de dicha información.

Desplegables combinables

Los desplegables se agrupan en una disposición horizontal y pueden combinarse con Botones y Navegación en esa misma dirección. Utilizar un tamaño uniforme al combinar los desplegables con otros componentes, le brinda más flexibilidad y estructura al diseño. Por ejemplo, si utiliza un desplegable mediano, también deberá utilizar botones del mismo tamaño.

Tipos Dropdown

Con selección múltiple

Grande


  <div class="dropdown">
    <button
      type="button"
      class="btn btn-dropdown btn-dropdown-border btn-lg"
      data-bs-toggle="dropdown"
      aria-expanded="false"
      data-bs-auto-close="outside"
    >
      <span class="material-symbols-rounded o-icon" aria-label="hidden">add</span>
      <span class="btn-dropdown-text ellipsis-1">Desplegable</span>
      <span class="material-symbols-rounded btn-dropdown-icon" aria-label="hidden">expand_more</span>
    </button>
    <div class="dropdown-menu">
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxLg"
          id="option-checkbox-lg-1"
          value="option-1"
          />
        <label class="form-checkbox-label" for="option-checkbox-lg-1">
          Opción de selección múltiple 1
        </label>
      </div>
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxLg"
          id="option-checkbox-lg-2"
          value="option-2"
          />
        <label class="form-checkbox-label" for="option-checkbox-lg-2">
          Opción de selección múltiple 2
        </label>
      </div>
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxLg"
          id="option-checkbox-lg-3"
          value="option-3"
          disabled
          />
        <label class="form-checkbox-label" for="option-checkbox-lg-3">
          Opción de selección múltiple 3
        </label>
      </div>
    </div>
  </div>

Mediano


  <div class="dropdown">
    <button
      type="button"
      class="btn btn-dropdown btn-dropdown-border"
      data-bs-toggle="dropdown"
      aria-expanded="false"
      data-bs-auto-close="outside"
    >
      <span class="material-symbols-rounded o-icon" aria-label="hidden">add</span>
      <span class="btn-dropdown-text ellipsis-1">Desplegable</span>
      <span class="material-symbols-rounded btn-dropdown-icon" aria-label="hidden">expand_more</span>
    </button>
    <div class="dropdown-menu">
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxMd"
          id="option-checkbox-1"
          value="option-1"
          />
        <label class="form-checkbox-label" for="option-checkbox-1">
          Opción de selección múltiple 1
        </label>
      </div>
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxMd"
          id="option-checkbox-2"
          value="option-2"
          />
        <label class="form-checkbox-label" for="option-checkbox-2">
          Opción de selección múltiple 2
        </label>
      </div>
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxMd"
          id="option-checkbox-3"
          value="option-3"
          disabled
          />
        <label class="form-checkbox-label" for="option-checkbox-3">
          Opción de selección múltiple 3
        </label>
      </div>
    </div>
  </div>

Chico


  <div class="dropdown">
    <button
      type="button"
      class="btn btn-dropdown btn-dropdown-border btn-sm"
      data-bs-toggle="dropdown"
      aria-expanded="false"
      data-bs-auto-close="outside"
    >
      <span class="material-symbols-rounded o-icon" aria-label="hidden">add</span>
      <span class="btn-dropdown-text ellipsis-1">Desplegable</span>
      <span class="material-symbols-rounded btn-dropdown-icon" aria-label="hidden">expand_more</span>
    </button>
    <div class="dropdown-menu">
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxSm"
          id="option-checkbox-sm-1"
          value="option-1"
          />
        <label class="form-checkbox-label" for="option-checkbox-sm-1">
          Opción de selección múltiple 1
        </label>
      </div>
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxSm"
          id="option-checkbox-sm-2"
          value="option-2"
          />
        <label class="form-checkbox-label" for="option-checkbox-sm-2">
          Opción de selección múltiple 2
        </label>
      </div>
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxSm"
          id="option-checkbox-sm-3"
          value="option-3"
          disabled
          />
        <label class="form-checkbox-label" for="option-checkbox-sm-3">
          Opción de selección múltiple 3
        </label>
      </div>
    </div>
  </div> 

Con selección única

Grande


  <div class="dropdown">
    <button
      type="button"
      class="btn btn-dropdown btn-dropdown-border btn-lg"
      data-bs-toggle="dropdown"
      aria-expanded="false"
      data-bs-auto-close="outside"
    >
      <span class="material-symbols-rounded o-icon" aria-label="hidden">add</span>
      <span class="btn-dropdown-text ellipsis-1">Desplegable</span>
      <span class="material-symbols-rounded btn-dropdown-icon" aria-label="hidden">expand_more</span>
    </button>
    <div class="dropdown-menu">
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioLg"
          id="option-radio-lg-1"
          value="option-1"
          />
        <label class="form-radio-label" for="option-radio-lg-1">
          Opción de selección única 1
        </label>
      </div>
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioLg"
          id="option-radio-lg-2"
          value="option-2"
          />
        <label class="form-radio-label" for="option-radio-lg-2">
          Opción de selección única 2
        </label>
      </div>
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioLg"
          id="option-radio-lg-3"
          value="option-3"
          disabled
          />
        <label class="form-radio-label" for="option-radio-lg-3">
          Opción de selección única 3
        </label>
      </div>
    </div>
  </div>

Mediano


  <div class="dropdown">
    <button
      type="button"
      class="btn btn-dropdown btn-dropdown-border"
      data-bs-toggle="dropdown"
      aria-expanded="false"
      data-bs-auto-close="outside"
    >
      <span class="material-symbols-rounded o-icon" aria-label="hidden">add</span>
      <span class="btn-dropdown-text ellipsis-1">Desplegable</span>
      <span class="material-symbols-rounded btn-dropdown-icon" aria-label="hidden">expand_more</span>
    </button>
    <div class="dropdown-menu">
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioMd"
          id="option-radio-md-1"
          value="option-1"
          />
        <label class="form-radio-label" for="option-radio-md-1">
          Opción de selección única 1
        </label>
      </div>
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioMd"
          id="option-radio-md-2"
          value="option-2"
          />
        <label class="form-radio-label" for="option-radio-md-2">
          Opción de selección única 2
        </label>
      </div>
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioMd"
          id="option-radio-md-3"
          value="option-3"
          disabled
          />
        <label class="form-radio-label" for="option-radio-md-3">
          Opción de selección única 3
        </label>
      </div>
    </div>
  </div>

Chico


  <div class="dropdown">
    <button
      type="button"
      class="btn btn-dropdown btn-dropdown-border btn-sm"
      data-bs-toggle="dropdown"
      aria-expanded="false"
      data-bs-auto-close="outside"
    >
      <span class="material-symbols-rounded o-icon" aria-label="hidden">add</span>
      <span class="btn-dropdown-text ellipsis-1">Desplegable</span>
      <span class="material-symbols-rounded btn-dropdown-icon" aria-label="hidden">expand_more</span>
    </button>
    <div class="dropdown-menu">
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioSm"
          id="option-radio-sm-1"
          value="option-1"
          />
        <label class="form-radio-label" for="option-radio-sm-1">
          Opción de selección única 1
        </label>
      </div>
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioSm"
          id="option-radio-sm-2"
          value="option-2"
          />
        <label class="form-radio-label" for="option-radio-sm-2">
          Opción de selección única 2
        </label>
      </div>
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioSm"
          id="option-radio-sm-3"
          value="option-3"
          disabled
          />
        <label class="form-radio-label" for="option-radio-3">
          Opción de selección única 3
        </label>
      </div>
    </div>
  </div>

Implementación

A continuación, se presenta un ejemplo de código JavaScript para su implementación, teniendo en cuenta los estilos y funcionalidad al seleccionar una opción.

Es importante tener en cuenta que la funcionalidad deberá integrarse de acuerdo con la tecnología utilizada, como por ejemplo React o Angular.

Desplegable con casillas de opción múltiple


  <div class="dropdown">
    <button
      type="button"
      class="btn btn-dropdown btn-dropdown-border"
      data-bs-toggle="dropdown"
      aria-expanded="false"
      data-bs-auto-close="outside"
      id="btnDropdownCheckboxJs"
    >
      <span class="material-symbols-rounded o-icon" aria-label="hidden">add</span>
      <span class="btn-dropdown-text ellipsis-1">Desplegable
        <span id="counterDropdownCheckboxJs"></span>
      </span>
      
      <span class="material-symbols-rounded btn-dropdown-icon" aria-label="hidden">expand_more</span>
    </button>
    <div class="dropdown-menu">
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxJs"
          id="option-1-js"
          value="option-1-js"
          />
        <label class="form-checkbox-label" for="option-1-js">
          Opción de selección múltiple 1
        </label>
      </div>
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxJs"
          id="option-2-js"
          value="option-2-js"
          />
        <label class="form-checkbox-label" for="option-2-js">
          Opción de selección múltiple 2
        </label>
      </div>
      <div class="form-checkbox">
        <input
          class="form-checkbox-input"
          type="checkbox"
          name="dropdownCheckboxJs"
          id="option-3-js"
          value="option-3-js"
          disabled
          />
        <label class="form-checkbox-label" for="option-3-js">
          Opción de selección múltiple 3
        </label>
      </div>
    </div>
  </div>

  const checkboxes = document.querySelectorAll('input[type="checkbox"][name="dropdownCheckboxJs"]');
  const counter = document.getElementById('counterDropdownCheckboxJs');
  const btnDropdown = document.getElementById('btnDropdownCheckboxJs');
  if (checkboxes) {
    checkboxes.forEach((checkbox) => {
      checkbox.addEventListener('change', function() {
        const selectedCount = Array.from(checkboxes).filter(cb => cb.checked).length;
        if (counter) {
          if (selectedCount == 0) {
            counter.textContent = '';
            btnDropdown?.classList.remove('selected');
          } else {
            counter.textContent = ` (${selectedCount}) `;
            btnDropdown?.classList.add('selected');
          }
        }
      });
    });
  }


Desplegable con casillas de opción única


  <div class="dropdown">
    <button
      type="button"
      class="btn btn-dropdown btn-dropdown-border"
      data-bs-toggle="dropdown"
      aria-expanded="false"
      data-bs-auto-close="outside"
      id="btnDropdownRadioJs"
    >
      <span class="material-symbols-rounded o-icon" aria-label="hidden">add</span>
      <span class="btn-dropdown-text ellipsis-1" id="btnDropdownRadioTextJs">Desplegable</span>
      <span class="material-symbols-rounded btn-dropdown-icon" aria-label="hidden">expand_more</span>
    </button>
    <div class="dropdown-menu">
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioJs"
          id="option-radio-1-js"
          value="option-1"
          />
        <label class="form-radio-label" for="option-radio-1-js">
          Opción de selección única 1
        </label>
      </div>
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioJs"
          id="option-radio-2-js"
          value="option-2"
          />
        <label class="form-radio-label" for="option-radio-2-js">
          Opción de selección única 2
        </label>
      </div>
      <div class="form-radio reverse">
        <input
          class="form-radio-input"
          type="radio"
          name="dropdownRadioJs"
          id="option-radio-3-js"
          value="option-3"
          disabled
          />
        <label class="form-radio-label" for="option-radio-3-js">
          Opción de selección única 3
        </label>
      </div>
    </div>
  </div>

  const radios = document.querySelectorAll('input[type="radio"][name="dropdownRadioJs"]');
  if (radios) {
    radios.forEach((radio) => {
      radio.addEventListener('change', function() {
        const selectedText = this.nextElementSibling.textContent.trim();
        const buttonText = document.getElementById('btnDropdownRadioTextJs');
        const button = document.getElementById('btnDropdownRadioJs');
        if (buttonText && button) {
          buttonText.textContent = selectedText;
          button.classList.add('selected');
        }
      });
    });
  }






Anatomía

Anatomía del desplegable de selección
ElementoCarácter
1. Campo de selecciónObligatorio, es el área donde aparecerá la opción seleccionada.
2. Icono izquierdo (Opcional)Opcional, se utiliza para facilitar la identificación del desplegable.
3. Texto del desplegableObligatorio, nombre de la lista que agrupa las opciones. Una vez seleccionada la opción se reemplaza por el texto de la opción.
4. Icono derecho (expandir)Obligatorio. Se utiliza para indicar que el campo puede expandirse para mostrar las opciones.
5. Borde (Opcional)Opcional. Borde visible a su alrededor otorgándole un aspecto más distintivo y resaltado dentro del diseño.

Estados

Predeterminado (default)

Estado predeterminado del campo de selección en una interfaz.

Estado predeterminado del desplegable de selección

Sobre (Hover)

Cuando un usuario está sobre el elemento.

Hover

En Foco (focus)

Es un principio de accesibilidad que asegura que cualquier elemento interactivo en una interfaz sea claramente visible cuando recibe la atención del usuario, especialmente al ser navegado con el teclado. En Obelisco se utiliza un borde o anillo (focus ring) por fuera del componente en un color distintivo.

Focus

Expandido

Cuando un usuario está seleccionando una opción.

Expandido

Seleccionado

Indica que la persona usuaria seleccionó una opción de la lista expandible.

Seleccionado

Tamaños

Los desplegables pueden ser grandes, medianos o chicos. El tamaño mediano es la opción predeterminada y más utilizada.

Tamaños del desplegable de selección

Cuando el desplegable se encuentra expandido, cada opción debe tener la misma altura que el encabezado del componente.

Tamaños del desplegable de selección expandido

Navegación alternativa

El componente de desplegable de selección está construido para ser accesible mediante navegación por teclado y reconocible por lectores de pantalla, comunicando su estado de forma clara.

TABENTERSPACESCAPE

Utilizando el tab la persona usuaria puede llegar hasta el campo de selección. Con la barra espaciadora (space), las flechas para arriba o abajo puede abrir el desplegable donde estarán las opciones a seleccionar. Las flechas, además, se usan para navegar a través de las opciones, las cuales pueden ser seleccionadas con labarra espaciadora o enter.

Navegación alternativa del desplegable de selección

En el desplegable de selección única cuando seleccionamos la opción con barra espaciadora o enter se cierra el desplegable en ese mismo acto.

En el desplegable de selección múltiple cuando seleccionamos la opción con barra espaciadora o enter el desplegable sigue abierto para poder seguir seleccionando más opciones, para cerrar el desplegable podemos usar scape.

Etiquetado descriptivo

Para el desplegable de selección recomendamos utilizar aria-haspopup=”true”, indica que elemento button abre un menú.

Recomendamos utilizar aria expanded con valor “false” cuando no se muestrea el menú y con el valor “true” cuando mostramos el menú.

<button 
  type="button" 
  class="btn btn-dropdown btn-lg" 
  data-bs-toogle="dropdown"  aria-haspopup="true" 
  aria-expanded="false" 
  data-bs-auto-close="outside"
>

Cuando un desplegable permite seleccionar múltiples opciones, el contador visual suele mostrarse como: Etiqueta (2).

Para cumplir con buenas prácticas de accesibilidad (WCAG + WAI-ARIA), recomendamos proporcionar una etiqueta accesible alternativa que comunique claramente el estado del componente.

El botón que abre el desplegable debe exponer un aria-label dinámico.

Ejemplo del desplegable: Visual:
Actividad (2)
Lector de pantalla: “Actividad, 2 seleccionadas”

Criterios WCAG aplicados

Success Criterion 1.1.1 Non-text Content (Level A)

Si el campo tiene un ícono decorativo, por ejemplo, un ícono de búsqueda, debe tener una alternativa textual o estar marcado como decorativo (aria-hidden="true" o role="presentation").

Success Criterion 1.4.11 Non-Text Contrast (Level AA)

La presentación visual de elementos de la interfaz de usuario y objetos gráficos tiene por lo menos una relación de contraste de 3:1 con respecto a los colores adyacentes.

Success Criterion 1.4.3 Contrast (Minimum) (Level AA)

La presentación visual de texto y de imágenes de texto tiene una relación de contraste de por lo menos 4.5:1, excepto textos grandes e imágenes de texto grande que tienen un contraste de por lo menos 3:1, textos o imágenes que son parte de un componente inactivo de interfaz de usuario o son pura decoración, o logotipos.

Success Criterion 1.4.4 Resize Text (Level AA)

Excepto por los subtítulos e imágenes de texto, el texto puede redimensionarse hasta un 200 % sin tecnología de asistencia, sin pérdida de contenido ni funcionalidad.

Success Criterion 2.1.1 Keyboard (Level A)

Todas las funcionalidades del contenido se puede operar a través de una interfaz de teclado.

Success Criterion 2.1.2 No Keyboard Trap (Level A)

Si el foco del teclado puede moverse a un componente de la página utilizando una interfaz de teclado, también debe ser posible mover el foco fuera de ese componente usando únicamente la misma interfaz de teclado. Si se requiere algo más que las teclas de flecha, tabulador u otros métodos estándar para salir, se debe informar al usuario sobre el método necesario para mover el foco.

Success Criterion 2.4.7 Focus Visible (Level AA)

Cualquier interfaz de usuario operable por teclado tiene un modo de operación donde el indicador de enfoque del teclado es visible.

Success Criterion 4.1.2 Name, Role, Value (Level A)

Para todos los componentes de la interfaz de usuario (incluidos, entre otros: elementos de formulario, enlaces y componentes generados por scripts), el nombre y la función se pueden determinar mediante programación; los estados, propiedades y valores que puede establecer el usuario se pueden configurar mediante programación; y la notificación de cambios en estos elementos está disponible para los agentes de usuario, incluidas las tecnologías de asistencia.

Navegación de pie de página