Obtengo un background-color de una API, nombre de variable settings.brand_color . Quiero usar esa variable en el elemento html. No puedo usar el atributo de style porque estoy usando :before del selector en mi aplicación. Quiero pasar esa variable API en mi archivo css y usarla en mi :before pseudoselector.
JSX
<input id={languageLabel} type="radio" name="language-select" value={languageLabel} // defaultChecked={index === 0} onChange={() => { onLanguageChange(language, languageLabel); }} className="focus:ring-0 mr-5 my-18p default-style radio__input" /> <div className="radio__radio"></div>CSS
.radio__radio { width: 24px; height: 24px; background-color: #d8d8d8; border-radius: 50%; box-sizing: border-box; padding: 6px; margin-right: 20px; z-index: 1; } .radio__radio::after { content: ""; width: 100%; height: 100%; display: block; background: #f28b46; border-radius: 50%; transform: scale(0); z-index: 9; }Si bien no puede establecer directamente el estilo de un pseudo elemento en JS, puede establecer una variable CSS y esto puede ser recogido por la configuración de clase para el pseudo elemento.
.radio__radio { width: 24px; height: 24px; background-color: #d8d8d8; border-radius: 50%; box-sizing: border-box; padding: 6px; margin-right: 20px; z-index: 1; --bg: #f28b46; /* ADDED for initial condition */ } .radio__radio::after { content: ""; width: 100%; height: 100%; display: block; background: var(--bg); border-radius: 50%; transform: scale(0); z-index: 9; }Luego, en tu Javascript cuando obtengas un nuevo color de fondo:
document.querySelector('.radio__radio').style.setProperty('--bg', newvalue);o, por supuesto, seleccione todos esos botones de radio y cambie para cada uno si eso es lo que se requiere.
El problema es que no puedes manipular pseudoelementos en javascript; sin embargo, todavía hay un par de opciones para manipularlos por efecto dominó.
Opción 1: como sugirió A Haworth, use una variable CSS.
Opción 2: si sabes que solo habrá unos pocos colores diferentes; entonces podría alternar una clase indicando de qué color debería ser. Por ejemplo, si configura el CSS en una estructura similar a esta:
.radio__radio { width: 24px; height: 24px; background-color: #d8d8d8; border-radius: 50%; box-sizing: border-box; padding: 6px; margin-right: 20px; z-index: 1; } .radio__radio::after { content: ""; width: 100%; height: 100%; display: block; border-radius: 50%; transform: scale(0); z-index: 9; } .radio__radio.green::after{ background-color: #000066 /* Silly colour as an example */ } .radio__radio.blue::after{ background-color: #006600 /* Silly colour as an example */ } .radio__radio.red::after{ background-color: #660000 /* Silly colour as an example */ }Entonces tu javascript
var d = document.getElementsByClassName("radio__radio"); /* This way supports older browsers */ d.className += " otherclass";O si usa img jQuery
$('.radio__radio').addClass('green').removeClass('red').removeClass('blue');No conozco ninguna forma de que inyecte directamente una variable de tiempo de ejecución desde su API sin usar javascript como intermediario; puede haber una manera de hacerlo con Blazor, pero aún no lo he encontrado.
Puede usar las propiedades personalizadas de CSS como variables para los colores, usando la clase : :root :
:root { --brand-color: #f28b46; } .radio__radio { width: 24px; height: 24px; background-color: #d8d8d8; border-radius: 50%; box-sizing: border-box; padding: 6px; margin-right: 20px; z-index: 1; } .radio__radio::after { content: ""; width: 100%; height: 100%; display: block; background: var(--brand-color); border-radius: 50%; // transform: scale(0); z-index: 9; } <div class="radio__radio"></div> Y al obtener el color de la marca de la API, cree una etiqueta de estilo y actualice el color de la marca :root .
Nota: la última variable :root anulará cualquier variable :root anterior, por lo que debe asegurarse de crear el <style> con el color de la marca después de su archivo CSS inicial.
:root { --brand-color: yellow; // will be overridden } :root { --brand-color: red; // that's the color that will show }Tengo la idea de que estás usando reaccionar, así que puedes hacer esto así:
const [brandColor, setBrandColor] = useState(); useEffect( () => { fetchBrandColorFromAPI().then(brandColor => setBrandColor(brandColor)); }, [])Y luego en el renderizador:
{brandColor && <style dangerouslySetInnerHTML={{ __html: ` :root { --brand-color: ${brandColor} }`}} /> } <!DOCTYPE html> <html> <head> <title> How to define colors as variables in CSS? </title> <style> :root { --primary-color: rgb(15, 157, 88); --secondary-color: rgb(255, 255, 255); } .first { width: 50%; padding: 40px 0px; margin: 10px 0px; text-align: center; /* Apply color using CSS var */ background-color: var(--primary-color); color: var(--secondary-color); } .second { width: 50%; padding: 40px 0px; text-align: center; /* Apply color using CSS var */ background-color: var(--primary-color); color: var(--secondary-color); } </style> </head> <body> <div class="first"> <h1>Stackoverflow</h1> </div> <div class="second"> <h1>gyan-js</h1> </div> </body> </html>Soy nuevo en React, así que proporcionaré la respuesta con Vannila JS.
:root{ --myColor: #545454; }color: var(--myColor);myColor porque no tiene efecto excepto la variable en sí porque lo usaremos en JS para cambiarlo.document.documentElement para establecer el color de la variable css myColor con el color que obtenemos de la API // I couldn't find a fake API response giving a Color, so this function mocks the API which gives the color string after 2 seconds. let getColorFromAPI = new Promise((resolve) => { setTimeout(function() { resolve('#FFFFFF') }, 2000) }); async function main() { console.log("The Existing Color is: ", getComputedStyle(document.documentElement).getPropertyValue('--mainColor')) console.log('Getting the Color from the API... ') let newColor = await getColorFromAPI // Get the color from API console.log('The New Color is: ', newColor) document.documentElement.style.setProperty('--mainColor', newColor) // Changing the color of the CSS variable } main() :root { --mainColor: #545454; } .buttonElement { background-color: var(--mainColor); } <button class="buttonElement">See the Color of this button</button>Para terminar:
document.documentElement.style.setPropertyTambién puede crear una clase ficticia con solo el color de fondo y agregarlo al elemento, ya que el navegador calcula el estilo con la declaración de estilo CSS más reciente.
Espero que esto ayude.
Tuve un problema similar una vez que realmente resolví usando otro elemento div en lugar del pseudo elemento. Pido disculpas si eso no funciona para su caso de uso específico, ya que dijo que quería usar el pseudo elemento. Sin embargo, dado que parece que tiene acceso a JS, JSX y CSS, podría ser algo que podría considerar.
Los pseudo elementos antes y después son casi equivalentes a los elementos div colocados como el primer o último elemento secundario del elemento principal, por lo que se agrega otro div como este
<div className="radio__radio"> <div className="radio__radio__after" style={{ backgroundColor: apiColor || '#f28b46' }} ></div> </div>y cambiando tu segundo selector de CSS así
.radio__radio__after { content: ""; width: 100%; height: 100%; display: block; border-radius: 50%; transform: scale(0); z-index: 9; }permitir que el accesorio de estilo controle el color de fondo debería funcionar, aunque es posible que deba realizar algunos ajustes leves en el CSS o JSX.
La mejor y más fácil forma posible es agregar estilo en el código JSX.
<input id={languageLabel} type="radio" name="language-select" value={languageLabel} // defaultChecked={index === 0} onChange={() => { onLanguageChange(language, languageLabel); }} className="focus:ring-0 mr-5 my-18p default-style radio__input" />Simplemente agregue esta parte a su archivo JSX
<style> {` .radio__radio::before { background-color: ${settings.brand_color} } `} </style>