agentsclimarketplace

Css

Skill 14BryanEspinoza/agent-stack/skills/css

Skills modulares para asistentes de codificación por IA. Define reglas, flujos de trabajo y estándares técnicos mediante archivos Markdowm.

Install
npx -y skills add 14BryanEspinoza/agent-stack --skill css

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 21 days oldThe repository was created 21 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Reglas de CSS moderno - layout, responsive, animaciones, container queries, layers, nesting, accesibilidad

SKILL.md

27.1 KB, as published. Nobody here has run it

CSS - Reglas y Convenciones


1. Filosofía

  1. Mobile-first — Los estilos se escriben para móvil primero. Pantallas más grandes reciben mejoras progresivas vía media queries, no al revés.
  2. Performance por defecto — Preferir propiedades que solo activan compositing (transform, opacity). Evitar animaciones que causan reflow/repaint (width, height, top). CSS > JS para animaciones.
  3. Mantenibilidad sobre conveniencia — Naming consistente (BEM), custom properties para temas, spacing y colores. Cero magic numbers. El código CSS se lee más veces del que se escribe.
  4. Progressive enhancement — Diseñar para navegadores modernos pero asegurar funcionalidad básica en los antiguos. Las features modernas (:has, container queries, nesting) son mejoras, no requisitos.
  5. Accesibilidad visual — Contraste suficiente, focus visible, respetar prefers-reduced-motion. El estilo nunca debe reducir la usabilidad.

2. Versión Mínima

TecnologíaVersión
CSSCSS3+ (moderno)

3. Mobile-First (Obligatorio)

Escribir estilos para móvil primero, luego escalar con media queries.

/* Base: mobile */
.container {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  padding: 1rem;
}

/* Tablet */
@media (min-width: 768px) {
  .container {
    grid-template-columns: repeat(2, 1fr);
    padding: 1.5rem;
  }
}

/* Desktop */
@media (min-width: 1024px) {
  .container {
    grid-template-columns: repeat(3, 1fr);
    padding: 2rem;
  }
}

Breakpoints

BreakpointAncho mínimoUso
sm576pxTablets pequeños
md768pxTablets
lg992pxDesktops
xl1200pxDesktops grandes
2xl1400pxPantallas extra

4. Layout

Flexbox (una dimensión)

/* Centro horizontal y vertical */
.centered {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Navbar */
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

/* Cards en fila */
.card-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.card-row > * {
  flex: 1 1 300px;
}

/* Flex propiedades clave */
flex-direction: row | column;
flex-wrap: wrap | nowrap;
flex: <grow> <shrink> <basis>;
align-items: center | flex-start | flex-end | stretch | baseline;
justify-content: center | space-between | space-around | flex-start | flex-end;
gap: <row-gap> <column-gap>;

Grid (dos dimensiones)

/* Grid básico */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1.5rem;
}

/* Sidebar + contenido */
.layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  gap: 2rem;
}

@media (max-width: 768px) {
  .layout {
    grid-template-columns: 1fr;
  }
}

/* Áreas nombradas */
.page {
  display: grid;
  grid-template-areas:
    "header header"
    "nav    main"
    "footer footer";
  grid-template-columns: 200px 1fr;
  gap: 1rem;
}

header {
  grid-area: header;
}
nav {
  grid-area: nav;
}
main {
  grid-area: main;
}
footer {
  grid-area: footer;
}

/* Subgrid (heredar tracks del grid padre) */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.card {
  display: grid;
  grid-template-rows: subgrid; /* Hereda filas del padre */
  grid-row: span 3; /* Ocupa 3 filas del padre */
}

/* Propiedades Grid clave */
grid-template-columns: repeat(3, 1fr) | 200px 1fr | auto-fill minmax(250px, 1fr);
grid-template-rows: auto 1fr auto;
grid-column: 1 / -1; /* De inicio a fin */
grid-row: span 2; /* Ocupa 2 filas */
gap: 1rem;
justify-items: center | stretch;
align-items: center | stretch;
place-items: center; /* shorthand justify + align */

5. Naming Conventions

BEM (Block Element Modifier)

/* Block - componente independiente */
.card {
}

/* Element - parte del block (__) */
.card__title {
}
.card__body {
}
.card__footer {
}

/* Modifier - variación (--) */
.card--featured {
}
.card--dark {
}
.card__title--large {
}

Ejemplo completo

