Logotipo de Bitdoze

Modo Oscuro en Carrd: Cómo Añadir un Alternador de Tema (Guía 2026)

Añade un alternador de modo oscuro en Carrd con CSS y JS para copiar y pegar. Evita el destello blanco, sigue el tema del sistema y recuerda la elección del usuario. Guía paso a paso.

Dragos

Actualizado Publicado 60 min de lectura

Modo Oscuro en Carrd: Cómo Añadir un Alternador de Tema (Guía 2026)

El modo oscuro pasó de ser una preferencia minoritaria a una expectativa generalizada. Muchos visitantes navegan de noche con el móvil ya en modo oscuro, y una web blanca y brillante les golpea como una linterna en la cara.

Añadir un alternador de modo oscuro en Carrd da a los visitantes el control sobre su experiencia. Cambian a lo que resulte más cómodo para sus ojos, y el sitio recuerda su elección para la próxima vez. Esta guía trae CSS y JS listos para copiar y pegar que además evitan el destello blanco al cargar y siguen el tema del sistema hasta que el visitante toma partido.

Carrd.co

Algunos tutoriales de Carrd:

Encontrarás la lista completa de plugins, temas y tutoriales de Carrd en mi web carrdme.com, incluidos un widget de pestañas y un widget de acordeón ya listos para usar.

Por Qué Añadir Modo Oscuro a tu Sitio Carrd

Cinco razones, una línea cada una:

  1. Menos fatiga visual: las interfaces oscuras son más cómodas con poca luz.
  2. Ahorro de batería: en pantallas OLED los píxeles oscuros consumen menos energía.
  3. Preferencia del usuario: mucha gente simplemente prefiere una interfaz oscura. Ofrecer la opción es un gesto de respeto barato.
  4. Sensibilidad a la luz: algunos visitantes necesitan de verdad interfaces más oscuras, y para ellos el modo oscuro es una función de accesibilidad.
  5. Expectativa moderna: todas las grandes apps ya traen un tema oscuro.

El modo oscuro ya no es una novedad. Los visitantes buscan el interruptor, y cuando no lo encuentran se van a un sitio que sí lo tenga.

Requisitos Previos: Necesitas Carrd Pro Standard para los Embeds

Todo este tutorial funciona con el elemento Embed de Carrd. Dos cosas lo dejan resuelto antes de pegar código.

  • Cuenta Carrd Pro Standard o superior (los Embeds no están en el plan gratis ni en Pro Lite)
  • Un sitio publicado, o listo para publicar (los embeds no se renderizan en el editor)
  • Unos 10 minutos
  • Sin otras herramientas, sin paso de compilación, sin archivos externos

Los Embeds necesitan Carrd Pro Standard o superior

El elemento Embed requiere Pro Standard o superior. Pro Lite cuesta 9 $/año para 3 sitios y no incluye embeds. Pro Standard cuesta 19 $/año para 10 sitios (39 $/año para 25 sitios) y añade embeds, formularios, dominios personalizados y analítica. Pro Plus cuesta 49 $/año para 25 sitios con ajustes avanzados. Si solo quieres seguir la guía, inicia la prueba Pro de 7 días. Sin tarjeta. Precios comprobados en carrd.co/pro en septiembre de 2026; revísalos antes de comprar.

Los Embeds no aparecen en el editor

La documentación de Carrd lo dice sin rodeos: el elemento Embed no muestra nada en el editor, así que tienes que publicar el sitio para verlo en acción. Si tu editor parece vacío después de pegar el código de abajo, nada está roto. Publica y luego prueba.

Para añadir un embed, haz clic en el signo + y elige Embed. En una página muy cargada también puedes usar el Panel de Elementos (More Actions → Elements…), añadido en agosto de 2026, para encontrar y gestionar elementos sin tener que buscarlos por todo el diseño.

Es el mismo patrón de embed con código personalizado que se usa en la guía para añadir un aviso de cookies a tu sitio Carrd. Una vez has hecho un embed, el resto son trabajos de copiar y pegar.

Cómo Funciona el Modo Oscuro en Carrd

Carrd no tiene modo oscuro integrado. Revisé de nuevo la documentación y el changelog en septiembre de 2026: sigue sin existir una función de cambio de tema. El código personalizado es el único camino.

El enfoque es el de siempre:

  1. Un atributo data-theme en la raíz de la página (light o dark)
  2. Variables CSS para los colores, intercambiadas por [data-theme="dark"]
  3. Un botón alternador que invierte el atributo
  4. localStorage para que la elección sobreviva a las recargas
  5. prefers-color-scheme como valor por defecto antes de que el visitante elija nada

