DevTools

Cheatsheet CSS

Folhas de estilo para design web

Volver a los lenguajes
CSS
94 tarjetas encontradas
Categorías:
Versiones:

Selectores


12 cards
Selector de elemento
p { color: blue; }
h1 { font-size: 2rem; }

Se aplica a todos los elementos de ese tipo. Es el selector más simple y menos específico.

Descendente
nav a { text-decoration: none; }
.card p { color: gray; }

Selecciona elementos dentro de otro (cualquier nivel de profundidad). El espacio es el combinador descendente.

Selectores de atributo
input[type="text"] { border: 1px solid; }
a[href^="https"] { color: green; }
img[src$=".png"] { border: 2px solid; }
a[href*="ejemplo"] { font-weight: bold; }

Seleccionan por atributo: ^= empieza con, $= termina con, *= contiene.

Selector de clase
.highlight { font-weight: bold; }
.btn-primary { background: blue; }

Selecciona elementos con class="highlight". Puede reutilizarse en varios elementos. Es el selector más usado.

Hijo directo
ul > li { list-style: none; }
.card > h2 { margin: 0; }

El > selecciona solo hijos directos, no nietos. Más preciso que el descendente.

Agrupar selectores
h1, h2, h3 { margin: 0; }
.btn, .link { cursor: pointer; }

La coma aplica la misma regla a varios selectores. Evita repetir código.

Selector de ID
#encabezado { margin: 0; }
#menu { position: fixed; }

Selecciona el elemento con id="encabezado". El ID debe ser único en la página. Tiene alta especificidad — evita usarlo para estilos.