<div class="card card--featured">
  <h2 class="card__title card__title--large">Título</h2>
  <p class="card__body">Contenido del card</p>
  <div class="card__footer">
    <button class="card__button card__button--primary">Acción</button>
  </div>
</div>
.card {
  border: 1px solid #e5e7eb;
  border-radius: 0.5rem;
  padding: 1.5rem;
  background: var(--color-bg);
}

.card--featured {
  border-color: var(--color-primary);
  box-shadow: 0 4px 6px -1px rgba(99, 102, 241, 0.2);
}

.card__title {
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.card__title--large {
  font-size: 1.5rem;
}

.card__body {
  color: var(--color-text-secondary);
  line-height: 1.6;
}

.card__button--primary {
  background-color: var(--color-primary);
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
  cursor: pointer;
}

Alternativa: utility-first

Para proyectos sin Tailwind:

/* Spacing */
.mt-1 {
  margin-top: 0.25rem;
}
.mt-2 {
  margin-top: 0.5rem;
}
.mt-4 {
  margin-top: 1rem;
}
.p-4 {
  padding: 1rem;
}
.p-6 {
  padding: 1.5rem;
}
.mx-auto {
  margin-inline: auto;
}

/* Flex */
.flex {
  display: flex;
}
.flex-col {
  flex-direction: column;
}
.flex-wrap {
  flex-wrap: wrap;
}
.items-center {
  align-items: center;
}
.justify-between {
  justify-content: space-between;
}
.gap-4 {
  gap: 1rem;
}

/* Grid */
.grid {
  display: grid;
}
.grid-cols-2 {
  grid-template-columns: repeat(2, 1fr);
}
.grid-cols-3 {
  grid-template-columns: repeat(3, 1fr);
}

/* Text */
.text-center {
  text-align: center;
}
.text-sm {
  font-size: 0.875rem;
}
.text-lg {
  font-size: 1.125rem;
}
.font-bold {
  font-weight: 700;
}
.text-gray-500 {
  color: #6b7280;
}

/* Display */
.block {
  display: block;
}
.hidden {
  display: none;
}
@media (min-width: 768px) {
  .md\:block {
    display: block;
  }
  .md\:hidden {
    display: none;
  }
}

6. Custom Properties (Variables CSS)

:root {
  /* Colores */
  --color-primary: #6366f1;
  --color-primary-hover: #4f46e5;
  --color-primary-light: #eef2ff;
  --color-secondary: #818cf8;
  --color-success: #22c55e;
  --color-danger: #ef4444;
  --color-warning: #f59e0b;
  --color-info: #3b82f6;

  --color-text: #111827;
  --color-text-secondary: #6b7280;
  --color-bg: #ffffff;
  --color-bg-secondary: #f9fafb;
  --color-border: #e5e7eb;

  /* Tipografía */
  --font-sans: "Inter", system-ui, -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", "Fira Code", monospace;

  /* Tamaños */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;

  /* Spacing */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-12: 3rem;
  --space-16: 4rem;

  /* Border */
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
  --radius-full: 9999px;

  /* Shadows */
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);

  /* Transitions */
  --transition-fast: 150ms ease;
  --transition-base: 200ms ease;
  --transition-slow: 300ms ease;

  /* Z-index */
  --z-dropdown: 100;
  --z-modal: 200;
  --z-toast: 300;
}

/* Dark mode */
@media (prefers-color-scheme: dark) {
  :root {
    --color-text: #f9fafb;
    --color-text-secondary: #9ca3af;
    --color-bg: #111827;
    --color-bg-secondary: #1f2937;
    --color-border: #374151;
  }
}

/* Uso */
.button {
  background-color: var(--color-primary);
  color: white;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  transition: background-color var(--transition-fast);
}

.button:hover {
  background-color: var(--color-primary-hover);
}

Tematización con data attributes

[data-theme="dark"] {
  --color-bg: #111827;
  --color-text: #f9fafb;
}

[data-theme="high-contrast"] {
  --color-primary: #0000ff;
  --color-text: #000000;
  --color-bg: #ffffff;
}

@property — Variables Tipadas