La mejora frente a un snippet ingenuo es el patrón de dos embeds. El Embed n.º 1 es un pequeño bootstrap en un embed Hidden → Head que establece data-theme antes de que la página se pinte. El Embed n.º 2 contiene la interfaz del alternador y el manejador del clic (Inline o Hidden → Body End).

¿Por qué dos embeds?

Un embed Inline único aplica el tema desde JavaScript después del primer pintado. Los usuarios con el sistema en oscuro ven un destello blanco en cada carga. El bootstrap del head se ejecuta antes del pintado, así que el primer frame ya lleva el tema correcto.

Dos cronologías comparadas. La fila A es el enfoque de un solo embed. La fila B es el enfoque de dos embeds que usa esta guía:

A. Un solo embed en líneaPeticiónPrimer pintado(blanco)JS correOscuro aplicado(tarde)Destello blanco visible para usuarios de modo oscuroB. Patrón de dos embeds (bootstrap en Hidden → Head)PeticiónEl script del head fijadata-themePrimer pintado(ya oscuro)Sin destello: el tema está activo antes del primer frame

Orden de resolución del tema, de mayor a menor prioridad:

  1. Una elección guardada en localStorage bajo la clave theme (el visitante pulsó el alternador en algún momento)
  2. La preferencia del SO/navegador vía prefers-color-scheme: dark
  3. El modo claro como valor por defecto fijo
¿localStorage(‘theme’) fijado?síUsa la elección guardadanoprefers-color-scheme:¿dark?sídarknolight

Las páginas más grandes aguantan bien. Los sitios con varias secciones construidos con el elemento Page de Carrd mantienen el tema automáticamente. Todo es un único documento, así que data-theme y localStorage persisten entre secciones.

Los scripts del head se ejecutan antes del pintado por especificación, así que la solución es sólida en principio. El orden exacto de inyección de Carrd aun así merece una confirmación en tu propio sitio publicado. Mira la checklist de pruebas más abajo.

Cómo Añadir Modo Oscuro a Carrd (Paso a Paso)

Dos embeds y luego eliges uno de los tres estilos de alternador. Cada bloque de abajo se puede copiar y pegar.

Paso 1: Añade un Embed en Head para Evitar el Destello Blanco

Haz clic en el signo + (o More Actions → Elements…) y añade un elemento Embed. Pon Type en Code, Style en Hidden y Location en Head.

Embed: CodeStyleInlineHiddenLocationHeadBody TopBody EndStyle: Hidden con Location: Head (la corrección del FOUC depende de ello)

Style: Hidden, Location: Head (no Inline)

La corrección del destello blanco necesita un embed Hidden dirigido al Head. Una configuración solo Inline lo hace imposible, porque el código Inline se renderiza en el cuerpo de la página después del pintado. Usaremos ambos estilos: Hidden → Head para el bootstrap, e Inline (o Hidden → Body End) para el alternador.

Pega esto en el campo Code:

html
<script>
(function () {
  var t;
  try { t = localStorage.getItem('theme'); } catch (e) {}
  if (!t) t = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
  document.documentElement.setAttribute('data-theme', t);
})();
</script>
<style>
  :root { color-scheme: light; }
  [data-theme="dark"] { color-scheme: dark; }
</style>

Qué hace:

  • Lee localStorage.theme dentro de try/catch, de modo que los modos privados que lanzan error al acceder al almacenamiento no rompan la página
  • Recurre a prefers-color-scheme: dark cuando el visitante nunca eligió un tema
  • Establece data-theme en la raíz del documento antes del primer pintado
  • Emite color-scheme: light|dark para que los controles de formulario nativos, las barras de scroll y el autocompletado sigan el tema (color-scheme está soportado en Chrome/Edge 81+, Firefox 96+, Safari 13+)

Carrd no inyecta ninguna pista de color-scheme en los sitios publicados. Revisé el HTML en bruto de un ejemplo publicado en septiembre de 2026: no hay nada. El snippet lo establece por sí mismo. No des por hecho que la plataforma lo hace por ti.

Comprueba: publica y abre el sitio en una ventana de incógnito en un equipo o móvil configurado en modo oscuro. La página debería cargar oscura sin destello blanco. Si aún ves un destello, el embed de head falta, está mal ubicado, o estás viendo una página en caché (fuerza la recarga).

Paso 2: Añade el Embed del Alternador de Modo Oscuro