Pseudo-clases
a:hover { color: red; }
input:focus { border: 2px solid blue; }
li:first-child { font-weight: bold; }
li:nth-child(2n) { background: #f5f5f5; }
li:last-child { border: none; }

Las pseudo-clases seleccionan por estado (hover, focus) o posición (first-child, nth-child). No necesitan una clase extra.

Especificidad
/* Orden de prioridad (mayor gana): */
/* inline (1000) > #id (100) > .clase (10) > elemento (1) */

p { color: blue; }          /* 1 */
.texto { color: green; }    /* 10 */
#título { color: red; }     /* 100 */

La especificidad decide qué regla gana en un conflicto. IDs > clases > elementos. El inline y !important sobrescriben todo.

Selector universal
* { box-sizing: border-box; }
* { margin: 0; padding: 0; }

Se aplica a todos los elementos. Útil para resets y box-sizing global.

Pseudo-elementos
p::before { content: "» "; }
p::after { content: " «"; }
p::first-line { font-weight: bold; }
::placeholder { color: #999; }

Los pseudo-elementos (::) crean contenido virtual o estilizan partes. El content es obligatorio en before/after.

Combinador de hermano
/* Hermano adyacente (justo después) */
h2 + p { margin-top: 0; }

/* Todos los hermanos siguientes */
h2 ~ p { color: gray; }

El + selecciona el hermano inmediatamente siguiente. El ~ selecciona todos los hermanos siguientes del mismo tipo.

Colores y fondos


8 cards
Formatos de color
color: red;
color: #ff0000;
color: rgb(255, 0, 0);
color: rgba(255, 0, 0, 0.5);
color: hsl(0, 100%, 50%);
color: hsla(0, 100%, 50%, 0.5);

CSS acepta nombres, hex, RGB(A) y HSL(A). El HSL es más intuitivo: matiz, saturación y luminosidad.

Gradiente radial
background: radial-gradient(circle, #fff, #000);
background: radial-gradient(ellipse at top, #a8edea, #fed6e3);

radial-gradient irradia del centro hacia afuera. La forma puede ser circle o ellipse.

Color de fondo
background-color: #f0f0f0;
background-color: rgba(0, 0, 0, 0.8);

Define el color de fondo del elemento. Con rgba, el fondo queda semitransparente sin afectar al texto.

Opacidad
opacity: 0.5;   /* 0 = transparente, 1 = opaco */
opacity: 0;     /* invisible pero ocupa espacio */

/* Afecta a TODO el elemento (texto incluido) */
/* Para solo el fondo, usa rgba() */

La opacidad afecta al elemento entero (hijos incluidos). Para transparencia solo en el fondo, usa rgba() en el color.

Imagen de fondo
background-image: url("img.jpg");
background-size: cover;
background-position: center;
background-repeat: no-repeat;

cover llena todo el espacio (puede recortar). contain muestra la imagen entera (puede dejar espacio).

Background shorthand
background: #fff url("x.jpg") no-repeat center / cover;

/* Orden: color | imagen | repeat | posición / size */

El shorthand junta todas las propiedades de fondo en una línea. El / separa posición de size.

Gradiente lineal
background: linear-gradient(to right, #ff7e5f, #feb47b);
background: linear-gradient(135deg, #667eea, #764ba2);
background: linear-gradient(#fff, #000);

linear-gradient crea una transición suave entre colores. La dirección puede ser to right, un ángulo, o por defecto de arriba a abajo.

Múltiples fondos
background:
  url("logo.png") no-repeat top right,
  url("pattern.png") repeat,
  #f0f0f0;

Puedes apilar varios fondos separados por coma. El primero queda encima de los siguientes.

Texto y fuentes


11 cards
Familia de fuente
font-family: "Segoe UI", Arial, sans-serif;
font-family: monospace;

Lista de fuentes con fallback. Si la primera no existe, prueba la siguiente. Los nombres con espacio necesitan comillas.

Decoración
text-decoration: underline;
text-decoration: none;        /* quita el subrayado */
text-decoration: line-through; /* tachado */
text-decoration: overline;

El none quita el subrayado de los enlaces. El line-through se usa para precios antiguos o tareas completadas.

Google Fonts
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap");

body {
  font-family: "Roboto", sans-serif;
}

El @import o la etiqueta <link> cargan fuentes de Google. El display=swap muestra texto inmediatamente con un fallback.

Tamaño de fuente
font-size: 16px;    /* fijo */
font-size: 1.2rem;  /* relativo a la raíz */
font-size: 1.5em;   /* relativo al padre */

El rem es relativo al html (recomendado). El em es relativo al padre. El px es fijo y no escala.

Espaciado
line-height: 1.6;      /* entre líneas */
letter-spacing: 2px;   /* entre letras */
word-spacing: 5px;     /* entre palabras */

Un line-height de 1.5-1.8 mejora la legibilidad. El letter-spacing es útil en mayúsculas y títulos.

Truncar con puntos suspensivos
.truncar {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

Las tres propiedades juntas cortan el texto con "..." cuando excede el contenedor. Requiere un ancho definido.

Peso y estilo
font-weight: bold;    /* 700 */
font-weight: 300;     /* light */
font-style: italic;
font-style: normal;

El font-weight acepta nombres (bold, normal) o numeros (100-900). El font-style controla la cursiva.

Transformación de texto
text-transform: uppercase;
text-transform: lowercase;
text-transform: capitalize;
text-transform: none;

Transforma el texto visualmente sin alterar el HTML. El capitalize pone la primera letra de cada palabra en mayúscula.

Truncar múltiples líneas
.truncar-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

El line-clamp limita el texto a N líneas con puntos suspensivos. Funciona en los navegadores modernos (prefijo -webkit-).

Alineación
text-align: center;
text-align: left;
text-align: right;
text-align: justify;

Alinea el texto horizontalmente. El justify distribuye el texto entre los dos márgenes (como en los periódicos).

Sombra de texto
text-shadow: 2px 2px 4px #000;
text-shadow: 0 0 10px rgba(0,0,0,0.5);
text-shadow: 1px 1px 0 #fff, 2px 2px 0 #ccc;

Formato: x y blur color. Puedes apilar varias sombras con coma para efectos creativos.

Modelo de caja


10 cards
Box model
/* Del exterior al interior: */
/* margin > border > padding > content */

.caja {
  margin: 20px;
  border: 1px solid #ccc;
  padding: 15px;
  width: 300px;
}

Cada elemento es una caja con 4 capas: margin (fuera), border, padding (dentro) y content.

Bordes
border: 1px solid #ccc;
border-radius: 8px;
border-radius: 50%;     /* círculo */
border-top: 2px dashed red;

El shorthand es grosor estilo color. El border-radius: 50% transforma cualquier cuadrado en un círculo.

Display
display: block;         /* ocupa toda la línea */
display: inline;        /* fluye con el texto */
display: inline-block;  /* inline + dimensiones */
display: none;          /* oculta totalmente */
display: flex;
display: grid;

El display define el tipo de caja. El none lo quita del flujo. El inline-block acepta width/height pero fluye inline.

box-sizing
* { box-sizing: border-box; }

/* content-box (por defecto): width = solo contenido */
/* border-box: width = contenido + padding + border */

El border-box hace que el width incluya padding y border. Hace los cálculos mucho más predecibles. Úsalo siempre.

Ancho y alto
width: 100%;
max-width: 1200px;
height: 200px;
min-height: 100vh;
aspect-ratio: 16 / 9;

El max-width evita estirar demasiado. El min-height: 100vh garantiza una altura mínima de pantalla. El aspect-ratio mantiene la proporción.

Visibility vs Display
visibility: hidden;  /* oculta pero ocupa espacio */
display: none;       /* quita del layout */
opacity: 0;          /* invisible, clicable */

El visibility: hidden oculta pero mantiene el espacio. El display: none lo quita por completo. El opacity: 0 aún recibe clics.

Márgenes
margin: 10px;                  /* todos */
margin: 10px auto;             /* centra horizontalmente */
margin: 5px 10px 15px 20px;   /* arriba der abajo izq */
margin: 10px 20px;            /* vertical | horizontal */

El auto en los laterales centra el bloque. El shorthand sigue el sentido horario: arriba, derecha, abajo, izquierda.

Sombra de caja
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
box-shadow: 0 0 0 3px blue;  /* "anillo" */
box-shadow: inset 0 2px 4px #000;  /* interna */

Formato: x y blur spread color. El inset hace la sombra hacia dentro. Sin blur/spread crea un contorno sólido.

Padding
padding: 20px;
padding: 10px 20px;    /* vertical | horizontal */
padding: 0 15px 10px;  /* arriba | lados | abajo */

El padding es el espacio interno entre el contenido y el borde. No acepta valores negativos (al contrario que margin).

Overflow
overflow: hidden;    /* corta */
overflow: auto;      /* scroll si es necesario */
overflow: scroll;    /* scroll siempre */
overflow: visible;   /* muestra fuera (por defecto) */

El overflow controla lo que pasa cuando el contenido excede la caja. El auto solo muestra scroll cuando lo necesita.

Caja flexible


10 cards
Activar flexbox
.container {
  display: flex;
}
/* Los hijos directos se vuelven items flex */

El display: flex activa el layout flexible en los hijos directos. El contenedor controla la alineación y distribución.

flex-wrap
flex-wrap: nowrap;  /* por defecto: todo en una línea */
flex-wrap: wrap;    /* salta a la línea siguiente */
flex-wrap: wrap-reverse;

Sin wrap, los items se comprimen en una línea. Con wrap, pasan a la línea siguiente cuando no caben.

order y align-self
.item { order: 2; }           /* reordena visualmente */
.item { align-self: flex-end; } /* sobrepone align-items */

El order cambia el orden visual sin alterar el HTML. El align-self sobrepone la alineación en un item específico.

Dirección
flex-direction: row;            /* → por defecto */
flex-direction: column;         /* ↓ */
flex-direction: row-reverse;    /* ← */
flex-direction: column-reverse; /* ↑ */

La dirección define el eje principal. Con column, el justify-content pasa a controlar la vertical.

gap
gap: 20px;
row-gap: 10px;
column-gap: 30px;

El gap es el espaciado moderno entre items flex/grid. Sustituye margins hacky y no añade espacio en los bordes.

Layout con flex (ejemplo)
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
}
/* Logo a la izquierda, menú a la derecha */

Ejemplo práctico: navbar con logo a la izquierda y menú a la derecha. El space-between los empuja a los bordes.

justify-content
justify-content: flex-start;
justify-content: center;
justify-content: flex-end;
justify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;

Distribuye los items en el eje principal. El space-between pega el primero y el último a los bordes. El space-evenly da espacios iguales.

flex shorthand
flex: 1;           /* crece igual */
flex: 0 0 200px;   /* fijo, no crece ni encoge */
flex: 2;           /* crece el doble que los demás */

/* flex: grow shrink basis */

El flex combina grow (crecer), shrink (encoger) y basis (tamaño base). El flex: 1 distribuye el espacio por igual.

align-items
align-items: stretch;     /* estira (por defecto) */
align-items: center;      /* centra */
align-items: flex-start;  /* arriba */
align-items: flex-end;    /* abajo */
align-items: baseline;    /* línea de texto */

Alinea los items en el eje cruzado (perpendicular). Con row, controla la vertical. El stretch es el valor por defecto.

Centrar perfectamente
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

La combinación justify + align center centra horizontal y verticalmente. El patrón más usado para centrar cualquier cosa.

Red


10 cards
Activar grid
.container {
  display: grid;
}
/* Los hijos se vuelven celdas de rejilla */

El display: grid activa el layout de rejilla. Ideal para layouts bidimensionales (filas Y columnas a la vez).

Definir filas
grid-template-rows: 100px auto 50px;
grid-auto-rows: minmax(100px, auto);

El grid-template-rows define alturas fijas. El grid-auto-rows controla las filas creadas automáticamente.

Alinear en grid
justify-items: center;   /* horizontal en la celda */
align-items: center;     /* vertical en la celda */
place-items: center;     /* ambos (shorthand) */

justify-content: center; /* la rejilla en el contenedor */

El place-items: center centra el contenido dentro de cada celda. El justify/align-content posiciona la rejilla entera.

Definir columnas
grid-template-columns: 200px 1fr 1fr;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(4, 250px);

El fr es una fracción del espacio disponible. El repeat(3, 1fr) crea 3 columnas iguales. Puedes mezclar px y fr.

Ocupar varias columnas
.item {
  grid-column: span 2;
}
.item-full {
  grid-column: 1 / -1;  /* todas */
}

El span 2 hace que el item ocupe 2 columnas. El 1 / -1 se extiende de la primera a la última columna (ancho completo).

Grid vs Flexbox
/* Flexbox: 1 dimensión (fila O columna) */
.nav { display: flex; }

/* Grid: 2 dimensiones (filas Y columnas) */
.layout { display: grid; }

/* ¡Se pueden combinar! */

Usa Flexbox para alinear items en una dirección. Usa Grid para layouts con filas y columnas. Se combinan bien.

Rejilla responsiva automática
grid-template-columns:
  repeat(auto-fit, minmax(250px, 1fr));

El auto-fit + minmax crea columnas que se ajustan solas. ¡Sin media queries! El patrón más útil de Grid.

Posicionar item
.item {
  grid-column: 1 / 3;  /* columnas 1 y 2 */
  grid-row: 1 / 2;     /* fila 1 */
}

Define inicio / fin en las líneas de la rejilla. Los numeros se refieren a las líneas (no a las celdas).

gap
gap: 20px;
row-gap: 10px;
column-gap: 30px;

El gap define el espacio entre celdas. Sustituye margins y es más limpio que los hacks con padding.

Áreas nombradas
.layout {
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }

Las grid-template-areas crean un layout visual con nombres. Muy legible — parece un dibujo de la página.

Posicionamiento


8 cards
Position
position: static;    /* por defecto, flujo normal */
position: relative;  /* desplaza del original */
position: absolute;  /* fuera del flujo */
position: fixed;     /* fijo en el viewport */
position: sticky;    /* se pega al hacer scroll */

El position controla cómo se posiciona el elemento. Solo static ignora las propiedades top/right/bottom/left.

Fixed
.barra {
  position: fixed;
  bottom: 0;
  width: 100%;
}

El fixed fija el elemento al viewport — no se desplaza con la página. Ideal para barras de navegación y botones flotantes.

Coordenadas
top: 10px;
right: 0;
bottom: 0;
left: 20px;
inset: 0;  /* todos a 0 (shorthand) */

Las coordenadas funcionan con position (excepto static). El inset: 0 es shorthand para top/right/bottom/left todos iguales.

Sticky
.menu {
  position: sticky;
  top: 0;
}

El sticky se comporta como relative hasta alcanzar el offset, luego se "pega" como fixed. Perfecto para headers y menús.

Relative
.caja {
  position: relative;
  top: 10px;
  left: 20px;
}
/* Desplaza pero mantiene el espacio original */

El relative desplaza el elemento de su posición original. El espacio que ocupaba se preserva. Sirve de referencia para hijos absolute.

z-index
.modal { z-index: 1000; }
.dropdown { z-index: 100; }
.navbar { z-index: 50; }

El z-index controla el orden de apilado (quién queda encima). Requiere position (no static). Los valores mayores quedan al frente.

Absolute
.pai { position: relative; }
.filho {
  position: absolute;
  top: 0;
  right: 0;
}

El absolute posiciona relativo al ancestro con position (no static) más cercano. Quita el elemento del flujo normal.

Centrar con absolute
.centro {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

Combina top/left 50% con translate(-50%, -50%) para centrar. Alternativa al flexbox para overlays y modales.

Sensible


8 cards
Media query
@media (max-width: 768px) {
  .menu { display: none; }
  .contenido { padding: 10px; }
}

Las media queries aplican reglas según el ancho de pantalla. El max-width es mobile-first al revés.

Imágenes responsivas
img {
  max-width: 100%;
  height: auto;
  display: block;
}

El max-width: 100% impide que la imagen exceda el contenedor. El height: auto mantiene la proporción. El display: block quita el espacio extra.

Breakpoints comunes
/* Mobile first (min-width): */
@media (min-width: 576px) { /* tablet */ }
@media (min-width: 768px) { /* desktop */ }
@media (min-width: 992px) { /* grande */ }
@media (min-width: 1200px) { /* xl */ }

Los breakpoints son puntos donde el layout cambia. El enfoque mobile-first usa min-width (estilos base = móvil).

clamp() fluido
font-size: clamp(1rem, 2.5vw, 2rem);
width: clamp(300px, 80%, 1200px);
padding: clamp(1rem, 5vw, 3rem);

El clamp(mín, preferido, máx) crea valores fluidos con límites. Sustituye media queries para tipografía y espaciados.

Unidad rem
html { font-size: 16px; }
h1 { font-size: 2rem; }    /* 32px */
p { font-size: 1rem; }     /* 16px */
.caja { padding: 1.5rem; } /* 24px */

El rem es relativo al font-size del html. Si cambias la raíz, todo escala proporcionalmente. Recomendado para accesibilidad.

Container queries
.card-wrapper {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .card { display: flex; }
}

Las container queries aplican estilos basados en el tamaño del contenedor (no del viewport). El futuro del CSS responsivo.

Unidades viewport
width: 100vw;     /* ancho de pantalla */
height: 100vh;    /* alto de pantalla */
font-size: 5vw;   /* escala con el ancho */
min-height: 100dvh; /* altura dinámica (móvil) */

Las unidades vw/vh son porcentajes del viewport. El dvh (dynamic viewport height) lidia con la barra del navegador móvil.

Orientación y preferencias
@media (orientation: landscape) { ... }

@media (prefers-color-scheme: dark) {
  body { background: #1a1a2e; color: #eee; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none; }
}

Además del ancho, puedes detectar la orientación, el tema oscuro y la preferencia de movimiento del usuario.

Transiciones y animaciones


8 cards
Transición
.btn {
  transition: all 0.3s ease;
}
.btn:hover {
  background: blue;
  transform: scale(1.05);
}

La transition anima cambios de propiedad suavemente. Formato: propiedad duración timing-function delay.

Propiedades de animación
animation-name: piscar;
animation-duration: 2s;
animation-delay: 0.5s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-fill-mode: forwards;

Control fino: delay (espera), iteration-count (repeticiones), direction (alternate invierte), fill-mode (estado final).

Transición específica
transition: background 0.3s,
  transform 0.5s ease-in-out;

/* Evita "all" en producción (rendimiento) */

Especifica qué propiedades animar en vez de all. Mejor rendimiento y control sobre cada animación.

Efecto hover (elevación)
.card {
  transition: transform 0.2s, box-shadow 0.2s;
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 12px rgba(0,0,0,0.15);
}

El efecto de elevación combina translateY con box-shadow. Da la sensación de que el elemento se "levanta" al pasar el ratón.

Transform
transform: scale(1.1);
transform: rotate(45deg);
transform: translateX(20px);
transform: translateY(-10px);
transform: skewX(5deg);

El transform aplica transformaciones visuales sin afectar al layout. Puedes combinar: translateX(10px) scale(1.1).

Timing functions
ease            /* suave (por defecto) */
linear          /* velocidad constante */
ease-in         /* empieza lento */
ease-out        /* termina lento */
ease-in-out     /* ambos */
cubic-bezier(0.4, 0, 0.2, 1)

Las timing functions controlan la aceleración. El ease-out es bueno para entradas. El cubic-bezier permite curvas personalizadas.

Keyframes
@keyframes piscar {
  0% { opacity: 1; }
  50% { opacity: 0; }
  100% { opacity: 1; }
}

.item {
  animation: piscar 1s infinite;
}

Los @keyframes definen los pasos de la animación. El animation la aplica con nombre, duración y repeticiones.

Animación de entrada
@keyframes aparecer {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card {
  animation: aparecer 0.4s ease-out;
}

La animación de entrada (fade + slide) da pulido a la interfaz. El ease-out hace que el elemento "aterrice" suavemente.

Consejos y buenas prácticas


9 cards
Variables CSS
:root {
  --color-principal: #3498db;
  --spacing: 1rem;
  --radio: 8px;
}

.btn {
  color: var(--color-principal);
  padding: var(--spacing);
  border-radius: var(--radio);
}

Las variables CSS (--nombre) centralizan valores. Cambiar en un sitio actualiza todo. Pueden ser sobrescritas por componente.

Selección de texto
::selection {
  background: #3498db;
  color: white;
}

El ::selection estiliza el texto cuando el usuario lo selecciona. Un pequeño detalle que da personalidad al sitio.

aspect-ratio
.video {
  aspect-ratio: 16 / 9;
  width: 100%;
}

.avatar {
  aspect-ratio: 1;  /* cuadrado */
  border-radius: 50%;
}

El aspect-ratio mantiene la proporción sin hacks de padding. Sustituye el truco del padding-top para vídeos responsivos.

Reset básico
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

El reset quita los estilos por defecto del navegador (margins, paddings). El border-box hace los cálculos predecibles.

Filtro de imagen
filter: grayscale(100%);
filter: blur(5px);
filter: brightness(0.8) contrast(1.2);
filter: sepia(0.5);

Los filtros aplican efectos visuales sin editar la imagen. Puedes combinar varios en la misma declaración.

Cursor
cursor: pointer;     /* clicable */
cursor: not-allowed;  /* desactivado */
cursor: grab;         /* arrastrable */
cursor: text;         /* editable */

El cursor: pointer indica que el elemento es clicable. Úsalo en botones, enlaces y elementos interactivos.

Esconder scrollbar
.no-scroll {
  scrollbar-width: none;       /* Firefox */
  -ms-overflow-style: none;    /* IE */
}
.no-scroll::-webkit-scrollbar {
  display: none;               /* Chrome */
}

Oculta la barra de scroll manteniendo la funcionalidad. Útil en carruseles y listas horizontales.

Scroll suave
html {
  scroll-behavior: smooth;
}

/* Respetar la preferencia del usuario: */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

El scroll-behavior: smooth anima el desplazamiento al hacer clic en anclas. Respeta siempre la preferencia de movimiento reducido.

Outline vs Border
/* Outline: no afecta al layout, bueno para focus */
input:focus {
  outline: 2px solid blue;
  outline-offset: 2px;
}

/* ¡Nunca quites el outline sin alternativa! */

El outline no ocupa espacio (no cambia el layout). Es esencial para la accesibilidad — nunca lo quites sin dar una alternativa visual.