John Luke Garofalo
John Luke Garofalo

Reputation: 140

Dynamically set div colors in sass/css from html(.erb)

I'm having trouble finding the best way to do this. I want to store the primary and secondary colors of objects in my database, then I want to display a divider using the two colors dynamically.

For instance...

enter image description here

Notice the black parts of the two divs

Most of the html/css solutions use css' :before & :after pseudo selectors to add the black part of the two divs. (Checkout code posted below). My initial thought is that I want to be able to pass the colors to the css/scss to set the before and after. After a little research, I realized that you can't do :before/:after via inline styles, which I would've said was an ugly solution anyway.

I'm more comfortable in React css in js, where this is a really simple task. I am also open to scrapping this html/css aspect and doing it differently since it seems overcomplicated with the way that I'm going about it.

Any help would be great! Thank you so much.

.tcd-primary {
  min-height: 100px;
  position: relative;
  width: calc(50% - 30px);
  float: left;

  &:after {
    content: '';
    position: absolute;
    top: 0;
    width: 0;
    height: 0;
    left: 100%;
    border-right: 50px solid transparent;
    border-top: 100px solid black; /* this should be the primary color instead of black */
  }
}

.tcd-secondary {
  min-height: 100px;
  position: relative;
  width: calc(50% - 30px);
  float: right;

  &:before {
    content: '';
    position: absolute;
    top: 0;
    width: 0;
    height: 0;
    right: 100%;
    border-left: 50px solid transparent;
    border-bottom: 100px solid black; /* this should be the secondary color rather than black */
  }
}

Here's a simplified version of the html.erb:

<% teams.each do |team| %>
  <p><%= team.name %></p>

  <div class="tcd-primary" style="background: <%= team.primary_color %>;"></div>
  <div class="tcd-secondary" style="background: <%= team.secondary_color %>;"></div>
<% end %>

Upvotes: 0

Views: 583

Answers (2)

Thinus
Thinus

Reputation: 11

Dynamic CSS Background Color

If you're using a framework like Vue and you are receiving your data from a database that contains stuff like the colors etc, you could either have specific classes but that gets tedious...

I recently found that you could pass a css variable to your html as a style property and then use that variable in your css...

Of course, this needs to be edited to change the below red to a variable of your choosing, this is just the concept.

<style>
    .myDiv {
        height: 200px;
        width: 200px;
        background: var(--backgroundColor);
    }
</style>
<div class="myDiv" style="'--backgroundColor: red;'>Some block</div>

From here, you would use Javascript to either change the value of your css variable with the below

const root = document.querySelector(':root');
root.style.setProperty('--backgroundColor', 'blue');

Or in Vue logic simply dynamically change the value with something like this

<div class="myDiv" :style="'--backgroundColor: ' + backgroundVariable + ';'">
    Some Block
</div>

Upvotes: 0

Paulie_D
Paulie_D

Reputation: 114979

Since these are just colored divs with no text we can take advantage of the inheritance of currentColor.

That is, if we define a text color, then the currentColor value can be used for the background and/or borders.

The currentColor keyword represents the value of an element's color property. This lets you use the color value on properties that do not receive it by default.

If currentColor is used as the value of the color property, it instead takes its value from the inherited value of the color property.

MDN

.tcd-primary {
  min-height: 100px;
  position: relative;
  width: calc(50% - 30px);
  float: left;
  background: currentColor;
}

.tcd-primary:after {
  content: '';
  position: absolute;
  top: 0;
  width: 0;
  height: 0;
  left: 100%;
  border-right: 50px solid transparent;
  border-top: 100px solid currentColor;
}

.tcd-secondary {
  min-height: 100px;
  position: relative;
  width: calc(50% - 30px);
  float: right;
  background: currentColor;
}

.tcd-secondary:before {
  content: '';
  position: absolute;
  top: 0;
  width: 0;
  height: 0;
  right: 100%;
  border-left: 50px solid transparent;
  border-bottom: 100px solid currentColor;
}
<div class="tcd-primary" style="color: gold; "></div>
<div class="tcd-secondary" style="color:orange;"></div>

<div class="tcd-primary" style="color: green; "></div>
<div class="tcd-secondary" style="color:silver;"></div>


If you want to get really up to date you could use a single div with an angled linear gradient and CSS Custom Properties

div { 
  height: 100px;
  background-image: linear-gradient(
  135deg,
  var(--color-1) 60%, 
  transparent 60%, transparent 62%, /* this is your gap */
  var(--color-2) 62%
  );
}
<div style="--color-1: gold; --color-2: orange;"></div>
<div style="--color-1: green; --color-2: silver;"></div>

Upvotes: 2

Related Questions