Añade un segundo elemento Embed. Pon Type en Code. Para Style, elige Inline (para ver dónde queda en el diseño) o Hidden con Location: Body End (el alternador es position: fixed, así que acaba en el mismo sitio de todos modos).

Editor de Carrd con el elemento Embed añadido y Type en Code

La captura muestra la ubicación Head del Paso 1. Para este segundo embed, elige Inline, o mantén Hidden y cambia la ubicación a Body End.

En el editor el embed sigue invisible. Publica para verlo. Luego elige uno de los tres estilos de alternador de abajo y pégalo en este segundo embed.

El bloque <style> de cada opción lleva los colores oscuros, y se carga con este segundo embed en el body. Si aún pillas un breve frame claro en una conexión lenta, recorta la parte <style>…</style> de tu opción elegida y pégala en el embed de Head del Paso 1, debajo del código existente. El botón y el <script> se quedan aquí.

Opción 1: Botón Alternador Flotante

Mi opción por defecto. Un pequeño botón fijo en la esquina, funciona con cualquier diseño y no estorba. Esta versión alterna un único emoji sol/luna, mantiene aria-pressed sincronizado, limita las transiciones para que el primer pintado sea instantáneo, respeta prefers-reduced-motion, sobrevive a los errores de almacenamiento en modo privado, sigue los cambios de tema del sistema en vivo y añade una transición de fundido cruzado con view-transition donde el navegador lo soporta.

html
<style>
  /* Light mode (default) colors */
  :root {
    --dm-bg-primary: #ffffff;
    --dm-bg-secondary: #f8fafc;
    --dm-text-primary: #1e293b;
    --dm-text-secondary: #64748b;
    --dm-border: #e2e8f0;
    --dm-accent: #3b82f6;
  }

  /* Dark mode colors */
  [data-theme="dark"] {
    --dm-bg-primary: #0f172a;
    --dm-bg-secondary: #1e293b;
    --dm-text-primary: #f1f5f9;
    --dm-text-secondary: #94a3b8;
    --dm-border: #334155;
    --dm-accent: #60a5fa;
  }

  /* Apply colors to Carrd elements */
  [data-theme="dark"] body,
  [data-theme="dark"] #wrapper,
  [data-theme="dark"] #main,
  [data-theme="dark"] section {
    background-color: var(--dm-bg-primary) !important;
  }

  [data-theme="dark"] h1,
  [data-theme="dark"] h2,
  [data-theme="dark"] h3,
  [data-theme="dark"] h4,
  [data-theme="dark"] p,
  [data-theme="dark"] span,
  [data-theme="dark"] li,
  [data-theme="dark"] a:not(.button) {
    color: var(--dm-text-primary) !important;
  }

  /* Style form inputs */
  [data-theme="dark"] input,
  [data-theme="dark"] textarea,
  [data-theme="dark"] select {
    background-color: var(--dm-bg-secondary) !important;
    color: var(--dm-text-primary) !important;
    border-color: var(--dm-border) !important;
  }

  /* Smooth transitions, scoped so the first paint is instant */
  @media (prefers-reduced-motion: no-preference) {
    [data-theme-ready] body,
    [data-theme-ready] #wrapper,
    [data-theme-ready] #main,
    [data-theme-ready] section,
    [data-theme-ready] h1,
    [data-theme-ready] h2,
    [data-theme-ready] h3,
    [data-theme-ready] h4,
    [data-theme-ready] p,
    [data-theme-ready] span,
    [data-theme-ready] li,
    [data-theme-ready] a:not(.button),
    [data-theme-ready] input,
    [data-theme-ready] textarea {
      transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
    }
  }

  /* Toggle button */
  .theme-toggle {
    position: fixed;
    bottom: 25px;
    left: 25px;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    z-index: 9999;
    background: var(--dm-bg-secondary);
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
    transition: transform 0.2s, background-color 0.3s;
  }

  .theme-toggle:hover {
    transform: scale(1.1);
  }

  .theme-toggle:focus-visible {
    outline: 2px solid var(--dm-accent);
    outline-offset: 2px;
  }
</style>

<button class="theme-toggle" id="themeToggle" aria-label="Toggle dark mode" aria-pressed="false">
  <span aria-hidden="true">☀️</span>
</button>

