Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

406
Vistas
Cómo anular la configuración de esquema de color preferido de css

Estoy implementando un modo oscuro, ya que macOS, Windows e iOS han introducido modos oscuros.

Existe una opción nativa para Safari, Chrome y Firefox, que utiliza la siguiente regla de medios CSS:

 @media (prefers-color-scheme: dark) { body { color:#fff; background:#333333 }

Esto identificará automáticamente los sistemas que están configurados en modos oscuros y aplicará las reglas CSS adjuntas.

Sin embargo; aunque los usuarios pueden tener su sistema configurado en modo oscuro, puede darse el caso de que prefieran el tema claro o predeterminado de un sitio web específico. También está el caso de los usuarios de Microsoft Edge que (todavía) no admiten @media (prefers-color-scheme . Para obtener la mejor experiencia de usuario, quiero asegurarme de que estos usuarios puedan alternar entre los modos oscuro y predeterminado para esos casos.

¿Hay algún método para que esto se pueda realizar, posiblemente con HTML 5 o JavaScript? ¡Incluiría el código que probé, pero no he podido encontrar ninguna información sobre cómo implementar esto en absoluto!

over 4 years ago · Santiago Trujillo
10 Respuestas
Responde la pregunta

0

No estoy seguro, por qué todas las respuestas son tan complicadas.

Use variables CSS, establezca un valor predeterminado y un valor opuesto en una consulta de medios, como de costumbre. También establezca los valores en dos clases. Implemente un conmutador que alterna estas clases cuando se hace clic.

De forma predeterminada, el modo claro/oscuro automático se utiliza según el esquema de color del sistema. Usando los interruptores de palanca al modo manual claro/oscuro. Vuelve al modo claro/oscuro automático después de actualizar la página (o eliminar la clase del elemento html).

 // toggle to switch classes between .light and .dark // if no class is present (initial state), then assume current state based on system color scheme // if system color scheme is not supported, then assume current state is light function toggleDarkMode() { if (document.documentElement.classList.contains("light")) { document.documentElement.classList.remove("light") document.documentElement.classList.add("dark") } else if (document.documentElement.classList.contains("dark")) { document.documentElement.classList.remove("dark") document.documentElement.classList.add("light") } else { if (window?.matchMedia('(prefers-color-scheme: dark)').matches) { document.documentElement.classList.add("light") } else { document.documentElement.classList.add("dark") } } }
 /* automatic/manual light mode */ :root, :root.light { --some-value: black; --some-other-value: white; } /* automatic dark mode */ /* ❗️ keep the rules in sync with the manual dark mode below! */ @media (prefers-color-scheme: dark) { :root { --some-value: white; --some-other-value: black; } } /* manual dark mode /* ❗️ keep the rules in sync with the automatic dark mode above! */ :root.dark { --some-value: white; --some-other-value: black; } /* use the variables */ body { color: var(--some-value); background-color: var(--some-other-value); }
 <button onClick="toggleDarkMode()">Toggle</button> <h1>Hello world!</h1>

over 4 years ago · Santiago Trujillo Denunciar

0

Creo que la mejor manera es seguir de forma nativa la configuración del sistema a menos que el usuario diga lo contrario.

Crear botón en tu html. Y luego vincule el interruptor de tres posiciones con js. Con guardar en LocalStorage del navegador.

Y, finalmente, estilice su elemento interruptor.

 document.addEventListener("DOMContentLoaded", function(event) { switchTheme('.theme-switch'); }); function switchTheme(selector) { const switches = document.querySelectorAll(selector); // let colorTheme = localStorage.getItem('colorTheme') || 'system'; //commented to avoid security issue let colorTheme = 'system'; function changeState() { // localStorage.setItem('colorTheme', colorTheme); //commented to avoid security issue document.documentElement.setAttribute('data-theme', colorTheme); } changeState(); switches.forEach(el => { el.addEventListener('click', () => { switch (colorTheme) { case 'dark': colorTheme = 'light'; break case 'light': colorTheme = 'system'; break default: colorTheme = 'dark'; } changeState(); }); }); }
 :root:not([data-theme="dark"]) { --bg: #fff; } @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --bg: #000; } } :root[data-theme="dark"] { /* yep, you'll need to duplicate styles from above */ --bg: #000; } body { background: var(--bg); } .theme-switch:after { content: ': system'; } :root[data-theme="dark"] .theme-switch:after { content: ': dark'; } :root[data-theme="light"] .theme-switch:after { content: ': light'; }
 <button class="theme-switch">Color scheme</button>

over 4 years ago · Santiago Trujillo Denunciar

0

TL;RD


index.html

 <!DOCTYPE html> <html> <head> <meta name="color-scheme" content="light dark"> <link rel="stylesheet" type="text/css" href="style.css" /> </head> <body> <h1>Hello world</h1> <button id="toggle">Toggle</button> <script type="text/javascript" src="script.js"></script> </body> </html>

style.css

 .dark-mode { background-color: black; color: white; } .light-mode { background-color: white; color: black; } @media (prefers-color-scheme: dark) { body { background-color: black; color: white; } }

script.js

 /** * Adopt: * the theme from the system preferences; or * the previously stored mode from the `localStorage` */ var initialMode = "light"; var prefersColorSchemeDark = window.matchMedia( "(prefers-color-scheme: dark)" ); if ( prefersColorSchemeDark.matches ) { initialMode = "dark"; } if( localStorage.getItem("initialMode") == null ) { localStorage.setItem("initialMode", initialMode); } if( localStorage.getItem("currentMode") == null ) { localStorage.setItem("currentMode", initialMode); } else { let currentMode = localStorage.getItem("currentMode"); if ( currentMode == "dark" && currentMode != initialMode ) { document.body.classList.add("dark-mode"); } else if ( currentMode == "light" && currentMode != initialMode ) { document.body.classList.add("light-mode"); } } /** * Process the toggle then store to `localStorage` */ document.getElementById('toggle').addEventListener("click", function() { var initialMode = localStorage.getItem("initialMode"); let currentMode = localStorage.getItem("currentMode"); if ( currentMode == "dark" && currentMode == initialMode ) { document.body.classList.add("light-mode"); localStorage.setItem("currentMode", "light"); } else if ( currentMode == "light" && currentMode == initialMode ) { document.body.classList.add("dark-mode"); localStorage.setItem("currentMode", "dark"); } else if ( currentMode != initialMode ) { document.body.removeAttribute("class"); if( currentMode == "dark" ) { localStorage.setItem("currentMode", "light"); } else { localStorage.setItem("currentMode", "dark"); } } }, false);

Detalles

Esta solución supone que:

  1. Lo que sea que se configuró en las preferencias del sistema (modo oscuro/claro), se reconocerá como el modo inicial
  2. Desde el modo inicial, el usuario final puede alternar manualmente entre el modo oscuro o el modo claro
  3. Si el sistema no tiene una función de modo oscuro, se usará el tema del modo claro
  4. Cualquiera que sea el tema (modo oscuro/claro) que el usuario final configuró manualmente anteriormente, ese será el nuevo modo inicial en la página siguiente recargar/actualizar
over 4 years ago · Santiago Trujillo Denunciar

0

Sugiero usar SCSS. Puedes hacerlo más simple.

 /* Dark Mode */ @mixin darkMixin { body { color: #fff; background: #000; } } @media (prefers-color-scheme: dark) { @include darkMixin; } .darkMode { @include darkMixin; } .lightMode { body { color: #000; background: #fff; } }

Y puede alternar/anular usando JavaScript. (En este ejemplo, usé jQuery para que pareciera fácil)

 // dark $('html').removeClass('lightMode').addClass('darkMode') // light $('html').removeClass('darkMode').addClass('lightMode')

Si quieres detectar, este es el código basado en el de JimmyBanks.

 function isDarkTheme(){ let theme="light"; //default to light if (localStorage.getItem("theme")){ if (localStorage.getItem("theme") == "dark") theme = "dark" } else if (!window.matchMedia) { return false } else if (window.matchMedia("(prefers-color-scheme: dark)").matches) { theme = "dark" } return theme=='dark' }

Para guardar el tema actual, simplemente use localStorage:

 localStorage.setItem("theme", 'light') or localStorage.setItem("theme", 'dark')
over 4 years ago · Santiago Trujillo Denunciar

0

Ninguno de los anteriores me convenía. Decidí abordar el problema desde una perspectiva diferente. El año es 2021.


Las siguientes ofertas:

  • Respeto de las preferencias del sistema.
  • Las preferencias del sistema se sobrescriben.
  • Respeto del esquema de color de las barras de desplazamiento.
  • Soporte de navegador universal. (Final de vida IE, 17 de agosto de 2021 🥳✌️🎉)

Cuando echa un vistazo a la página Web Docs de MDN para ver prefers-color-scheme , puede leer lo siguiente:

La función multimedia CSS de esquema de color preferido se utiliza para detectar si el usuario ha solicitado un tema de color claro u oscuro. [...]

light Indica que el usuario ha notificado que prefiere una interfaz que tiene un tema claro o no ha expresado una preferencia activa .

Por lo tanto, para todos los navegadores, el prefers-color-scheme está configurado en light o no es compatible de forma predeterminada.

Uno de los problemas que tuve con la respuesta aceptada fue que los cambios no afectaban el color de la barra de desplazamiento. Esto se puede manejar usando la propiedad CSS color-scheme junto con el pseudo elemento :root .

El otro problema que tuve fue que, si un usuario cambiara la configuración del sistema a claro u oscuro, el sitio web no se vería afectado y generaría coincidencias erróneas entre ambos estilos. Podemos arreglar ese comportamiento acoplando window.matchMedia( '(prefers-color-scheme: light)' ) a un detector de eventos onchange .

Aquí está el guión final.

 (() => { var e = document.getElementById("tglScheme"); window.matchMedia("(prefers-color-scheme: dark)").matches ? (document.head.insertAdjacentHTML("beforeend", '<style id="scheme">:root{color-scheme:dark}</style>'), document.body.classList.add("dark"), e && (e.checked = !0), window.localStorage.getItem("scheme") && (document.getElementById("scheme").remove(), document.head.insertAdjacentHTML("beforeend", '<style id="scheme">:root{color-scheme:light}</style>'), document.body.classList.remove("dark"), e && (e.checked = !1)), e && e.addEventListener("click", () => { e.checked ? (document.getElementById("scheme").remove(), document.head.insertAdjacentHTML("beforeend", '<style id="scheme">:root{color-scheme:dark}</style>'), document.body.classList.add("dark"), localStorage.removeItem("scheme")) : (document.getElementById("scheme").remove(), document.head.insertAdjacentHTML("beforeend", '<style id="scheme">:root{color-scheme:light}</style>'), document.body.classList.remove("dark"), localStorage.setItem("scheme", 1)); })) : (document.head.insertAdjacentHTML("beforeend", '<style id="scheme">:root{color-scheme:light}</style>'), e && (e.checked = !1), window.localStorage.getItem("scheme") && (document.getElementById("scheme").remove(), document.head.insertAdjacentHTML("beforeend", '<style id="scheme">:root{color-scheme:dark}</style>'), document.body.classList.add("dark"), e && (e.checked = !0)), e && e.addEventListener("click", () => { e.checked ? (document.getElementById("scheme").remove(), document.head.insertAdjacentHTML("beforeend", '<style id="scheme">:root{color-scheme:dark}</style>'), document.body.classList.add("dark"), localStorage.setItem("scheme", 1)) : (document.getElementById("scheme").remove(), document.head.insertAdjacentHTML("beforeend", '<style id="scheme">:root{color-scheme:light}</style>'), document.body.classList.remove("dark"), localStorage.removeItem("scheme")); })); })(), window.matchMedia("(prefers-color-scheme: light)").addEventListener("change", () => { location.reload(), localStorage.removeItem("scheme"); });

Para el lado de CSS, usamos los valores predeterminados de propiedades personalizadas variables con el color oscuro en la primera posición. Podemos definir todos los colores oscuros necesarios a través del elemento :root.

 :root body.dark { --app-bg-dark: #131313; --app-tx-dark: #f8f9fa; } body{ background-color: var( --app-bg-dark, white ); color: var( --app-tx-dark, black ); } /* if dark mode isn't set, fallback to light. */

Y para el html, una simple casilla de verificación <input id="tglScheme" type="checkbox"> .

Finalmente aquí está el Codepen https://codepen.io/amarinediary/full/yLgppWW .

Codepen sobrescribe location.reload() por lo que no podrá probar la actualización en vivo en el cambio del sistema. No dude en probarlo en su host local.

over 4 years ago · Santiago Trujillo Denunciar

0

Aquí hay una respuesta que respeta el prefers-color-scheme preferido predeterminado, y solo entonces le permite alternar a través localStorage . Esto ahorra el segundo que se tarda en averiguar el esquema predeterminado a través de JS, además la gente usará el esquema predeterminado incluso sin JS.

No me gusta tener que declarar un estilo predeterminado (opté por Oscuro) y luego volver a declararlo como una clase llamada dark-mode pero es inevitable .

Tenga en cuenta que este foro parece bloquear localStorage , por lo que debe probar el código en otro lugar.

 var theme, prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)"); if (prefersDarkScheme.matches) theme = document.body.classList.contains("light-mode") ? "light" : "dark"; else theme = document.body.classList.contains("dark-mode") ? "dark" : "light"; localStorage.setItem("theme", theme); function toggle() { var currentTheme = localStorage.getItem("theme"); if (currentTheme == "dark") document.body.classList.toggle("light-mode"); else if (currentTheme == "light") document.body.classList.toggle("dark-mode"); }
 .dark-mode {color: white; background-color: black} .dark-mode a:link {color: DeepSkyBlue} .light-mode {color: black; background-color: white} .light-mode a:link {color: green} @media (prefers-color-scheme: dark) { body {color: white; background-color: black} a:link {color: DeepSkyBlue} }
 <button onclick="toggle()">Toggle Light/Dark Mode</button>

over 4 years ago · Santiago Trujillo Denunciar

0

He determinado una solución adecuada, es la siguiente:

CSS utilizará variables y temas:

 // root/default variables :root { --font-color: #000; --link-color:#1C75B9; --link-white-color:#fff; --bg-color: rgb(243,243,243); } //dark theme [data-theme="dark"] { --font-color: #c1bfbd; --link-color:#0a86da; --link-white-color:#c1bfbd; --bg-color: #333; }

A continuación, las variables se llaman cuando es necesario, por ejemplo:

 //the redundancy is for backwards compatibility with browsers that do not support CSS variables. body { color:#000; color:var(--font-color); background:rgb(243,243,243); background:var(--bg-color); }

JavaScript se usa para identificar qué tema ha establecido el usuario, o si ha anulado el tema de su sistema operativo, así como para alternar entre los dos, esto se incluye en el encabezado antes de la salida del <body>...</body> :

 //determines if the user has a set theme function detectColorScheme(){ var theme="light"; //default to light //local storage is used to override OS theme settings if(localStorage.getItem("theme")){ if(localStorage.getItem("theme") == "dark"){ var theme = "dark"; } } else if(!window.matchMedia) { //matchMedia method not supported return false; } else if(window.matchMedia("(prefers-color-scheme: dark)").matches) { //OS theme setting detected as dark var theme = "dark"; } //dark theme preferred, set document with a `data-theme` attribute if (theme=="dark") { document.documentElement.setAttribute("data-theme", "dark"); } } detectColorScheme();

Este javascript se usa para alternar entre las configuraciones, no es necesario incluirlo en el encabezado de la página, pero puede incluirse donde sea

 //identify the toggle switch HTML element const toggleSwitch = document.querySelector('#theme-switch input[type="checkbox"]'); //function that changes the theme, and sets a localStorage variable to track the theme between page loads function switchTheme(e) { if (e.target.checked) { localStorage.setItem('theme', 'dark'); document.documentElement.setAttribute('data-theme', 'dark'); toggleSwitch.checked = true; } else { localStorage.setItem('theme', 'light'); document.documentElement.setAttribute('data-theme', 'light'); toggleSwitch.checked = false; } } //listener for changing themes toggleSwitch.addEventListener('change', switchTheme, false); //pre-check the dark-theme checkbox if dark-theme is set if (document.documentElement.getAttribute("data-theme") == "dark"){ toggleSwitch.checked = true; }

finalmente, la casilla de HTML para alternar entre temas:

 <label id="theme-switch" class="theme-switch" for="checkbox_theme"> <input type="checkbox" id="checkbox_theme"> </label>

Mediante el uso de variables CSS y JavaScript, podemos determinar automáticamente el tema de los usuarios, aplicarlo y permitir que el usuario lo anule también. [En el momento actual de escribir esto (2019/06/10), solo Firefox y Safari admiten la detección automática de temas]

over 4 years ago · Santiago Trujillo Denunciar

0

Tomó la solución provista por @JimmyBanks y 1) convirtió la casilla de verificación en un botón de texto alternante, y 2) agregó el cambio automático de tema en el cambio de tema del sistema operativo.

CSS no ha cambiado, con temas claros almacenados en :root y temas oscuros almacenados en [data-theme="dark"] :

 :root { --color_01: #000; --color_02: #fff; --color_03: #888; } [data-theme="dark"] { --color_01: #fff; --color_02: #000; --color_03: #777; }

El <head> JS tiene algunas ediciones, incluidas algunas omisiones y el movimiento de la declaración data-theme al bloque JS posterior:

 var theme = 'light'; if (localStorage.getItem('theme')) { if (localStorage.getItem('theme') === 'dark') { theme = 'dark'; } } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) { theme = 'dark'; }

Y aquí está la edición del segundo bloque de JS, además del HTML relacionado. theme_switch alterna el tema, mientras que theme_OS actualiza automáticamente el tema del sitio con cambios en el tema del sistema operativo.

 var theme; function theme_apply() { 'use strict'; if (theme === 'light') { document.getElementById('theme_readout').innerHTML = 'Dark'; document.documentElement.setAttribute('data-theme', 'light'); localStorage.setItem('theme', 'light'); } else { document.getElementById('theme_readout').innerHTML = 'Light'; document.documentElement.setAttribute('data-theme', 'dark'); localStorage.setItem('theme', 'dark'); } } theme_apply(); function theme_switch() { 'use strict'; if (theme === 'light') { theme = 'dark'; } else { theme = 'light'; } theme_apply(); } var theme_OS = window.matchMedia('(prefers-color-scheme: light)'); theme_OS.addEventListener('change', function (e) { 'use strict'; if (e.matches) { theme = 'light'; } else { theme = 'dark'; } theme_apply(); });
 <a onclick="theme_switch()">Theme: <span id="theme_readout"></span></a>

Por favor, hágamelo saber si tiene alguna sugerencia para mejorar!

over 4 years ago · Santiago Trujillo Denunciar

0

Puede usar mi elemento personalizado <dark-mode-toggle> que inicialmente se adhiere a la configuración del prefers-color-scheme del usuario, pero que también permite al usuario anularlo (permanente o temporalmente). La alternancia funciona con archivos CSS separados o con clases que se alternan. El README tiene ejemplos para ambos enfoques.

over 4 years ago · Santiago Trujillo Denunciar

0

My Solution (3 opciones en entradas de radio: dark, system, light) adaptación de JimmyBanks y Meanderbilt Solution:

es un poco detallado, supongo, pero me costó un poco entenderlo

 const themeSwitches = document.querySelectorAll('[data-color-theme-toggle]') function removeColorThemeLocalStorage() { localStorage.removeItem('color-theme') } function saveColorTheme(colorTheme) { if (colorTheme === 'system') { removeColorThemeLocalStorage() return } localStorage.setItem('color-theme', colorTheme) } function applyColorTheme() { const localStorageColorTheme = localStorage.getItem('color-theme') const colorTheme = localStorageColorTheme || null if (colorTheme) { document.documentElement.setAttribute('data-color-theme', colorTheme) } } function themeSwitchHandler() { themeSwitches.forEach(themeSwitch => { const el = themeSwitch if (el.value === localStorage.getItem('color-theme')) { el.checked = true } el.addEventListener('change', () => { if (el.value !== 'system') { saveColorTheme(el.value) applyColorTheme(el.value) } else { removeColorThemeLocalStorage() document.documentElement.removeAttribute('data-color-theme') } }) }) applyColorTheme() } document.addEventListener('DOMContentLoaded', () => { themeSwitchHandler() applyColorTheme() })
 html { --hue-main: 220; --color-text: hsl(var(--hue-main), 10%, 25%); --color-text--high-contrast: hsl(var(--hue-main), 10%, 5%); --color-link: hsl(var(--hue-main), 40%, 30%); --color-background: hsl(var(--hue-main), 51%, 98.5%); } @media (prefers-color-scheme: dark) { html.no-js { --color-text: hsl(var(--hue-main), 5%, 60%); --color-text--high-contrast: hsl(var(--hue-main), 10%, 80%); --color-link: hsl(var(--hue-main), 60%, 60%); --color-background: hsl(var(--hue-main), 10%, 12.5%); } } [data-color-theme='dark'] { --color-text: hsl(var(--hue-main), 5%, 60%); --color-text--high-contrast: hsl(var(--hue-main), 10%, 80%); --color-link: hsl(var(--hue-main), 60%, 60%); --color-background: hsl(var(--hue-main), 10%, 12.5%); }
 <div class="color-scheme-toggle" role="group" title="select a color scheme"> <p>saved setting: <span class="theme-readout">...</span></p> <input type="radio" name="scheme" id="dark" value="dark" aria-label="dark color scheme"> <label for="dark">dark</label> <input type="radio" name="scheme" id="system" value="system" aria-label="system color scheme" checked="system"> <label for="system">system</label> <input type="radio" name="scheme" id="light" value="light" aria-label="light color scheme"> <label for="light">light</label> </div>
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda