CSS
Tutorial CSS: Accesibilidad web con CSS
Aprende a mejorar la accesibilidad web con CSS usando contraste de color, estilos de foco, media queries y patrones de diseño accesibles.
Aprende CSS y certifícateContraste de color y variables para temas accesibles
El contraste de color es uno de los pilares fundamentales de la accesibilidad web. Un contraste adecuado entre texto y fondo permite que personas con diferentes capacidades visuales puedan percibir y comprender el contenido de nuestra página. Combinado con las variables CSS, podemos crear temas accesibles que se adapten a diferentes necesidades.
Fundamentos del contraste de color
El contraste se refiere a la diferencia de luminosidad entre dos colores adyacentes. Para que un texto sea legible, necesita tener suficiente contraste con su fondo. Las Pautas de Accesibilidad para el Contenido Web (WCAG) establecen criterios específicos:
- Nivel AA: Requiere una relación de contraste mínima de 4.5:1 para texto normal y 3:1 para texto grande
- Nivel AAA: Requiere una relación de contraste mínima de 7:1 para texto normal y 4.5:1 para texto grande
Veamos un ejemplo de contraste insuficiente versus adecuado:
/* Contraste insuficiente */
.low-contrast {
color: #767676;
background-color: #EEEEEE;
/* Relación de contraste aproximada: 2.5:1 */
}
/* Contraste adecuado (nivel AA) */
.good-contrast {
color: #595959;
background-color: #FFFFFF;
/* Relación de contraste aproximada: 4.5:1 */
}
/* Contraste excelente (nivel AAA) */
.excellent-contrast {
color: #333333;
background-color: #FFFFFF;
/* Relación de contraste aproximada: 8:1 */
}
Variables CSS para temas accesibles
Las variables CSS (también llamadas propiedades personalizadas) son una herramienta poderosa para crear temas accesibles. Nos permiten definir valores que podemos reutilizar y modificar fácilmente en toda nuestra hoja de estilos.
La sintaxis básica para definir y usar variables CSS es:
:root {
--variable-name: value;
}
.selector {
property: var(--variable-name);
}
Podemos aprovechar estas variables para crear un sistema de colores accesible:
:root {
/* Colores base */
--color-text: #333333;
--color-background: #FFFFFF;
--color-primary: #0056b3;
--color-secondary: #6c757d;
--color-accent: #e91e63;
/* Elementos interactivos */
--color-link: #0056b3;
--color-link-hover: #003d7a;
--color-button-bg: #0056b3;
--color-button-text: #FFFFFF;
}
body {
color: var(--color-text);
background-color: var(--color-background);
}
a {
color: var(--color-link);
}
a:hover {
color: var(--color-link-hover);
}
.button {
background-color: var(--color-button-bg);
color: var(--color-button-text);
}
Creando temas alternativos con variables CSS
Una de las grandes ventajas de usar variables CSS es la capacidad de crear temas alternativos que podemos aplicar fácilmente. Esto es especialmente útil para ofrecer un modo oscuro o un modo de alto contraste para usuarios con necesidades visuales específicas.
/* Tema claro (predeterminado) */
:root {
--color-text: #333333;
--color-background: #FFFFFF;
--color-surface: #F5F5F5;
--color-border: #DDDDDD;
--color-primary: #0056b3;
}
/* Tema oscuro */
.dark-theme {
--color-text: #EEEEEE;
--color-background: #121212;
--color-surface: #1E1E1E;
--color-border: #333333;
--color-primary: #4D9FFF;
}
/* Tema de alto contraste */
.high-contrast-theme {
--color-text: #FFFFFF;
--color-background: #000000;
--color-surface: #000000;
--color-border: #FFFFFF;
--color-primary: #FFFF00;
}
Con esta estructura, podemos cambiar todo el tema de nuestra aplicación simplemente añadiendo una clase al elemento <html>
o <body>
:
/* Aplicamos los estilos usando las variables */
body {
color: var(--color-text);
background-color: var(--color-background);
}
.card {
background-color: var(--color-surface);
border: 1px solid var(--color-border);
}
.button-primary {
background-color: var(--color-primary);
color: var(--color-text);
}
Implementando un selector de temas
Podemos implementar un selector de temas que permita a los usuarios elegir el que mejor se adapte a sus necesidades:
/* Definimos los temas como antes */
:root {
/* Variables del tema claro */
--color-text: #333333;
--color-background: #FFFFFF;
/* Más variables... */
}
.dark-theme {
/* Variables del tema oscuro */
--color-text: #EEEEEE;
--color-background: #121212;
/* Más variables... */
}
.high-contrast-theme {
/* Variables del tema de alto contraste */
--color-text: #FFFFFF;
--color-background: #000000;
/* Más variables... */
}
/* Transición suave entre temas */
body {
color: var(--color-text);
background-color: var(--color-background);
transition: background-color 0.3s ease, color 0.3s ease;
}
Verificación del contraste
Es importante verificar que nuestros colores cumplen con los requisitos de contraste. Aunque existen herramientas online para esto, también podemos crear una guía visual en nuestro CSS:
/* Guía de contraste */
.contrast-guide {
/* Nivel AA (4.5:1) para texto normal */
--aa-normal-light-on-dark: #959595 on #000000;
--aa-normal-dark-on-light: #707070 on #FFFFFF;
/* Nivel AAA (7:1) para texto normal */
--aaa-normal-light-on-dark: #B7B7B7 on #000000;
--aaa-normal-dark-on-light: #595959 on #FFFFFF;
}
Variables para espaciado y tamaños accesibles
La accesibilidad no se limita solo al contraste de color. También podemos usar variables CSS para definir tamaños de texto y espaciados que favorezcan la legibilidad:
:root {
/* Tamaños de texto accesibles */
--font-size-base: 16px;
--font-size-large: 1.25rem;
--font-size-xlarge: 1.5rem;
--font-size-small: 0.875rem;
/* Espaciado para mejorar legibilidad */
--line-height: 1.5;
--paragraph-spacing: 1.5rem;
--letter-spacing: 0.01em;
}
body {
font-size: var(--font-size-base);
line-height: var(--line-height);
letter-spacing: var(--letter-spacing);
}
h1 {
font-size: var(--font-size-xlarge);
margin-bottom: var(--paragraph-spacing);
}
p {
margin-bottom: var(--paragraph-spacing);
}
Ejemplo práctico: Sistema de colores accesible completo
Veamos un ejemplo más completo de un sistema de colores accesible usando variables CSS:
:root {
/* Colores base */
--color-black: #000000;
--color-white: #FFFFFF;
/* Paleta de grises */
--color-gray-100: #F8F9FA;
--color-gray-200: #E9ECEF;
--color-gray-300: #DEE2E6;
--color-gray-400: #CED4DA;
--color-gray-500: #ADB5BD;
--color-gray-600: #6C757D;
--color-gray-700: #495057;
--color-gray-800: #343A40;
--color-gray-900: #212529;
/* Colores semánticos (tema claro) */
--color-text: var(--color-gray-900);
--color-text-muted: var(--color-gray-600);
--color-background: var(--color-white);
--color-surface: var(--color-gray-100);
--color-border: var(--color-gray-300);
/* Colores de acento */
--color-primary: #0056b3;
--color-primary-light: #4D9FFF;
--color-primary-dark: #003d7a;
/* Colores de estado */
--color-success: #28a745;
--color-warning: #ffc107;
--color-danger: #dc3545;
--color-info: #17a2b8;
/* Espaciado y tamaños */
--font-size-base: 16px;
--spacing-unit: 0.5rem;
}
/* Tema oscuro */
.dark-theme {
--color-text: var(--color-gray-100);
--color-text-muted: var(--color-gray-400);
--color-background: var(--color-gray-900);
--color-surface: var(--color-gray-800);
--color-border: var(--color-gray-700);
/* Ajustamos colores de acento para mantener contraste */
--color-primary: var(--color-primary-light);
/* Ajustamos colores de estado */
--color-success: #5dd879;
--color-warning: #ffda6a;
--color-danger: #f77;
--color-info: #6edff6;
}
/* Aplicamos los estilos */
body {
color: var(--color-text);
background-color: var(--color-background);
font-size: var(--font-size-base);
}
.card {
background-color: var(--color-surface);
border: 1px solid var(--color-border);
padding: calc(var(--spacing-unit) * 2);
margin-bottom: calc(var(--spacing-unit) * 3);
}
.text-muted {
color: var(--color-text-muted);
}
.btn-primary {
background-color: var(--color-primary);
color: var(--color-white);
padding: var(--spacing-unit) calc(var(--spacing-unit) * 2);
}
Consideraciones finales
Al trabajar con contraste de color y variables para temas accesibles, es importante:
- Probar con usuarios reales o herramientas de simulación de discapacidad visual
- Mantener la consistencia en toda la interfaz
- No confiar solo en el color para transmitir información importante
- Documentar el sistema de variables para que otros desarrolladores puedan entenderlo y usarlo correctamente
- Revisar periódicamente que los contrastes siguen cumpliendo con los estándares WCAG
Con estas técnicas, podemos crear interfaces que no solo sean visualmente atractivas, sino también inclusivas y accesibles para todos los usuarios.
Estilos para estados de foco y navegación por teclado
La navegación por teclado es fundamental para muchos usuarios que no pueden utilizar un ratón, incluyendo personas con discapacidades motoras, usuarios de lectores de pantalla y aquellos que prefieren el teclado por eficiencia. Diseñar estilos adecuados para los estados de foco es una parte esencial de la accesibilidad web.
Importancia del indicador de foco
El indicador de foco es una señal visual que muestra qué elemento de la página está actualmente seleccionado cuando navegamos con el teclado (usando la tecla Tab). Por defecto, los navegadores muestran un contorno (outline) alrededor del elemento enfocado, pero este estilo básico:
- A menudo es eliminado por desarrolladores por razones estéticas
- Puede tener un contraste insuficiente en algunos contextos
- No siempre es consistente entre navegadores
Veamos cómo mejorar estos indicadores de foco:
/* Nunca elimines el outline sin proporcionar una alternativa */
:focus {
outline: 2px solid #4d90fe;
outline-offset: 2px;
}
La propiedad outline-offset crea un espacio entre el elemento y su contorno, mejorando la visibilidad.
Diferenciando el foco del ratón y del teclado
En CSS moderno, podemos usar la pseudo-clase :focus-visible
para aplicar estilos de foco solo cuando el usuario navega con teclado, manteniendo una experiencia limpia para usuarios de ratón:
/* Estilo básico para todos los elementos enfocados */
:focus {
outline: none;
}
/* Estilo mejorado solo para navegación con teclado */
:focus-visible {
outline: 3px solid #1a73e8;
outline-offset: 2px;
box-shadow: 0 0 0 6px rgba(26, 115, 232, 0.2);
}
/* Soporte para navegadores más antiguos */
@supports not selector(:focus-visible) {
:focus {
outline: 3px solid #1a73e8;
outline-offset: 2px;
}
}
Estilos de foco para diferentes componentes
Diferentes elementos de interfaz pueden beneficiarse de estilos de foco personalizados:
Enlaces y botones
a:focus-visible,
button:focus-visible {
outline: 3px solid #1a73e8;
outline-offset: 2px;
border-radius: 4px;
text-decoration: underline;
}
/* Botones con fondo oscuro necesitan un outline más claro */
.dark-button:focus-visible {
outline-color: #78aeff;
}
Campos de formulario
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
outline: 2px solid #1a73e8;
border-color: #1a73e8;
box-shadow: 0 0 0 4px rgba(26, 115, 232, 0.25);
}
/* Checkbox y radio buttons */
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
}
Tarjetas y contenedores
.card:focus-visible,
.interactive-container:focus-visible {
outline: 2px dashed #1a73e8;
outline-offset: 4px;
}
Mejorando la visibilidad con transiciones
Las transiciones pueden hacer que el indicador de foco sea más notorio, especialmente útil para usuarios con discapacidades cognitivas o atención limitada:
.button {
position: relative;
transition: transform 0.2s ease;
}
.button:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
transform: scale(1.05);
}
/* Efecto de pulso para mayor visibilidad */
.button:focus-visible::after {
content: '';
position: absolute;
top: -4px;
left: -4px;
right: -4px;
bottom: -4px;
border-radius: inherit;
animation: pulse 1.5s infinite;
z-index: -1;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(26, 115, 232, 0.4);
}
70% {
box-shadow: 0 0 0 8px rgba(26, 115, 232, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(26, 115, 232, 0);
}
}
Orden de tabulación lógico
El orden de tabulación es crucial para una navegación por teclado intuitiva. Por defecto, los elementos reciben el foco en el orden en que aparecen en el HTML. Sin embargo, a veces necesitamos modificar este comportamiento:
/* Elementos que no deben recibir foco */
.decorative-element {
tabindex: -1;
}
/* Elementos interactivos que no son nativamente enfocables */
.custom-dropdown {
tabindex: 0;
}
Es importante recordar que:
tabindex="0"
incluye un elemento en el orden natural de tabulacióntabindex="-1"
excluye un elemento del orden de tabulación pero permite enfocarlo con JavaScripttabindex="1+"
(valores positivos) fuerza un orden específico, pero debe evitarse ya que puede confundir a los usuarios
Skip links para navegación eficiente
Los enlaces de salto (skip links) permiten a los usuarios de teclado saltar directamente al contenido principal, evitando tener que tabular a través de menús de navegación extensos:
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #1a73e8;
color: white;
padding: 8px;
z-index: 100;
transition: top 0.2s ease;
}
.skip-link:focus {
top: 0;
}
Este estilo mantiene el enlace oculto visualmente hasta que recibe el foco, momento en el que aparece en la parte superior de la página.
Indicadores de foco personalizados
Podemos crear indicadores de foco personalizados que se integren mejor con el diseño de nuestra interfaz:
/* Indicador de foco con subrayado animado */
.nav-link:focus-visible {
outline: none;
}
.nav-link:focus-visible::after {
content: '';
position: absolute;
left: 0;
bottom: -2px;
width: 100%;
height: 2px;
background-color: currentColor;
transform: scaleX(0);
transition: transform 0.3s ease;
transform-origin: left;
animation: expand 0.3s forwards;
}
@keyframes expand {
to {
transform: scaleX(1);
}
}
Manejo de componentes complejos
Para componentes interactivos complejos como menús desplegables, carruseles o diálogos, es importante gestionar correctamente el foco:
/* Contenedor de menú desplegable */
.dropdown {
position: relative;
}
/* Botón que activa el menú */
.dropdown-toggle:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
}
/* Menú desplegable */
.dropdown-menu {
display: none;
}
/* Cuando el menú está abierto */
.dropdown.open .dropdown-menu {
display: block;
}
/* Elementos del menú */
.dropdown-item:focus-visible {
outline: none;
background-color: #e8f0fe;
color: #1a73e8;
}
Estilos para diferentes estados de interacción
Es importante diferenciar visualmente entre los distintos estados de interacción:
.button {
background-color: #1a73e8;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
}
/* Estado hover (ratón) */
.button:hover {
background-color: #1765cc;
}
/* Estado focus (teclado) */
.button:focus-visible {
outline: 3px solid #78aeff;
outline-offset: 2px;
}
/* Estado active (clic/pulsación) */
.button:active {
background-color: #155db9;
transform: translateY(1px);
}
/* Estado disabled */
.button:disabled {
background-color: #ccc;
color: #666;
cursor: not-allowed;
}
Pruebas de navegación por teclado
Para verificar que nuestros estilos de foco funcionan correctamente, debemos realizar pruebas de navegación por teclado:
- Presionar Tab para navegar hacia adelante
- Shift+Tab para navegar hacia atrás
- Enter/Space para activar elementos
- Flechas para interactuar con componentes como menús o sliders
Ejemplo práctico: Menú de navegación accesible
Veamos un ejemplo completo de un menú de navegación accesible con estilos de foco mejorados:
.nav {
display: flex;
list-style: none;
padding: 0;
margin: 0;
}
.nav-item {
position: relative;
}
.nav-link {
display: block;
padding: 12px 16px;
color: #333;
text-decoration: none;
transition: color 0.2s;
}
/* Estilos para hover */
.nav-link:hover {
color: #1a73e8;
}
/* Estilos para foco */
.nav-link:focus {
outline: none;
}
.nav-link:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: -2px;
border-radius: 4px;
color: #1a73e8;
}
/* Indicador visual adicional */
.nav-link:focus-visible::before {
content: '';
position: absolute;
bottom: 6px;
left: 16px;
right: 16px;
height: 2px;
background-color: #1a73e8;
}
/* Estado activo */
.nav-link.active {
font-weight: bold;
color: #1a73e8;
}
/* Elemento actual */
.nav-link[aria-current="page"] {
font-weight: bold;
color: #1a73e8;
}
Consideraciones para dispositivos táctiles
En dispositivos táctiles, el foco visual funciona de manera diferente. Es importante asegurarse de que nuestros estilos sean adecuados para todos los dispositivos:
/* Estilos base para todos los dispositivos */
.button {
padding: 8px 16px;
background: #1a73e8;
color: white;
border: none;
border-radius: 4px;
}
/* Estilos específicos para dispositivos táctiles */
@media (hover: none) and (pointer: coarse) {
.button {
padding: 12px 20px; /* Área táctil más grande */
}
/* Evitamos efectos hover en dispositivos táctiles */
.button:hover {
background: #1a73e8; /* Mismo que el estado normal */
}
}
Compatibilidad con navegadores antiguos
Para navegadores que no soportan :focus-visible
, podemos usar un enfoque progresivo:
/* Estilo base para todos los navegadores */
:focus {
outline: 2px solid #1a73e8;
outline-offset: 2px;
}
/* Mejora para navegadores modernos */
:focus:not(:focus-visible) {
outline: none;
}
:focus-visible {
outline: 3px solid #1a73e8;
outline-offset: 3px;
box-shadow: 0 0 0 6px rgba(26, 115, 232, 0.2);
}
Este enfoque garantiza que todos los usuarios tengan una experiencia accesible, independientemente del navegador que utilicen.
Media queries para preferencias de usuario (reducción de movimiento, contraste)
Las media queries son una herramienta fundamental en CSS que nos permite aplicar estilos específicos según las características del dispositivo o las preferencias del usuario. Más allá de adaptar nuestros diseños a diferentes tamaños de pantalla, podemos utilizarlas para mejorar la accesibilidad respondiendo a las preferencias específicas de los usuarios.
Media queries basadas en preferencias
CSS moderno incluye media queries que detectan las preferencias configuradas por los usuarios en sus sistemas operativos o navegadores. Estas consultas nos permiten crear experiencias más inclusivas y accesibles sin requerir configuración adicional por parte del usuario.
/* Estos estilos se aplicarán según las preferencias del usuario */
@media (prefers-reduced-motion: reduce) {
/* Estilos para usuarios que prefieren menos movimiento */
}
@media (prefers-color-scheme: dark) {
/* Estilos para usuarios que prefieren modo oscuro */
}
@media (prefers-contrast: more) {
/* Estilos para usuarios que prefieren mayor contraste */
}
Reducción de movimiento (prefers-reduced-motion)
La media query prefers-reduced-motion
detecta si el usuario ha configurado su sistema para reducir o eliminar animaciones y movimientos. Esto es especialmente importante para personas con trastornos vestibulares, sensibilidad visual o condiciones como TDAH, para quienes las animaciones pueden causar mareos, náuseas o distracciones.
Esta media query tiene dos valores posibles:
reduce
: El usuario prefiere menos movimientono-preference
: El usuario no ha expresado preferencia
Veamos cómo implementarla:
/* Animación estándar */
.card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
/* Respetamos la preferencia de reducción de movimiento */
@media (prefers-reduced-motion: reduce) {
.card {
transition: none;
}
.card:hover {
transform: none;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
}
Para animaciones más complejas con @keyframes
, también debemos adaptarlas:
/* Animación de carga giratoria */
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loader {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Alternativa sin movimiento para usuarios que lo prefieren */
@media (prefers-reduced-motion: reduce) {
.loader {
animation: none;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-left: 4px solid #3498db;
}
}
Enfoque progresivo para reducción de movimiento
Una buena práctica es adoptar un enfoque progresivo donde comenzamos con animaciones mínimas o nulas y las añadimos solo para usuarios que no tienen preferencia por reducir el movimiento:
/* Por defecto, sin animaciones */
.button {
background-color: #0056b3;
color: white;
border: none;
padding: 10px 20px;
/* Sin transiciones por defecto */
}
/* Añadimos animaciones solo si el usuario no prefiere reducirlas */
@media (prefers-reduced-motion: no-preference) {
.button {
transition: background-color 0.2s, transform 0.1s;
}
.button:hover {
background-color: #003d7a;
transform: scale(1.05);
}
}
Preferencias de esquema de color (prefers-color-scheme)
La media query prefers-color-scheme
detecta si el usuario prefiere un tema claro u oscuro en su sistema operativo. Aunque ya vimos variables CSS para implementar temas en la sección anterior, esta media query nos permite activarlos automáticamente según las preferencias del usuario:
:root {
/* Tema claro (predeterminado) */
--color-text: #333333;
--color-background: #ffffff;
--color-primary: #0056b3;
--color-secondary: #6c757d;
}
/* Aplicamos automáticamente el tema oscuro si el usuario lo prefiere */
@media (prefers-color-scheme: dark) {
:root {
--color-text: #f5f5f5;
--color-background: #121212;
--color-primary: #4d9fff;
--color-secondary: #a1a8ae;
}
}
body {
color: var(--color-text);
background-color: var(--color-background);
}
.button-primary {
background-color: var(--color-primary);
color: white;
}
Preferencias de contraste (prefers-contrast)
La media query prefers-contrast
detecta si el usuario ha configurado su sistema para mostrar contenido con mayor o menor contraste. Esta característica es especialmente útil para personas con baja visión o sensibilidad a ciertos contrastes.
Tiene tres valores posibles:
more
: El usuario prefiere mayor contrasteless
: El usuario prefiere menor contrasteno-preference
: El usuario no ha expresado preferencia
/* Estilos base con contraste estándar */
.card {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
color: #212529;
}
/* Aumentamos el contraste para usuarios que lo prefieren */
@media (prefers-contrast: more) {
.card {
background-color: white;
border: 2px solid black;
color: black;
}
/* Eliminamos efectos sutiles que reducen el contraste */
.card {
box-shadow: none;
text-shadow: none;
}
/* Aseguramos que los bordes sean muy visibles */
input, button, select, textarea {
border: 2px solid black;
outline: 2px solid black;
}
}
/* Reducimos el contraste para usuarios que lo prefieren */
@media (prefers-contrast: less) {
.card {
background-color: #fafafa;
border-color: #eaeaea;
color: #333333;
}
}
Combinando media queries para mayor precisión
Podemos combinar diferentes media queries para crear experiencias aún más personalizadas:
/* Estilos para modo oscuro con alto contraste */
@media (prefers-color-scheme: dark) and (prefers-contrast: more) {
:root {
--color-text: white;
--color-background: black;
--color-primary: yellow;
--color-border: white;
}
/* Aseguramos que los elementos interactivos sean muy visibles */
button, a {
border: 2px solid white;
text-decoration: underline;
}
}
/* Estilos para modo oscuro con reducción de movimiento */
@media (prefers-color-scheme: dark) and (prefers-reduced-motion: reduce) {
.hero-section {
background-image: url('static-dark-bg.jpg');
/* En lugar de un video o animación de fondo */
}
}
Preferencias de transparencia (prefers-reduced-transparency)
Aunque tiene menor soporte en navegadores, también existe la media query prefers-reduced-transparency
para usuarios que prefieren menos efectos de transparencia:
.glass-card {
background-color: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(10px);
}
@media (prefers-reduced-transparency: reduce) {
.glass-card {
background-color: #ffffff;
backdrop-filter: none;
}
}
Implementación práctica: Sistema completo de preferencias
Veamos un ejemplo más completo que integra varias preferencias de usuario:
:root {
/* Variables base */
--transition-speed: 0.3s;
--animation-duration: 1s;
/* Colores - tema claro predeterminado */
--color-text: #333333;
--color-background: #ffffff;
--color-surface: #f5f5f5;
--color-primary: #0056b3;
--color-secondary: #6c757d;
--color-border: #dee2e6;
/* Efectos */
--shadow-small: 0 2px 4px rgba(0, 0, 0, 0.1);
--shadow-medium: 0 4px 8px rgba(0, 0, 0, 0.1);
--blur-effect: blur(10px);
--transparency-level: 0.8;
}
/* Ajustes para modo oscuro */
@media (prefers-color-scheme: dark) {
:root {
--color-text: #f5f5f5;
--color-background: #121212;
--color-surface: #1e1e1e;
--color-primary: #4d9fff;
--color-secondary: #a1a8ae;
--color-border: #333333;
/* Ajustamos sombras para modo oscuro */
--shadow-small: 0 2px 4px rgba(0, 0, 0, 0.3);
--shadow-medium: 0 4px 8px rgba(0, 0, 0, 0.3);
}
}
/* Ajustes para alto contraste */
@media (prefers-contrast: more) {
:root {
/* Maximizamos contraste */
--color-text: black;
--color-background: white;
--color-surface: white;
--color-primary: #0000ee;
--color-secondary: #551a8b;
--color-border: black;
/* Eliminamos efectos que reducen contraste */
--shadow-small: none;
--shadow-medium: none;
--blur-effect: none;
--transparency-level: 1;
}
/* En modo oscuro con alto contraste */
@media (prefers-color-scheme: dark) {
:root {
--color-text: white;
--color-background: black;
--color-surface: black;
--color-primary: yellow;
--color-secondary: #00ffff;
--color-border: white;
}
}
}
/* Ajustes para reducción de movimiento */
@media (prefers-reduced-motion: reduce) {
:root {
--transition-speed: 0s;
--animation-duration: 0s;
}
}
/* Aplicamos las variables a los elementos */
body {
color: var(--color-text);
background-color: var(--color-background);
transition: background-color var(--transition-speed),
color var(--transition-speed);
}
.card {
background-color: var(--color-surface);
border: 1px solid var(--color-border);
box-shadow: var(--shadow-small);
transition: transform var(--transition-speed),
box-shadow var(--transition-speed);
}
.card:hover {
transform: translateY(-5px);
box-shadow: var(--shadow-medium);
}
.button {
background-color: var(--color-primary);
color: white;
border: none;
transition: background-color var(--transition-speed);
}
.button:hover {
background-color: color-mix(in srgb, var(--color-primary), black 20%);
}
.glass-effect {
background-color: rgba(255, 255, 255, var(--transparency-level));
backdrop-filter: var(--blur-effect);
}
.loading-spinner {
animation: spin var(--animation-duration) linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
Detección de soporte para media queries
Para asegurar la compatibilidad con navegadores más antiguos, podemos usar @supports
para detectar si el navegador soporta estas media queries:
/* Enfoque por defecto */
.button {
background-color: #0056b3;
color: white;
transition: none; /* Sin animación por defecto */
}
/* Comprobamos si el navegador soporta prefers-reduced-motion */
@supports ((-webkit-appearance: none) or (-moz-appearance: none)) and
(selector(media (prefers-reduced-motion))) {
/* Si hay soporte, añadimos animaciones solo si el usuario no las ha reducido */
@media (prefers-reduced-motion: no-preference) {
.button {
transition: background-color 0.2s, transform 0.1s;
}
.button:hover {
background-color: #003d7a;
transform: scale(1.05);
}
}
}
Consideraciones para implementar media queries de preferencias
Al trabajar con estas media queries, es importante tener en cuenta:
- Prueba en diferentes sistemas operativos: Las preferencias de usuario se configuran de manera diferente en Windows, macOS, iOS, Android, etc.
- No fuerces preferencias: Respeta siempre las preferencias del usuario y no las sobrescribas con JavaScript.
- Proporciona controles adicionales: Además de responder a las preferencias del sistema, ofrece controles en tu interfaz para cambiar temas, contraste o animaciones.
- Mantén la funcionalidad: Al eliminar animaciones o cambiar contrastes, asegúrate de que la funcionalidad básica siga siendo accesible.
- Documenta las opciones: Informa a los usuarios sobre las opciones de accesibilidad disponibles en tu sitio.
Con estas media queries basadas en preferencias, podemos crear experiencias web que se adapten automáticamente a las necesidades específicas de cada usuario, mejorando significativamente la accesibilidad sin requerir configuración adicional.
Patrones de diseño accesibles con CSS
Los patrones de diseño accesibles son soluciones reutilizables que abordan problemas comunes de accesibilidad en interfaces web. Implementar estos patrones con CSS nos permite crear componentes que sean utilizables por todas las personas, independientemente de sus capacidades o dispositivos de asistencia.
Tarjetas accesibles
Las tarjetas son un componente fundamental en muchos diseños web modernos. Para hacerlas accesibles, debemos considerar varios aspectos:
.card {
display: flex;
flex-direction: column;
border: 1px solid #ddd;
border-radius: 4px;
padding: 1rem;
background-color: #fff;
/* Aseguramos que el borde sea visible para usuarios con baja visión */
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
/* Transición suave para estados interactivos */
transition: transform 0.2s, box-shadow 0.2s;
}
/* Si la tarjeta es interactiva (enlace o botón) */
a.card,
button.card {
cursor: pointer;
text-align: left; /* Mantiene la alineación natural del texto */
color: inherit; /* Hereda el color del texto */
font-family: inherit; /* Hereda la fuente */
text-decoration: none; /* Elimina el subrayado de enlaces */
}
/* Estado de foco para tarjetas interactivas */
a.card:focus-visible,
button.card:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
box-shadow: 0 0 0 4px rgba(26, 115, 232, 0.25);
}
/* Estado hover para tarjetas interactivas */
a.card:hover,
button.card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
Para mejorar aún más la accesibilidad, podemos añadir un indicador visual que comunique que la tarjeta es interactiva:
a.card::after,
button.card::after {
content: "";
position: absolute;
top: 1rem;
right: 1rem;
width: 1rem;
height: 1rem;
background-image: url("icon-interactive.svg");
background-size: contain;
background-repeat: no-repeat;
}
Acordeones accesibles
Los acordeones permiten mostrar y ocultar contenido, pero deben implementarse de manera que sean utilizables con teclado y lectores de pantalla:
.accordion {
border: 1px solid #ddd;
border-radius: 4px;
overflow: hidden;
}
.accordion-header {
margin: 0;
padding: 0;
}
.accordion-button {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 1rem;
background-color: #f5f5f5;
border: none;
text-align: left;
font-weight: bold;
cursor: pointer;
}
/* Indicador visual de expansión */
.accordion-button::after {
content: "";
width: 0.8rem;
height: 0.8rem;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
transform: rotate(45deg);
transition: transform 0.2s;
margin-left: 0.5rem;
}
/* Cuando está expandido, rotamos el indicador */
.accordion-button[aria-expanded="true"]::after {
transform: rotate(-135deg);
}
/* Estado de foco */
.accordion-button:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: -2px;
background-color: #e8f0fe;
}
/* Panel de contenido */
.accordion-panel {
padding: 0;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s, padding 0.3s;
}
/* Cuando está expandido */
.accordion-panel[aria-hidden="false"] {
max-height: 500px; /* Valor arbitrario, ajustar según necesidad */
padding: 1rem;
}
Este patrón debe complementarse con los atributos ARIA adecuados en HTML (aria-expanded
, aria-controls
, aria-hidden
), pero el CSS proporciona las pistas visuales necesarias.
Menús desplegables accesibles
Los menús desplegables son otro componente común que requiere consideraciones de accesibilidad:
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-toggle {
padding: 0.5rem 1rem;
background-color: #f5f5f5;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
/* Añadimos un indicador visual */
display: flex;
align-items: center;
gap: 0.5rem;
}
.dropdown-toggle::after {
content: "";
width: 0.5rem;
height: 0.5rem;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
transform: rotate(45deg);
}
/* Estado de foco */
.dropdown-toggle:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
background-color: #e8f0fe;
}
/* Menú desplegable */
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
min-width: 10rem;
padding: 0.5rem 0;
margin: 0.125rem 0 0;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
/* Oculto por defecto */
opacity: 0;
visibility: hidden;
transform: translateY(-10px);
transition: opacity 0.2s, visibility 0.2s, transform 0.2s;
}
/* Cuando está expandido */
.dropdown.open .dropdown-menu {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
/* Elementos del menú */
.dropdown-item {
display: block;
width: 100%;
padding: 0.5rem 1rem;
text-align: left;
background: none;
border: none;
color: #333;
text-decoration: none;
cursor: pointer;
}
.dropdown-item:hover {
background-color: #f5f5f5;
}
.dropdown-item:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: -2px;
background-color: #e8f0fe;
}
Pestañas (tabs) accesibles
Las pestañas son un patrón de navegación común que debe ser accesible tanto para usuarios de ratón como de teclado:
.tabs {
display: flex;
flex-direction: column;
}
.tab-list {
display: flex;
border-bottom: 1px solid #ddd;
margin: 0;
padding: 0;
list-style: none;
}
.tab {
margin-bottom: -1px;
}
.tab-button {
padding: 0.75rem 1.25rem;
background: none;
border: 1px solid transparent;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
cursor: pointer;
font-weight: 500;
color: #555;
}
/* Pestaña activa */
.tab-button[aria-selected="true"] {
background-color: #fff;
border-color: #ddd;
border-bottom-color: #fff;
color: #1a73e8;
}
/* Estado de foco */
.tab-button:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: -2px;
z-index: 1;
}
/* Estado hover */
.tab-button:hover:not([aria-selected="true"]) {
background-color: #f5f5f5;
border-bottom-color: #ddd;
}
/* Paneles de contenido */
.tab-panel {
padding: 1rem;
border: 1px solid #ddd;
border-top: none;
background-color: #fff;
}
/* Ocultar paneles inactivos */
.tab-panel[hidden] {
display: none;
}
Tooltips accesibles
Los tooltips proporcionan información adicional, pero deben ser accesibles para todos los usuarios:
.tooltip-container {
position: relative;
display: inline-block;
}
.tooltip-trigger {
/* Estilos para el elemento que activa el tooltip */
border-bottom: 1px dotted #555;
cursor: help;
}
.tooltip {
position: absolute;
bottom: 125%;
left: 50%;
transform: translateX(-50%);
padding: 0.5rem;
background-color: #333;
color: #fff;
border-radius: 4px;
font-size: 0.875rem;
white-space: nowrap;
z-index: 10;
/* Oculto por defecto */
opacity: 0;
visibility: hidden;
transition: opacity 0.2s, visibility 0.2s;
/* Aseguramos suficiente contraste */
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
/* Flecha del tooltip */
.tooltip::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #333 transparent transparent transparent;
}
/* Mostrar tooltip al hacer hover o al enfocar */
.tooltip-container:hover .tooltip,
.tooltip-trigger:focus + .tooltip,
.tooltip-trigger:focus-visible + .tooltip {
opacity: 1;
visibility: visible;
}
/* Aseguramos que el tooltip sea visible cuando se enfoca el trigger */
.tooltip-trigger:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
}
Carruseles accesibles
Los carruseles son componentes complejos que requieren consideraciones especiales para ser accesibles:
.carousel {
position: relative;
overflow: hidden;
}
.carousel-track {
display: flex;
transition: transform 0.5s ease;
}
.carousel-slide {
flex: 0 0 100%;
/* Aseguramos que cada slide tenga la misma anchura */
width: 100%;
}
/* Controles de navegación */
.carousel-controls {
display: flex;
justify-content: space-between;
margin-top: 1rem;
}
.carousel-button {
background-color: #f5f5f5;
border: 1px solid #ddd;
border-radius: 50%;
width: 2.5rem;
height: 2.5rem;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
/* Estado de foco */
.carousel-button:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
background-color: #e8f0fe;
}
/* Indicadores de slide */
.carousel-indicators {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 1rem;
}
.carousel-indicator {
width: 0.75rem;
height: 0.75rem;
border-radius: 50%;
background-color: #ddd;
border: none;
padding: 0;
cursor: pointer;
}
.carousel-indicator[aria-current="true"] {
background-color: #1a73e8;
}
.carousel-indicator:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
}
/* Pausa automática al hacer hover o enfocar */
.carousel:hover .carousel-track,
.carousel:focus-within .carousel-track {
animation-play-state: paused;
}
Modales accesibles
Los diálogos modales deben ser accesibles y permitir una navegación adecuada:
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
/* Oculto por defecto */
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s;
}
.modal-overlay.open {
opacity: 1;
visibility: visible;
}
.modal {
background-color: #fff;
border-radius: 4px;
max-width: 90%;
width: 500px;
max-height: 90vh;
overflow-y: auto;
padding: 1.5rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
/* Animación de entrada */
transform: scale(0.9);
transition: transform 0.3s;
}
.modal-overlay.open .modal {
transform: scale(1);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
.modal-title {
margin: 0;
font-size: 1.25rem;
}
.modal-close {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
padding: 0.25rem;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
.modal-close:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
background-color: #e8f0fe;
}
/* Aseguramos que el contenido detrás del modal no sea navegable */
body.modal-open {
overflow: hidden;
}
Formularios accesibles
Los formularios son elementos críticos que deben ser accesibles para todos los usuarios:
.form-group {
margin-bottom: 1.5rem;
}
.form-label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
/* Campos de texto */
.form-input {
display: block;
width: 100%;
padding: 0.5rem 0.75rem;
font-size: 1rem;
line-height: 1.5;
color: #333;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 4px;
transition: border-color 0.2s, box-shadow 0.2s;
}
.form-input:focus {
border-color: #1a73e8;
box-shadow: 0 0 0 3px rgba(26, 115, 232, 0.25);
outline: none;
}
/* Campos con error */
.form-input.error {
border-color: #dc3545;
}
.form-input.error:focus {
box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.25);
}
/* Mensaje de error */
.form-error {
display: block;
color: #dc3545;
margin-top: 0.25rem;
font-size: 0.875rem;
}
/* Campos obligatorios */
.required-field .form-label::after {
content: "*";
color: #dc3545;
margin-left: 0.25rem;
}
/* Checkbox y radio buttons */
.form-check {
display: flex;
align-items: center;
margin-bottom: 0.5rem;
}
.form-check-input {
margin-right: 0.5rem;
/* Aumentamos el tamaño para facilitar la interacción */
min-width: 1.25rem;
min-height: 1.25rem;
}
/* Botones de formulario */
.form-button {
padding: 0.5rem 1rem;
font-size: 1rem;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s, box-shadow 0.2s;
}
.form-button:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
}
.form-button-primary {
background-color: #1a73e8;
color: white;
border: none;
}
.form-button-primary:hover {
background-color: #1557b0;
}
Navegación de migas de pan (breadcrumbs)
Las migas de pan ayudan a los usuarios a entender su ubicación en un sitio web:
.breadcrumbs {
display: flex;
flex-wrap: wrap;
padding: 0.75rem 0;
margin: 0;
list-style: none;
}
.breadcrumb-item {
display: flex;
align-items: center;
}
/* Separador entre elementos */
.breadcrumb-item:not(:first-child)::before {
content: "/";
display: inline-block;
padding: 0 0.5rem;
color: #6c757d;
}
.breadcrumb-link {
color: #1a73e8;
text-decoration: none;
}
.breadcrumb-link:hover {
text-decoration: underline;
}
.breadcrumb-link:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
border-radius: 2px;
}
/* Elemento actual */
.breadcrumb-item.active {
color: #6c757d;
}
Paginación accesible
La paginación debe ser navegable con teclado y comprensible para lectores de pantalla:
.pagination {
display: flex;
padding: 0;
margin: 1rem 0;
list-style: none;
}
.pagination-item {
margin: 0 0.25rem;
}
.pagination-link {
display: flex;
align-items: center;
justify-content: center;
min-width: 2.5rem;
height: 2.5rem;
padding: 0 0.5rem;
border: 1px solid #ddd;
border-radius: 4px;
color: #1a73e8;
text-decoration: none;
}
.pagination-link:hover {
background-color: #f5f5f5;
}
.pagination-link:focus-visible {
outline: 2px solid #1a73e8;
outline-offset: 2px;
background-color: #e8f0fe;
}
/* Página actual */
.pagination-item.active .pagination-link {
background-color: #1a73e8;
border-color: #1a73e8;
color: white;
font-weight: bold;
}
/* Botones de navegación */
.pagination-prev .pagination-link,
.pagination-next .pagination-link {
font-size: 1.25rem;
}
/* Elemento deshabilitado */
.pagination-item.disabled .pagination-link {
color: #6c757d;
pointer-events: none;
background-color: #f5f5f5;
border-color: #ddd;
}
Barras de progreso accesibles
Las barras de progreso deben comunicar claramente su estado a todos los usuarios:
.progress {
display: flex;
height: 1rem;
overflow: hidden;
background-color: #e9ecef;
border-radius: 0.25rem;
}
.progress-bar {
display: flex;
flex-direction: column;
justify-content: center;
color: #fff;
text-align: center;
white-space: nowrap;
background-color: #1a73e8;
transition: width 0.6s ease;
}
/* Variantes de color */
.progress-bar-success {
background-color: #28a745;
}
.progress-bar-warning {
background-color: #ffc107;
color: #212529; /* Mejor contraste */
}
.progress-bar-danger {
background-color: #dc3545;
}
/* Barra de progreso con etiqueta */
.progress-with-label {
position: relative;
}
.progress-label {
position: absolute;
right: 0.5rem;
color: #212529;
font-weight: bold;
}
/* Barra de progreso indeterminada */
.progress-indeterminate .progress-bar {
width: 100%;
background-image: linear-gradient(
45deg,
rgba(255, 255, 255, 0.15) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.15) 50%,
rgba(255, 255, 255, 0.15) 75%,
transparent 75%,
transparent
);
background-size: 1rem 1rem;
animation: progress-bar-stripes 1s linear infinite;
}
@keyframes progress-bar-stripes {
from { background-position: 1rem 0; }
to { background-position: 0 0; }
}
Mensajes de alerta accesibles
Los mensajes de alerta deben ser claramente visibles y comprensibles:
.alert {
position: relative;
padding: 1rem;
margin-bottom: 1rem;
border: 1px solid transparent;
border-radius: 4px;
}
.alert-info {
color: #0c5460;
background-color: #d1ecf1;
border-color: #bee5eb;
}
.alert-success {
color: #155724;
background-color: #d4edda;
border-color: #c3e6cb;
}
.alert-warning {
color: #856404;
background-color: #fff3cd;
border-color: #ffeeba;
}
.alert-danger {
color: #721c24;
background-color: #f8d7da;
border-color: #f5c6cb;
}
/* Icono de alerta */
.alert::before {
content: "";
display: inline-block;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.5rem;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
vertical-align: text-bottom;
}
.alert-info::before {
background-image: url("icon-info.svg");
}
.alert-success::before {
background-image: url("icon-success.svg");
}
.alert-warning::before {
background-image: url("icon-warning.svg");
}
.alert-danger::before {
background-image: url("icon-danger.svg");
}
/* Botón para cerrar la alerta */
.alert-close {
position: absolute;
top: 0.5rem;
right: 0.5rem;
padding: 0.25rem;
background: none;
border: none;
font-size: 1.25rem;
cursor: pointer;
color: inherit;
}
.alert-close:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
}
Consideraciones generales para patrones accesibles
Al implementar estos patrones de diseño, es importante seguir estas prácticas:
- Mantén la semántica HTML: El CSS debe complementar un HTML semánticamente correcto.
- Asegura suficiente contraste: Todos los elementos deben tener una relación de contraste adecuada.
- Proporciona estados visibles: Los estados de hover, focus, active y disabled deben ser claramente distinguibles.
- Usa transiciones con moderación: Las transiciones deben ser sutiles y respetar las preferencias de reducción de movimiento.
- Prueba con tecnologías asistivas: Verifica que los componentes funcionen correctamente con lectores de pantalla y navegación por teclado.
- Mantén la consistencia: Utiliza patrones coherentes en toda la interfaz para facilitar el aprendizaje y uso.
Estos patrones de diseño accesibles con CSS te proporcionan una base sólida para crear interfaces inclusivas que puedan ser utilizadas por todas las personas, independientemente de sus capacidades o dispositivos.
Ejercicios de esta lección Accesibilidad web con CSS
Evalúa tus conocimientos de esta lección Accesibilidad web con CSS con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Reto modelo caja CSS
Propiedades de posicionamiento
Modelo de caja
Sombras en texto y cajas
Reto implementación de fuentes web
Sintaxis básica
Estilos de fuente
Diseño responsive con media queries
Animaciones y transiciones
Proyecto CSS Landing page simple
Reto unidades de medida
Propiedades de texto
Metodologías BEM, SMACSS, OOCSS
Herencia y cascada
Sintaxis avanzada
Reto fondos background CSS
Reto sintaxis CSS
Flexbox en diseños modernos
Elementos 'float' y 'clear'
Pseudo-clases y pseudo-elementos
Reto grid de columnas en CSS
Selectores avanzados
Reto componente responsive
Reto formulario estilizado
Proyecto CSS crear una navbar
Proyecto CSS Dashboard Responsive
Reto Flexbox Hero
Propiedades de fondo
Introducción a CSS
Reto selectores básicos CSS
Reto Flexbox Card
Reto propiedades texto
Modelo de caja
Propiedad 'display'
Variables en CSS
Grid en diseños de cuadrícula
Selectores básicos
Reto tema claro/oscuro con variables
Reto especificidad y cascada
Todas las lecciones de CSS
Accede a todas las lecciones de CSS y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Css
Introducción Y Entorno
Entorno Para Desarrollar Css
Introducción Y Entorno
Sintaxis
Sintaxis De Selectores Y Propiedades
Selectores Básicos
Sintaxis De Selectores Y Propiedades
Herencia Y Cascada
Sintaxis De Selectores Y Propiedades
Pseudo-clases Y Pseudo-elementos
Sintaxis De Selectores Y Propiedades
Colores En Css
Sintaxis De Selectores Y Propiedades
Unidades De Medida
Sintaxis De Selectores Y Propiedades
Especificidad
Sintaxis De Selectores Y Propiedades
Estilos De Fuente
Estilización De Texto Y Fondo
Propiedades De Texto
Estilización De Texto Y Fondo
Sombras En Texto Y Cajas
Estilización De Texto Y Fondo
Propiedades De Fondo
Estilización De Texto Y Fondo
Fuentes Web
Estilización De Texto Y Fondo
Efectos De Texto: Gradientes, Recortes
Estilización De Texto Y Fondo
Tipografía Avanzada
Estilización De Texto Y Fondo
Modelo De Caja
Modelo Caja
Propiedades De Posicionamiento
Modelo Caja
Propiedad 'Display'
Modelo Caja
Elementos 'Float' Y 'Clear'
Modelo Caja
Rellenos Y Márgenes
Modelo Caja
Bordes Y Contornos
Modelo Caja
Absolute, Fixed, Sticky Y Z-index
Posicionamiento
Flexbox Para Crear Layouts Y Estructuras
Flexbox
Css Grid Para Crear Layouts Y Estructuras
Flexbox
Propiedades Del Contenedor Flex
Flexbox
Propiedades De Los Items Flex
Flexbox
Columnas Y Filas En Grid
Css Grid
Espaciado Y Alineación
Css Grid
Tipografía Responsive
Diseño Responsive
Fundamentos Del Diseño Responsive
Diseño Responsive
Imágenes Responsive
Diseño Responsive
Funciones Matemáticas
Variables Y Funciones Css
Transformaciones 2d
Transformación, Transición, Animación
Transformaciones 3d
Transformación, Transición, Animación
Animaciones
Transformación, Transición, Animación
Transiciones
Transformación, Transición, Animación
Css Para Formularios
Css Avanzado
Accesibilidad Web Con Css
Css Avanzado
Container Queries
Css Avanzado
Selectores Avanzados
Css Avanzado
Animaciones Y Transiciones
Técnicas Modernas Y Metodologías
Variables En Css
Técnicas Modernas Y Metodologías
Diseño Responsive Con Media Queries
Técnicas Modernas Y Metodologías
Metodologías De Escritura En Css
Técnicas Modernas Y Metodologías
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender la importancia del contraste de color y cómo aplicarlo según las pautas WCAG.
- Aprender a utilizar variables CSS para crear temas accesibles y alternativos.
- Diseñar estilos de foco claros y diferenciados para la navegación por teclado.
- Implementar media queries que respeten las preferencias de usuario como reducción de movimiento o modo oscuro.
- Aplicar patrones de diseño accesibles en componentes comunes como tarjetas, menús, formularios y modales.