<script>
(function () {
  var toggle = document.getElementById('themeToggle');

  function apply(theme) {
    document.documentElement.setAttribute('data-theme', theme);
    document.documentElement.setAttribute('data-theme-ready', '');
    toggle.setAttribute('aria-pressed', theme === 'dark' ? 'true' : 'false');
    toggle.firstElementChild.textContent = theme === 'dark' ? '🌙' : '☀️';
  }

  function current() {
    return document.documentElement.getAttribute('data-theme') || 'light';
  }

  apply(current());

  toggle.addEventListener('click', function () {
    var next = current() === 'dark' ? 'light' : 'dark';
    try { localStorage.setItem('theme', next); } catch (e) {}
    if (document.startViewTransition) {
      document.startViewTransition(function () { apply(next); });
    } else {
      apply(next);
    }
  });

  window.matchMedia('(prefers-color-scheme: dark)')
    .addEventListener('change', function (e) {
      var saved = null;
      try { saved = localStorage.getItem('theme'); } catch (err) {}
      if (!saved) apply(e.matches ? 'dark' : 'light');
    });
})();
</script>

Notas sobre las partes clave:

  • Las transiciones solo se aplican después de que data-theme-ready se establezca en la raíz, así que el tema inicial no se anima.
  • document.startViewTransition es una mejora progresiva (Chrome/Edge 111+, Firefox 144+, Safari 18+). Los navegadores sin soporte simplemente cambian al instante.
  • El listener de cambio del sistema solo actúa cuando el visitante no tiene elección guardada. Una vez que pulsa el alternador, su elección manda hasta que la borre.
  • Los emoji se renderizan de forma distinta en Windows y en Android antiguos. Si quieres iconos con píxeles consistentes, sustituye los caracteres ☀️ / 🌙 por formas SVG en línea de sol y luna.

Comprueba: pulsa el alternador y los colores deberían fundirse. Recarga y el tema debería mantenerse (localStorage.theme contiene light o dark). Navega con Tab hasta el botón y deberías ver el anillo de foco, con aria-pressed cambiando en DevTools → Elements.

Opción 2: Interruptor en la Cabecera

Un interruptor tipo píldora que puedes colocar cerca de la cabecera. Las mismas correcciones compartidas de la Opción 1: tratamiento del texto a:not(.button), transiciones limitadas a [data-theme-ready], try/catch alrededor del almacenamiento y un listener de cambio del sistema.

Una trampa común en snippets antiguos de este patrón: *, *::before, *::after { transition: … }. Eso anima toda la página en el primer pintado y lastra los diseños pesados. La regla de abajo está limitada a propósito. Si toda tu página se anima al cargar, dejaste la regla de transición global.

html
<style>
  /* Light mode colors */
  :root {
    --dm-bg: #ffffff;
    --dm-bg-alt: #f3f4f6;
    --dm-text: #111827;
    --dm-text-muted: #6b7280;
    --dm-border: #e5e7eb;
  }

  /* Dark mode colors */
  [data-theme="dark"] {
    --dm-bg: #111827;
    --dm-bg-alt: #1f2937;
    --dm-text: #f9fafb;
    --dm-text-muted: #9ca3af;
    --dm-border: #374151;
  }

  /* Apply to page */
  [data-theme="dark"] body,
  [data-theme="dark"] #wrapper,
  [data-theme="dark"] #main,
  [data-theme="dark"] section {
    background-color: var(--dm-bg) !important;
  }

  [data-theme="dark"] h1,
  [data-theme="dark"] h2,
  [data-theme="dark"] h3,
  [data-theme="dark"] h4,
  [data-theme="dark"] p,
  [data-theme="dark"] span,
  [data-theme="dark"] li,
  [data-theme="dark"] a:not(.button) {
    color: var(--dm-text) !important;
  }

  [data-theme="dark"] input,
  [data-theme="dark"] textarea {
    background-color: var(--dm-bg-alt) !important;
    color: var(--dm-text) !important;
    border-color: var(--dm-border) !important;
  }

  /* Transitions scoped to post-load state */
  @media (prefers-reduced-motion: no-preference) {
    [data-theme-ready] body,
    [data-theme-ready] #wrapper,
    [data-theme-ready] #main,
    [data-theme-ready] section,
    [data-theme-ready] h1,
    [data-theme-ready] h2,
    [data-theme-ready] h3,
    [data-theme-ready] h4,
    [data-theme-ready] p,
    [data-theme-ready] span,
    [data-theme-ready] li,
    [data-theme-ready] a:not(.button),
    [data-theme-ready] input,
    [data-theme-ready] textarea {
      transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
    }
  }

  /* Toggle switch container */
  .switch-container {
    position: fixed;
    top: 20px;
    right: 20px;
    display: flex;
    align-items: center;
    gap: 10px;
    z-index: 9999;
    background: var(--dm-bg-alt);
    padding: 8px 15px;
    border-radius: 50px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  }

  .switch-label {
    font-size: 18px;
  }

  .switch {
    position: relative;
    width: 56px;
    height: 28px;
  }

  .switch input {
    opacity: 0;
    width: 0;
    height: 0;
  }

  .switch input:focus-visible + .switch-slider {
    outline: 2px solid #3b82f6;
    outline-offset: 2px;
  }

  .switch-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #e5e7eb;
    border-radius: 28px;
    transition: 0.3s;
  }

  .switch-slider:before {
    position: absolute;
    content: "";
    height: 22px;
    width: 22px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    border-radius: 50%;
    transition: 0.3s;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
  }

  input:checked + .switch-slider {
    background-color: #3b82f6;
  }

  input:checked + .switch-slider:before {
    transform: translateX(28px);
  }