@property --hue {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.color-wheel {
  background: hsl(var(--hue), 80%, 50%);
  transition: --hue 0.3s;
}

@property --spacing {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

7. CSS Nesting (nativo)

/* Sin nesting */
.card {
}
.card__title {
}
.card__title--large {
}

/* Con nesting (CSS nativo, soportado en 2025+) */
.card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);

  &__title {
    /* .card__title */
    font-size: var(--text-lg);
    font-weight: 600;

    &--large {
      /* .card__title--large */
      font-size: var(--text-xl);
    }
  }

  &__body {
    color: var(--color-text-secondary);
  }

  &:hover {
    box-shadow: var(--shadow-md);
  }

  @media (min-width: 768px) {
    padding: var(--space-6);
  }
}

8. Cascade Layers (@layer)

/* Definir orden de capas */
@layer reset, base, components, utilities;

/* Reset layer */
@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }
}

/* Base layer */
@layer base {
  body {
    font-family: var(--font-sans);
    color: var(--color-text);
    background: var(--color-bg);
    line-height: 1.6;
  }

  h1,
  h2,
  h3 {
    line-height: 1.2;
    font-weight: 700;
  }
}

/* Components layer */
@layer components {
  .card {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
  }
}

/* Utilities layer (mayor prioridad) */
@layer utilities {
  .text-center {
    text-align: center;
  }
  .mt-4 {
    margin-top: var(--space-4);
  }
}

/* Importar dentro de capa */
@import url("reset.css") layer(reset);

Orden de prioridad: utilities > components > base > reset

Minimal Reset

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  margin: 0;
  line-height: 1.5;
}

img,
video {
  max-width: 100%;
  height: auto;
  display: block;
}

9. Container Queries

/* Definir container */
.card-container {
  container-type: inline-size;
  container-name: card;
}

/* Query */
@container card (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 200px 1fr;
    gap: 1rem;
  }

  .card__title {
    font-size: var(--text-xl);
  }
}

@container card (max-width: 399px) {
  .card {
    display: flex;
    flex-direction: column;
  }

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

/* Container shorthand */
.container {
  container: card / inline-size;
}

/* Container style queries */
@container card style(--featured: true) {
  .card {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-md);
  }
}

10. Selectores Modernos

:has() (CSS Parent Selector)

/* Card que contiene una imagen */
.card:has(img) {
  grid-template-rows: auto 1fr;
}

/* Formulario con error */
.form-group:has(:invalid) {
  border-color: var(--color-danger);
}

.form-group:has(:focus) {
  border-color: var(--color-primary);
}

/* Navbar con menú abierto */
.navbar:has(.menu--open) {
  background: var(--color-bg-secondary);
}

/* Tabla con selección */
tr:has(input:checked) {
  background: var(--color-primary-light);
}

/* Hermano siguiente de un elemento con clase */
.card.featured + .card:not(.featured) {
  opacity: 0.8;
}

Otros selectores útiles

/* :where() - especificidad cero */
:where(.card, .panel, .box) {
} /* (0,0,0) */

/* :is() - especificidad del más específico */
:is(.card, #header, .panel) {
} /* (1,0,0) por #header */

/* :not() */
.button:not(.button--primary) {
}
.card:not(:has(img)) {
}

/* :focus-visible (solo foco teclado) */
.button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* :focus-within (container con focus) */
.form-group:focus-within {
  border-color: var(--color-primary);
}

/* :target (elemento con #hash en URL) */
#section:target {
  animation: highlight 2s ease;
}

/* :placeholder-shown */
input:placeholder-shown {
  border-color: var(--color-border);
}

/* :empty */
.card:empty {
  display: none;
}

11. Funciones CSS Modernas

/* clamp() - valor fluido entre min y max */
font-size: clamp(1rem, 0.75rem + 0.5vw, 1.125rem);
padding: clamp(1rem, 3vw, 3rem);
width: clamp(300px, 50%, 800px);

/* min() / max() */
width: min(100%, 1200px); /* responsive + max-width */
padding: max(1rem, 2vw); /* padding mínimo */
grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr));

/* calc() */
width: calc(100% - 2rem);
height: calc(100vh - var(--header-height));
font-size: calc(1rem + 0.5vw);

/* abs() - CSS Values 5 */
margin: abs(-10px); /* 10px */

/* round() - redondear a unidad */
width: round(50.7px, 5px); /* 50px */

12. @supports Feature Queries

Detectar soporte del navegador antes de usar propiedades modernas.

/* Grid support */
@supports (display: grid) {
  .layout {
    display: grid;
  }
}

