'Dynamically set background color based on value from DB
The db stores hex values which will then be used to set the background color of the div.
How can I pass the value which is coming through from the DB to the css class?
id| page_category| color
1 | ABC | 38963c
2 | XYZ | 269bee
JS
pageCategories.map((category, i) => {
<div className={`pp_color`} />
}
CSS
.pp_color1 {
background:???;
}
Solution 1:[1]
It's not 100% clear what your code holds (as values) but here's an example of how to set the background color of an element through JavaScript.
Variablizing CSS isn't possible with JavaScript (meaning you can't bind a JavaScript variable to a css property value in your css file). But, you can certainly apply css via JavaScript
const testDiv = document.getElementById('test');
let counter = 0;
const colors = ['red', 'green', 'blue', 'orange', 'yellow'];
document.getElementById('btnChangeColor').addEventListener('click', e => {
if (counter === colors.length) { counter = 0; }
testDiv.style.background = colors[counter];
counter++;
});
<div id="test">Hello World</div>
<button id="btnChangeColor">Change the Color</button>
So, if you can imagine taking that response from you db, getting the hex values (colors) and applying them with similar logic, you should be good to go.
Solution 2:[2]
Your solution would sort of work but you would have to know all the colors in advance and then build all the css classes to reference in your JS.
If you want a dynamic solution and if you are happy to go with CSS Variables you could just set the background color to be a variable then change it with your hex value with Javascript like so.
CSS
:root {
--main-bg-color: brown;
}
JS
const dbValues = {
'main-bg-color': '#00ff00'
}
Object.entries(dbValues).map(([key, value]) => {
document.documentElement.style.setProperty(`--${key}`, value)
})
Just a heads up that CSS variables aren't fully supported but there is a css-vars-ponyfill if that helps.
And one last point. You can also dynamically change variables in the scope of an element without effecting the class globally. More info here
Solution 3:[3]
It's a bit "hacky" and you can use the combination of callback refs, and CSS variables to pull it off.
function Page({ id, category, backgroundColor }) {
const setRef = node => {
// ? Set the background value here from the ref.
node.style.setProperty("--background-color", `#${backgroundColor}`);
};
return (
<div ref={setRef} className="box pp_color1">
<h1>BOX {id}</h1>
<p>Category: {category}</p>
</div>
);
}
const pageInfos = ["1 | ABC | 38963c", "2 | XYZ | 269bee"];
function App() {
const pageElements = pageInfos.map(pageInfo => {
const [id, category, backgroundColor] = pageInfo.split(" | ");
return (
<Page
key={id}
id={id}
category={category}
backgroundColor={backgroundColor}
/>
);
});
return <div className="App">{pageElements}</div>;
}
The CSS would require the variable, which is defined as following.
/* Declare the variable */
:root {
--background-color: #fff;
}
.box {
... redacted for brevity
}
/* This is where you set the background color */
.pp_color1 {
background-color: var(--background-color);
}
The code above will render,
Other suggestion
You might want to actually check out other CSS in JS solutions such as styled-components or emotion. CSS in JS accel in such dynamic behavior as those libraries accepts props
, which you can dynamically set
As an example, check out this styled-component
code.
const Button = styled.button`
/* ? using props as background */
background: ${props => props.primary ? "palevioletred" : "white"};
color: ${props => props.primary ? "white" : "palevioletred"};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
It accepts the background as a prop and sets it accordingly.
You can apply the same concept for your code by creating a styled component, which accepts backgroundColor
const Box = styled.div`
?
background-color: ${props => props.backgroundColor};
width: 200px;
height: 200px;
border: 1px solid rgba(43, 16, 16, 0.247);
margin: 2rem;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
`;
and use it like,
?
<Box key={id} backgroundColor={`#${backgroundColor}`}>
<h1>BOX {id}</h1>
<p>Category: {category}</p>
</Box>;
The Styled Component version is also in the sandbox mentioned above.
Solution 4:[4]
The following answer is much more complex than what is needed to solve the posed question. However, it is how I solved my problem that is based on the same basic principle. I have dynamic data being displayed on a page and need to change the colors based on the value.
Based on this information: How to use HSL color in CSS
This is what I came up with.
- Define a base style class: I have mine named .runColor
- Write a jquery function to iterate through all document elements with the class. Find the data points to base the color change on. In my case, I have them in the title of the div. My function is called after the html is returned from my ajax call to the controller.(MVC application)
- Create the new colors
- Update the desired attribute
I do see the error that my code creates. Not sure what it is at the moment. No time to debug. If you know what it is, feel free to change and let me know. ;)
function SetRunColors() {
$.each($('.runColor'),
function(i, val) {
var rtArray = val.title.split(': ');
var titleArray = val.title.split('Prod %:');
var percentage = titleArray[1].replace('%', '');
var rt = rtArray[1];
rt = rt.split(' ');
var rtVal = rt[0];
var dec = parseFloat(percentage) / 100;
var newH = 120 * dec;
if (rtVal < 1) {
newH = 120;
}
var color = "hsl(" + newH + ",100% , 50% )";
var lightColor = "hsl(" + newH + ",100% , 85% )";
var background = "linear-gradient(" + lightColor + "," + color + ")";
$(this).css('background', background);
});
.runColor, .runScrap {
background-color: green;
text-align: center;
height: 30px;
background: linear-gradient(lightgreen, green);
-webkit-box-shadow: #B4B5B5 1px 1px 1px;
-moz-box-shadow: #B4B5B5 1px 1px 1px;
box-shadow: #B4B5B5 1px 1px 1px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
<div id="2" class="runColor" title="
Start of First : 9.9
Start: 4/20/2022 08:00:12
Stop: 4/20/2022 08:10:07
Prod (Bakers Dozen): 27
Prod %: 45.37%" style="margin-top: 10px; float: left; width: 27px; background: linear-gradient(rgb(255, 248, 179), rgb(255, 231, 0));"></div><div id="3" class="runColor" title="
Running : 10.0
Start: 4/20/2022 08:10:07
Stop: 4/20/2022 08:20:05
Prod (Bakers Dozen): 60
Prod %: 100.48%" style="margin-top: 10px; float: left; width: 27px; background: linear-gradient(rgb(179, 255, 179), rgb(0, 255, 2));"></div><div id="4" class="runColor" title="
Running : 9.9
Start: 4/20/2022 08:20:05
Stop: 4/20/2022 08:30:00
Prod (Bakers Dozen): 43
Prod %: 72.24%" style="margin-top: 10px; float: left; width: 27px; background: linear-gradient(rgb(221, 255, 179), rgb(142, 255, 0));"></div><div id="5" class="runColor" title="
Running : 10.1
Start: 4/20/2022 08:30:00
Stop: 4/20/2022 08:40:05
Prod (Bakers Dozen): 55
Prod %: 90.87%" style="margin-top: 10px; float: left; width: 28px; background: linear-gradient(rgb(192, 255, 179), rgb(47, 255, 0));"></div><div id="6" class="runColor" title="
Running : 9.9
Start: 4/20/2022 08:40:05
Stop: 4/20/2022 08:50:00
Prod (Bakers Dozen): 45
Prod %: 75.63%" style="margin-top: 10px; float: left; width: 27px; background: linear-gradient(rgb(216, 255, 179), rgb(124, 255, 0));"></div><div id="7" class="runColor" title="
Running : 10.1
Start: 4/20/2022 08:50:00
Stop: 4/20/2022 09:00:05
Prod (Bakers Dozen): 52
Prod %: 85.93%" style="margin-top: 10px; float: left; width: 28px; background: linear-gradient(rgb(200, 255, 179), rgb(72, 255, 0));"></div><div id="8" class="runColor" title="
Running : 9.9
Start: 4/20/2022 09:00:05
Stop: 4/20/2022 09:10:00
Prod (Bakers Dozen): 40
Prod %: 67.24%" style="margin-top: 10px; float: left; width: 27px; background: linear-gradient(rgb(229, 255, 179), rgb(167, 255, 0));"></div><div id="9" class="runColor" title="
Running : 10.1
Start: 4/20/2022 09:10:00
Stop: 4/20/2022 09:20:05
Prod (Bakers Dozen): 59
Prod %: 97.49%" style="margin-top: 10px; float: left; width: 28px; background: linear-gradient(rgb(182, 255, 179), rgb(13, 255, 0));"></div><div id="10" class="runColor" title="
Running : 9.9
Start: 4/20/2022 09:20:05
Stop: 4/20/2022 09:30:00
Prod (Bakers Dozen): 50
Prod %: 84.04%" style="margin-top: 10px; float: left; width: 27px; background: linear-gradient(rgb(203, 255, 179), rgb(81, 255, 0));"></div><div id="11" class="runColor" title="
Running : 10.1
Start: 4/20/2022 09:30:00
Stop: 4/20/2022 09:40:05
Prod (Bakers Dozen): 37
Prod %: 61.15%" style="margin-top: 10px; float: left; width: 28px; background: linear-gradient(rgb(238, 255, 179), rgb(198, 255, 0));"></div><div id="12" class="runColor" title="
Running : 9.9
Start: 4/20/2022 09:40:05
Stop: 4/20/2022 09:50:00
Prod (Bakers Dozen): 0
Prod %: 0.00%" style="margin-top: 10px; float: left; width: 27px; background: linear-gradient(rgb(255, 179, 179), rgb(255, 0, 0));"></div><div id="13" class="runColor" title="
Running : 10.1
Start: 4/20/2022 09:50:00
Stop: 4/20/2022 10:00:06
Prod (Bakers Dozen): 20
Prod %: 33.05%" style="margin-top: 10px; float: left; width: 28px; background: linear-gradient(rgb(255, 229, 179), rgb(255, 169, 0));"></div><div id="14" class="runColor" title="
Running : 2.8
Start: 4/20/2022 10:00:06
Stop: 4/20/2022 10:02:53
Prod (Bakers Dozen): 20
Prod %: 119.44%" style="margin-top: 10px; float: left; width: 7px; background: linear-gradient(rgb(179, 255, 208), rgb(0, 255, 99));"></div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mwilson |
Solution 2 | stwilz |
Solution 3 | |
Solution 4 | midohioboarder |