</style>

<div class="switch-container">
  <span class="switch-label" aria-hidden="true">☀️</span>
  <label class="switch">
    <input type="checkbox" id="themeSwitch" role="switch" aria-label="Toggle dark mode">
    <span class="switch-slider"></span>
  </label>
  <span class="switch-label" aria-hidden="true">🌙</span>
</div>

<script>
(function () {
  var themeSwitch = document.getElementById('themeSwitch');

  function apply(theme) {
    document.documentElement.setAttribute('data-theme', theme);
    document.documentElement.setAttribute('data-theme-ready', '');
    themeSwitch.checked = (theme === 'dark');
    themeSwitch.setAttribute('aria-checked', theme === 'dark' ? 'true' : 'false');
  }

  function current() {
    return document.documentElement.getAttribute('data-theme') || 'light';
  }

  apply(current());

  themeSwitch.addEventListener('change', function () {
    var next = themeSwitch.checked ? 'dark' : 'light';
    try { localStorage.setItem('theme', next); } catch (e) {}
    apply(next);
  });

  window.matchMedia('(prefers-color-scheme: dark)')
    .addEventListener('change', function (e) {
      var saved = null;
      try { saved = localStorage.getItem('theme'); } catch (err) {}
      if (!saved) apply(e.matches ? 'dark' : 'light');
    });
})();
</script>

El checkbox oculto lleva role="switch" y aria-label="Toggle dark mode", con aria-checked sincronizado. Sin esa etiqueta no tiene nombre accesible.

Opción 3: Alternador de Icono Minimalista

Un pequeño círculo con borde que intercambia sol y luna. Variables de paleta con nombres más ligeros si prefieres ese estilo. Las mismas correcciones compartidas que las otras dos.

html
<style>
  /* Theme colors */
  :root {
    --page-bg: #ffffff;
    --page-bg-alt: #f9fafb;
    --page-text: #18181b;
    --page-text-muted: #71717a;
  }

  [data-theme="dark"] {
    --page-bg: #18181b;
    --page-bg-alt: #27272a;
    --page-text: #fafafa;
    --page-text-muted: #a1a1aa;
  }

  [data-theme="dark"] body,
  [data-theme="dark"] #wrapper,
  [data-theme="dark"] #main,
  [data-theme="dark"] section {
    background-color: var(--page-bg) !important;
  }

  [data-theme="dark"] h1,
  [data-theme="dark"] h2,
  [data-theme="dark"] h3,
  [data-theme="dark"] h4,
  [data-theme="dark"] p,
  [data-theme="dark"] span,
  [data-theme="dark"] li,
  [data-theme="dark"] a:not(.button) {
    color: var(--page-text) !important;
  }

  [data-theme="dark"] input,
  [data-theme="dark"] textarea {
    background-color: var(--page-bg-alt) !important;
    color: var(--page-text) !important;
    border-color: var(--page-text-muted) !important;
  }

  @media (prefers-reduced-motion: no-preference) {
    [data-theme-ready] body,
    [data-theme-ready] #wrapper,
    [data-theme-ready] #main,
    [data-theme-ready] section,
    [data-theme-ready] h1,
    [data-theme-ready] h2,
    [data-theme-ready] h3,
    [data-theme-ready] h4,
    [data-theme-ready] p,
    [data-theme-ready] span,
    [data-theme-ready] li,
    [data-theme-ready] a:not(.button),
    [data-theme-ready] input,
    [data-theme-ready] textarea {
      transition: background-color 0.25s ease, color 0.25s ease;
    }
  }

  /* Minimal toggle */
  .minimal-toggle {
    position: fixed;
    top: 20px;
    right: 20px;
    width: 44px;
    height: 44px;
    border: 2px solid var(--page-text);
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    z-index: 9999;
    transition: transform 0.3s, background-color 0.3s;
  }

  .minimal-toggle:hover {
    background: var(--page-bg-alt);
    transform: rotate(20deg);
  }

  .minimal-toggle:focus-visible {
    outline: 2px solid var(--page-text-muted);
    outline-offset: 2px;
  }

  .minimal-toggle .sun-icon {
    display: block;
  }

  .minimal-toggle .moon-icon {
    display: none;
  }

  [data-theme="dark"] .minimal-toggle .sun-icon {
    display: none;
  }

  [data-theme="dark"] .minimal-toggle .moon-icon {
    display: block;
  }