/* Container queries support */
@supports (container-type: inline-size) {
  .card {
    container-type: inline-size;
  }
}

/* Nesting support */
@supports (selector(&)) {
  .card {
    & .title {
    }
  }
}

Combinaciones Lógicas

/* AND */
@supports (display: grid) and (container-type: inline-size) {
}

/* OR */
@supports (display: grid) or (display: flex) {
}

/* NOT */
@supports not (display: grid) {
}

13. Tipografía

Sistema tipográfico

body {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--color-text);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1 {
  font-size: clamp(1.75rem, 1rem + 2vw, 2.5rem);
  line-height: 1.2;
}
h2 {
  font-size: clamp(1.5rem, 1rem + 1.5vw, 2rem);
  line-height: 1.25;
}
h3 {
  font-size: clamp(1.25rem, 1rem + 0.5vw, 1.5rem);
  line-height: 1.3;
}

p {
  max-width: 70ch;
} /* Legibilidad óptima */

@font-face

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter.woff2") format("woff2");
  font-weight: 400 700; /* Variable font range */
  font-display: swap; /* FOIT evita invisible */
  font-style: normal;
  unicode-range: U+0000-00FF; /* Latin básico */
}

/* Variable fonts */
body {
  font-variation-settings:
    "wght" 400,
    "wdth" 100;
}

h1 {
  font-variation-settings:
    "wght" 700,
    "wdth" 85;
}

14. Animaciones y Transiciones

Transiciones

.button {
  background-color: var(--color-primary);
  transition:
    background-color 150ms ease,
    transform 150ms ease,
    box-shadow 150ms ease;
}

.button:hover {
  background-color: var(--color-primary-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

Animaciones @keyframes

.fade-in {
  animation: fadeIn 300ms ease-out both;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.slide-up {
  animation: slideUp 300ms ease-out both;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Animaciones más complejas */
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

@keyframes skeleton {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}

.spinner {
  animation: spin 1s linear infinite;
}

.skeleton {
  background: linear-gradient(90deg, #eee 25%, #f5f5f5 50%, #eee 75%);
  background-size: 200% 100%;
  animation: skeleton 1.5s ease-in-out infinite;
}

Propiedades de animación

.element {
  animation-name: fadeIn;
  animation-duration: 300ms;
  animation-timing-function: ease-out;
  animation-delay: 0ms;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-fill-mode: both; /* Mantiene estado final */
  animation-play-state: running;
}

/* Shorthand */
.element {
  animation: fadeIn 300ms ease-out 0ms 1 normal both;
}

Animación basada en scroll (Scroll Timeline)

/* CSS Scroll Timeline (experimental 2026+) */
@keyframes fade-in-scroll {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.reveal {
  animation: fade-in-scroll linear;
  animation-timeline: view();
  animation-range: entry 0% entry 100%;
}

View Transitions API (SPA)

/* Navegación entre páginas */
@keyframes slide-from-right {
  from {
    transform: translateX(100%);
  }
}

@keyframes slide-to-left {
  to {
    transform: translateX(-100%);
  }
}

::view-transition-old(root) {
  animation: slide-to-left 300ms ease;
}

::view-transition-new(root) {
  animation: slide-from-right 300ms ease;
}

Reduced Motion

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

15. Responsive Design

Imágenes Responsive

img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Mantener aspecto */
.img-square {
  aspect-ratio: 1 / 1;
}
.img-video {
  aspect-ratio: 16 / 9;
}
.img-portrait {
  aspect-ratio: 3 / 4;
}

/* Object fit */
.img-cover {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.img-contain {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

Contenedores

.container {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: 1rem;
}

@media (min-width: 768px) {
  .container {
    padding-inline: 1.5rem;
  }
}

@media (min-width: 1024px) {
  .container {
    padding-inline: 2rem;
  }
}

16. Logical Properties

/* En lugar de physical properties */
/* ❌ Physical */
.element {
  margin-left: 1rem;
  margin-right: 1rem;
  padding-top: 1rem;
  padding-bottom: 1rem;
  border-left: 1px solid;
  width: 100%;
  height: 100%;
}

/* ✅ Logical (respetan dirección del texto) */
.element {
  margin-inline: 1rem; /* margin-left + margin-right */
  padding-block: 1rem; /* padding-top + padding-bottom */
  border-inline-start: 1px solid; /* border-left */
  inline-size: 100%; /* width */
  block-size: 100%; /* height */
  inset-inline: 1rem; /* left + right */
  inset-block: 1rem; /* top + bottom */
  text-align: start; /* left en LTR, right en RTL */
}

/* Para RTL automático */
[dir="rtl"] .element {
  /* Las logical properties se adaptan solas */
}

17. Dark Mode y Preferencias del Sistema

/* Modo oscuro */
:root {
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #111827;
    --color-text: #f9fafb;
  }
}

/* Alto contraste */
@media (prefers-contrast: high) {
  :root {
    --color-primary: #0000ff;
    --color-border: #000;
  }

  .card {
    border-width: 2px;
  }
}

@media (prefers-contrast: less) {
  :root {
    --color-text-secondary: #6b7280;
  }
}

/* Transparencia reducida */
@media (prefers-reduced-transparency: reduce) {
  .modal-backdrop {
    background: rgba(0, 0, 0, 0.8);
  }

  .card {
    box-shadow: none;
  }
}

/* Datos reducidos */
@media (prefers-reduced-data: reduce) {
  .hero-image {
    background-image: none;
  }
}

Forzar modo en el DOM

<meta name="color-scheme" content="light dark" />
<html data-theme="dark"></html>

18. Scroll

Scroll Snap

.scroll-container {
  scroll-snap-type: x mandatory;
  overflow-x: auto;
  display: flex;
  gap: 1rem;
}

.scroll-item {
  scroll-snap-align: start;
  scroll-snap-stop: always; /* Detiene en cada item */
  flex: 0 0 100%;
}

/* Scroll snap vertical */
.vertical-snap {
  scroll-snap-type: y proximity; /* Snap suave, no forzado */
  overflow-y: scroll;
  height: 100vh;
}

.vertical-snap > section {
  scroll-snap-align: start;
  height: 100vh;
}

Comportamiento de scroll

html {
  scroll-behavior: smooth; /* Smooth scroll en anclas */
}

/* Prevenir overscroll */
body {
  overscroll-behavior: none; /* Evita el rebote en móviles */
}

.modal-content {
  overscroll-behavior: contain; /* Scroll contenido dentro del modal */
}

Scrollbar

.custom-scrollbar {
  scrollbar-width: thin; /* Firefox: auto | thin | none */
  scrollbar-color: var(--color-primary) transparent; /* Firefox */
}

/* WebKit */
.custom-scrollbar::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.custom-scrollbar::-webkit-scrollbar-track {
  background: transparent;
}

.custom-scrollbar::-webkit-scrollbar-thumb {
  background: var(--color-border);
  border-radius: 3px;
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background: var(--color-text-secondary);
}

scrollbar-gutter

/* Evitar layout shift cuando aparece scrollbar */
.container {
  scrollbar-gutter: stable; /* Reserva espacio para scrollbar */
}

19. Accesibilidad CSS

Focus

/* Focus visible (obligatorio en interactivos) */
:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Quitar outline solo cuando :focus-visible aplica */
:focus:not(:focus-visible) {
  outline: none;
}

Ocultar visualmente (pero accesible)

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

Skip link

.skip-link {
  position: absolute;
  top: -100%;
  left: 0;
  z-index: var(--z-toast);
  padding: 0.5rem 1rem;
  background: var(--color-primary);
  color: white;
  text-decoration: none;
}

.skip-link:focus {
  top: 0;
}

20. Selectores y Cascada

Especificidad

/* (0,0,1) - elemento */
p {
}

/* (0,1,0) - clase (preferido) */
.card {
}

/* (0,2,0) - dos clases */
.card.featured {
}

/* (1,0,0) - ID (evitar para estilos) */
#header {
}

/* (1,1,1) - ID + clase + elemento - evitar */
div#header .nav {
}

!important (solo excepciones)

/* ❌ Evitar */
.button {
  background: red !important;
}

/* ✅ Mejor: mayor especificidad */
.button--emergency {
  background: red;
}

/* ✅ Aceptable: utilities con !important */
@layer utilities {
  .hidden {
    display: none !important;
  }
}

21. Efectos Visuales

Filtros

.blur {
  filter: blur(4px);
}
.grayscale {
  filter: grayscale(100%);
}
.sepia {
  filter: sepia(60%);
}
.brightness {
  filter: brightness(1.2);
}
.contrast {
  filter: contrast(150%);
}
.drop-shadow {
  filter: drop-shadow(0 4px 4px rgba(0, 0, 0, 0.2));
}

/* Backdrop filter (efecto vidrio) */
.glass {
  background: rgba(255, 255, 255, 0.5);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* Combinar filtros */
.card-image:hover {
  filter: brightness(1.1) contrast(110%);
}

Clip-path

.clip-circle {
  clip-path: circle(50%);
}

.clip-polygon {
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
}

.clip-curve {
  clip-path: ellipse(50% 60% at 50% 40%);
}

Máscaras

.mask-fade {
  mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
}

.mask-text {
  mask-image: url("/mask.svg");
  -webkit-mask-image: url("/mask.svg");
}

3D Transforms

.card-3d {
  perspective: 1000px;
}

.card-3d:hover {
  transform: rotateY(10deg) rotateX(5deg);
  transition: transform 300ms ease;
}

/* Card flip */
.flip-card {
  perspective: 1000px;
}

.flip-card-inner {
  transition: transform 600ms;
  transform-style: preserve-3d;
}

.flip-card:hover .flip-card-inner {
  transform: rotateY(180deg);
}

.flip-card-front,
.flip-card-back {
  backface-visibility: hidden;
  position: absolute;
  inset: 0;
}

.flip-card-back {
  transform: rotateY(180deg);
}

Colores Modernos

color-mix()

.element {
  background: color-mix(in srgb, #6366f1, white 20%);
  border: 2px solid color-mix(in srgb, var(--color-primary), black 10%);
}

oklch()

.element {
  color: oklch(70% 0.15 250);
  background: oklch(95% 0.02 250);
}

light-dark()

:root {
  --bg: light-dark(#ffffff, #1a1a1a);
  --text: light-dark(#000000, #ffffff);
}

body {
  background: var(--bg);
  color: var(--text);
}

22. Performance CSS

content-visibility

/* Lazy render de secciones fuera del viewport */
.section-below-fold {
  content-visibility: auto;
  contain-intrinsic-size: 0 500px; /* Altura estimada */
}

contain

/* Aislar subárbol para optimizar re-render */
.widget {
  contain: layout style paint;
}

.card-container {
  contain: content; /* layout + style + paint */
}

will-change

/* Solo para animaciones problemáticas */
.animated-element {
  will-change: transform, opacity;
  /* NO usar en demasiados elementos */
}

GPU-accelerated properties

/* ✅ Preferir para animaciones (solo composite) */
transform: translateX(100px);
opacity: 0.5;
filter: blur(4px);

/* ❌ Evitar (causan reflow + repaint) */
width: 50%;
height: auto;
margin-left: 100px;
top: 50px;

23. Print Styles

@media print {
  /* Ocultar no imprimible */
  nav,
  footer,
  .sidebar,
  .ads,
  .no-print {
    display: none !important;
  }

  /* Ajustar página */
  body {
    font-size: 12pt;
    line-height: 1.5;
    color: #000;
    background: #fff;
  }

  /* Links visibles */
  a[href]::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
    color: #666;
  }

  /* Evitar saltos de página */
  h1,
  h2,
  h3,
  h4 {
    page-break-after: avoid;
  }

  p,
  li {
    orphans: 3;
    widows: 3;
  }
}

24. Prohibiciones

  • NO usar !important salvo utilities o excepciones justificadas
  • ❌ No usar IDs para estilos (#header { }) - usar clases
  • ❌ No anidar más de 3 niveles (Sass/SCSS, o usar nesting nativo)
  • ❌ No usar px para tipografía (usar rem / clamp())
  • ❌ No inline styles (style="...")
  • ❌ No float para layout (usar Flexbox o Grid)
  • ❌ No position: absolute para layout general
  • ❌ No animar width, height, top, left (causan reflow)
  • ❌ No dejar !important en producción sin justificación documentada
  • ❌ No usar colores hardcodeados (usar custom properties)
  • ❌ No usar @import dentro de CSS (usar <link> en HTML)
  • ❌ No abusar de will-change (solo en elementos con problemas comprobados)
  • ❌ No usar * { box-sizing: border-box } sin considerar third-party widgets
  • ❌ No poner imágenes sin max-width: 100%

25. Referencias

Nota: Para HTML, ver HTML Nota: Para JavaScript, ver JavaScript Nota: Para Git, ver Git


Última actualización: 2026-07

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.