-1

Earlier my question was:-

I have the following code in my Sass css file

.random {
    box-sizing: content-box;
    text-align: center;
    line-height: 1;

    &:before {
        display: inline-block;
        margin-right: 0.2em;
        width: 0;
        height: 0;
        border-right: 0.4em  solid transparent;
        border-left: 0.4em solid transparent;
        content: "";
        vertical-align: baseline;
    }
}

.perc-neg:before {
    border-top: 0.5em solid #FCB062;
}

.perc-neg.good:before {
    border-top: 0.5em solid #98F1AC;
}

I have a div with class = "random perc-neg good"

Now I want to change style of the above div. how to do it?

I tried following in console but it returns empty object

$("random perc-neg good:before").css("color","red");
$("random.perc-neg.good:before").css("color","red");
$(".random.perc-neg.good:before").css("color","red");

Someone has suggested its a possible duplicate but its not.

Int he related question, the user just wanted to make it visible or hidden so two classes will be sufficient.

But my requirement is to change the color as per user's choice which he can select from wide range of colors.

Its definitely impossible to define a class with each color changes.

And we cant pass some variable to css as well to change the color property accordingly.

Updated Question:

I am now using Sass. I have defined an function to update the color

@function em($color) {
  @return border-bottom: 0.5em solid $color;
 }

.perc-neg.good:before {
    em(#98F1AC);
}

definitely, I can call the function from the Sass file but how to call it from javascript

Now I want to pass the hex code of color from javascript

I need to pass something like this from javascript

.perc-neg.good:before(#98F1AC)

looked for the same in google did not find anything relevant Instead of marking it as duplicate, it would be much better if you can provide a solution

seven-phases-max
  • 11,765
  • 1
  • 45
  • 57
  • you can add dynamic CSS to head via javascript – Vladu Ionut Oct 02 '16 at 08:15
  • @VladuIonut i tried that but it did not work i tried both with append and add function – tylerdurden Oct 02 '16 at 08:54
  • @Paulie_D How does the referenced question solve OP's problem of manipulating `color` of pseudo elements? As far as I got, it solves only changing content of pseudo elements by putting it on a data-attribute and referencing that in the pseudo element's content property. Sadly, afaik `attr()` in CSS cannot be used for other properties than `content`. – connexo Oct 02 '16 at 09:57
  • Just make a list of classes with the colors you are going to use, then change the class of the element with javascript –  Oct 02 '16 at 16:01
  • like i said the user will be allowed to choose a color from color picker. so its nearly impossible to define a class for each color..hope u get my point – tylerdurden Oct 02 '16 at 19:02

2 Answers2

2

You cannot access pseudo elements in Javascript since these elements are not in the DOM.

If you want the change pseudo elements styling, you need to predefine css classes for that purpose and add/remove those based on your triggering events.

If that is not possible, simply don't set the colorproperty on the pseudo element at all, but on the host element, since :before and :after will then inherit their host element's color property (if they don't have a specific color property assigned to themselves in CSS).

connexo
  • 53,704
  • 14
  • 91
  • 128
  • thats why i am trying to use less css to update the color property from a function am i doing something wrong? – tylerdurden Oct 02 '16 at 08:09
  • Less is being translated at build-time. I understood you want to change styling at run-time, right? – connexo Oct 02 '16 at 08:15
  • yeah thats what my requirement is – tylerdurden Oct 02 '16 at 08:53
  • As i want to change the color its difficult to add a class for each color because user will be provided with color picker – tylerdurden Oct 02 '16 at 08:55
  • even if i dont assign color property to pseudo element, how can i assign color to that psedo element later? – tylerdurden Oct 02 '16 at 08:58
  • You can assign it to the host element. Instead of assigning it to `element:before`, assign the color to `element`. Ofc this only works if `element:before` does not have a color defined already. – connexo Oct 02 '16 at 09:17
  • Whilst you can't directly modify the pseudo elements without inserting new style rules, you can certainly access their current CSS properties using [Window.getComputedStyle()](https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle). For example in this case: `window.getComputedStyle(document.querySelector('.perc-neg.good'), ':before').getPropertyValue('color');` – BurpmanJunior Oct 02 '16 at 11:08
1

You cannot call a SASS / LESS function from javascript as they are both pre-compilers that just produce a static stylesheet.

If you have a limited color pallet you could create all the rules that cover your use cases.

However you do have the ability to create a style element with javascript and append new rules to it. Here is a simple example that you could expand on

// add Style is wrapped in a closure that locks in a single 
// style element that you can add to on the fly
const addStyle = (() => {
  // create and append the style element
  const styleSheet = document.createElement('style')
  document.head.appendChild(styleSheet)
  const style = styleSheet.sheet
  
  // helper function to serialize an object to a css string
  const serializeStyle = (styles) => {
    return Object.keys(styles).reduce((str, prop) => {
      return str + kebabCase(prop) + ':' + styles[prop] + ';'
    }, '')
  }
  
  // helper function to convert camelCase to kebab-case
  const kebabCase = (str) => 
    str.replace(/([A-Z])/g, (_, letter) => '-'+ letter.toUpperCase()) 
  
  // return the public function
  return (selector, styles) => {
    // add a new rule to the created stylesheet
    style.insertRule(
      selector + '{' + serializeStyle(styles) + '}', 
      style.cssRules.length
    )
  }
})()

addStyle('.random::before', {
  border: '10px solid #aec369'
})

addStyle('.random::before', {
  background: '#bada55',
  boxShadow: '5px 5px 10px #777'
})

const el = document.querySelector('#color')

const em = () => {
  addStyle('.random::before', {
    borderColor: el.value
  })
}
el.addEventListener('keyup', em)
el.addEventListener('change', em)
.random {
  position: relative;
  background-color: #eee;
}

.random::before {
  content: '';
  display: block;
  height: 200px;
  width: 200px;
}
<input id="color" placeholder="#000000" />
<div class="random">
  
</div>
synthet1c
  • 6,152
  • 2
  • 24
  • 39