</style>

<button class="minimal-toggle" id="minimalToggle" aria-label="Toggle dark mode" aria-pressed="false">
  <span class="sun-icon" aria-hidden="true">☀️</span>
  <span class="moon-icon" aria-hidden="true">🌙</span>
</button>

<script>
(function () {
  var minimalToggle = document.getElementById('minimalToggle');

  function apply(theme) {
    document.documentElement.setAttribute('data-theme', theme);
    document.documentElement.setAttribute('data-theme-ready', '');
    minimalToggle.setAttribute('aria-pressed', theme === 'dark' ? 'true' : 'false');
  }

  function current() {
    return document.documentElement.getAttribute('data-theme') || 'light';
  }

  apply(current());

  minimalToggle.addEventListener('click', function () {
    var next = current() === 'dark' ? 'light' : 'dark';
    try { localStorage.setItem('theme', next); } catch (e) {}
    if (document.startViewTransition) {
      document.startViewTransition(function () { apply(next); });
    } else {
      apply(next);
    }
  });

  window.matchMedia('(prefers-color-scheme: dark)')
    .addEventListener('change', function (e) {
      var saved = null;
      try { saved = localStorage.getItem('theme'); } catch (err) {}
      if (!saved) apply(e.matches ? 'dark' : 'light');
    });
})();
</script>

Comprueba (las tres opciones): el Tab del teclado debería llegar al alternador con un anillo de foco visible. Es la parte que la mayoría de snippets se saltan y la que hace el control usable sin ratón.

Personalizar los Colores del Modo Oscuro en Carrd

Las variables CSS de la parte superior de la Opción 1 (y el conjunto --page-* de la Opción 3) son los únicos colores que necesitas tocar.

Variables CSS (usadas en esta guía)

Dos bloques. Valores claros en :root, valores oscuros en [data-theme="dark"]:

css
:root {
  --dm-bg-primary: #ffffff;     /* Main background */
  --dm-bg-secondary: #f8fafc;   /* Secondary background (cards, inputs) */
  --dm-text-primary: #1e293b;   /* Main text color */
  --dm-text-secondary: #64748b; /* Muted text */
  --dm-border: #e2e8f0;         /* Border color */
  --dm-accent: #3b82f6;         /* Accent/link color */
}

[data-theme="dark"] {
  --dm-bg-primary: #0f172a;     /* Dark background */
  --dm-bg-secondary: #1e293b;   /* Slightly lighter dark */
  --dm-text-primary: #f1f5f9;   /* Light text */
  --dm-text-secondary: #94a3b8; /* Muted light text */
  --dm-border: #334155;         /* Dark border */
  --dm-accent: #60a5fa;         /* Lighter accent for contrast */
}

Funciona en todas partes y te da control total sobre cada tema. El resto de la guía asume esta configuración.

Alternativa light-dark()

Define cada color una vez y deja que color-scheme elija el ganador:

css
:root {
  --dm-bg-primary: light-dark(#ffffff, #0f172a);
  --dm-bg-secondary: light-dark(#f8fafc, #1e293b);
  --dm-text-primary: light-dark(#1e293b, #f1f5f9);
  --dm-accent: light-dark(#3b82f6, #60a5fa);
}

Menos CSS, pero solo en navegadores nuevos. El alternador igualmente tiene que invertir color-scheme (el Paso 1 ya lo establece). Usa esto si no te importan las versiones antiguas de Safari.

Soporte de light-dark() en navegadores

Chrome 123+, Firefox 120+, Safari 17.5+ (Baseline 2024, comprobado en septiembre de 2026). Se puede usar ahora que el Paso 1 establece color-scheme. Mantén la versión de variables CSS si necesitas Safari antiguo.

Para más personalización CSS de copiar y pegar en Carrd, mira los diseños personalizados de temporizador de cuenta regresiva en Carrd.

Consejos de Diseño para el Modo Oscuro

Prueba el contraste. El texto debe seguir siendo legible sobre el fondo oscuro. Pasa la paleta por un comprobador de contraste cuando tengas dudas.

No uses negro puro. #000000 es duro a la vista. Usa grises oscuros como #0f172a o #1e293b en su lugar.

Aclara tu color de acento. Los colores que funcionan sobre blanco suelen verse apagados sobre oscuro. #3b82f6 se convierte en #60a5fa en la paleta de arriba por exactamente esa razón.

Revisa cada sección. Recorre toda la página en ambos temas. Algunos elementos necesitarán selectores extra (siguiente sección).

Ten en cuenta las imágenes. Los logos y gráficos diseñados para fondos blancos pueden necesitar una segunda versión, un filtro o un marco sutil.

Elementos e Imágenes Específicos de Carrd

Carrd genera selectores estructurales estables: #wrapper, #main y .inner están presentes en los sitios publicados (verificado en el HTML en bruto de un ejemplo publicado en septiembre de 2026). Los nombres de clase específicos de cada plantilla varían, así que los elementos rebeldes necesitan un apuntado extra.

css
/* Target specific Carrd elements */
[data-theme="dark"] .inner,
[data-theme="dark"] .container,
[data-theme="dark"] [class*="style1"],
[data-theme="dark"] [class*="style2"] {
  background-color: var(--dm-bg-primary) !important;
  color: var(--dm-text-primary) !important;
}

/* Target Carrd buttons (ul.buttons > li > a.button); a:not(.button) above only covers text links */
[data-theme="dark"] .buttons .button {
  background-color: var(--dm-accent) !important;
}

/* Target Carrd icons (ul.icons > li > a > svg) */
[data-theme="dark"] .icons svg {
  filter: brightness(0) invert(1);
}

Varianza entre plantillas

Los nombres de clase style1…style5 difieren según la plantilla, y trucos como [data-theme="dark"] .inner > * { background: transparent !important } pueden borrar los fondos de botones y tarjetas en algunas plantillas. Prueba en la tuya. Si los botones pierden su fondo en modo oscuro, quita esa regla primero. Nada de esto es universal. Verifica cada override en tu página publicada.

Las imágenes de fondo no responden a los overrides de background-color. Si una sección se niega a oscurecer, la culpable es probablemente una imagen de fondo. Cámbiala, o atenúala con una capa superpuesta:

css
[data-theme="dark"] img {
  opacity: 0.9;
  filter: brightness(0.95);
}

/* Or give images a subtle frame */
[data-theme="dark"] img {
  border: 1px solid var(--dm-border);
  border-radius: 8px;
}

Si tienes una cabecera sticky, espera un choque: una barra de cabecera todavía clara en una página por lo demás oscura. La guía del sticky header para Carrd muestra qué selectores tocar para que la barra se oscurezca con el resto.

Posicionar el Botón Alternador

Cambia la posición editando estas propiedades CSS en tu clase del alternador:

Abajo a la izquierda (por defecto en la Opción 1):

css
bottom: 25px;
left: 25px;

Arriba a la derecha:

css
top: 25px;
right: 25px;

Abajo a la derecha:

css
bottom: 25px;
right: 25px;

Sobre el z-index: los snippets usan z-index: 9999 para que el alternador flote sobre el contenido. Eso puede chocar con el botón de menú móvil y los iconos sociales de Carrd. Si el alternador tapa algo pulsable, baja el z-index o mueve el botón a la esquina opuesta. Lo mismo si además tienes un control fijo de volver arriba. Mira nuestra guía para añadir un botón de volver arriba en Carrd y evita que los dos se apilen en una esquina. En diseños móviles en particular, comprueba dos veces que nada quede bajo el alternador después de crear una barra de navegación responsive en Carrd.

Probar y Solucionar Problemas del Alternador de Modo Oscuro en Carrd

Los embeds no renderizan nada en el editor, así que cada comprobación de abajo se hace en el sitio publicado.

  • Publica y luego abre el sitio en una ventana de incógnito en un sistema configurado en oscuro: el tema se aplica sin destello blanco
  • Pulsa el alternador y recarga: la elección persiste en localStorage (clave theme)
  • La consola de DevTools está limpia (sin Uncaught SecurityError de localStorage en modo privado)
  • El Tab del teclado llega al alternador y el anillo de foco es visible
  • aria-pressed (o aria-checked en la Opción 2) cambia en el panel Elements al alternar
  • Sin elección guardada, cambia el tema del SO en vivo: la página lo sigue

Si algo se comporta mal:

El destello blanco sigue apareciendo

El bootstrap del head falta, está en la ubicación equivocada (debe ser Style: Hidden, Location: Head), o estás viendo una copia en caché. Confirma que el embed existe con el estilo y la ubicación correctos, luego fuerza la recarga o prueba en una ventana privada. Verifica también una vez en tu propio sitio publicado que el código del head se ejecuta antes del pintado. El orden de inyección de Carrd merece una única comprobación de extremo a extremo, ya que el editor no te lo muestra. Si el embed de head está bien y queda un destello corto, mueve el bloque <style> del alternador también al embed de head (ver Paso 2).

El alternador hace clic pero nada cambia

Tres sospechosos habituales: un error de script en la consola (pega de nuevo todo el bloque de código; las etiquetas sin cerrar son la causa común), los selectores CSS oscuros que no coinciden con tu plantilla, o el sitio que no se publicó de verdad después de tu edición. Mira la consola primero, luego inspecciona el elemento <html>. data-theme debería cambiar al hacer clic.

Los botones o las tarjetas perdieron su fondo en modo oscuro

Es la regla [data-theme="dark"] .inner > * { background: transparent !important } haciendo de las suyas. Depende de la plantilla y suele ser demasiado agresiva. Quítala y dale a .button y a los contenedores de tarjetas sus propios overrides de fondo en su lugar.

El alternador tapa el menú móvil o los iconos sociales

z-index: 9999 más una posición en esquina se solapa con la interfaz de Carrd en pantallas pequeñas. Baja el z-index, o recoloca el alternador en una esquina libre (ver la sección de posicionamiento). Prueba al ancho de un móvil, no solo en escritorio.

Algunas secciones nunca cambian de color

O la plantilla usa clases styleN que tus selectores no cubren, o el fondo de la sección es una imagen. Inspecciona el elemento, añade su clase al bloque CSS oscuro, y cambia o atenúa las imágenes de fondo. Los iconos SVG en línea también ignoran los overrides de color. Recolóralos con reglas fill/stroke o un filter.

La preferencia no se guarda o hay Uncaught SecurityError en la consola

Los modos de navegación privada pueden bloquear localStorage. El código envuelve cada lectura/escritura en try/catch, así que el alternador sigue funcionando durante la sesión. Simplemente no puede recordar la elección. No hay nada que arreglar; la degradación es intencionada.

Volver atrás

Nada fuera de los dos embeds queda modificado. Borra ambos elementos Embed y publica: el sitio vuelve a su estado original. Para limpiar la preferencia atascada de un visitante, abre DevTools → Application → Local Storage y elimina la clave theme.

FAQ: Preguntas sobre el Modo Oscuro en Carrd

¿Carrd tiene modo oscuro integrado?

No. A septiembre de 2026 no existe ninguna función de cambio de tema en Carrd. Revisé la documentación y el changelog. Un embed de código personalizado es el camino, y esta guía es la vía de copiar y pegar.

¿Por qué mi sitio Carrd parpadea en blanco antes de cargar el modo oscuro?

Eso es FOUC (flash of unstyled content), en este caso un destello del tema equivocado. Un embed Inline único aplica el modo oscuro desde JavaScript después del primer pintado, así que los usuarios de modo oscuro ven blanco primero. El bootstrap Hidden → Head del Paso 1 establece data-theme antes del pintado y elimina el destello.

¿Qué plan de Carrd necesito para el modo oscuro?

Pro Standard (19 $/año para 10 sitios) o superior, porque los Embeds son el mecanismo de entrega. Pro Lite (9 $/año) no tiene embeds en absoluto. Pro Plus (49 $/año) solo merece la pena si necesitas sus ajustes avanzados. Carrd ofrece una prueba Pro gratuita de 7 días sin tarjeta si solo quieres montar esto una vez. Los precios son de septiembre de 2026; revísalos en carrd.co/pro.

¿Funciona el alternador de modo oscuro en un sitio Carrd de varias secciones?

Sí. Las secciones hechas con el elemento Page de Carrd comparten un único documento, así que data-theme y localStorage persisten mientras los visitantes se mueven. Un alternador de modo oscuro en Carrd cubre todo el sitio. Si además quieres una acción flotante de la misma familia de botones fijos, añade un botón de chat de WhatsApp a Carrd.

Prueba Carrd.co

Conclusión

El modo oscuro se espera a estas alturas, sobre todo por los visitantes que navegan de noche. El montaje completo son dos embeds y un snippet de alternador. Unos 10 minutos si pegas con cuidado. Empieza con la Opción 1 (el botón flotante) si no sabes qué estilo encaja. Funciona con cualquier diseño y no estorba.

Un par de pasos siguientes una vez el alternador esté en marcha: