2

Given the following CSS:

.myClass1 {
    width: 50px;
}
.myClass2 {
    width: 150px;
}

And the following HTML:

...
<div id="myDiv">...</div>
...

Is there a way to determine the values inside of a class without referencing the element itself?

JQuery.someFunc(".myClass1").width()

Or would I have to assign the classes to the element and then check the actual attribute values like so:

function CheckClassWidthValue() {
    var $myDiv = $("#myDiv");

    $myDiv.removeClass();
    $myDiv.addClass("myClass1");
    var class1Width = $myDiv.width();

    $myDiv.removeClass();
    $myDiv.addClass("myClass2");
    var class2Width = $myDiv.width();
}

The code I'm writing would be much cleaner if I could just pull the values from the CSS class names directly. Preferably avoiding locating the CSS element, parsing the code.

Thanks!

Ed Williams
  • 125
  • 2
  • 10
  • 1
    Given that the css rules should not (typically) be dynamic, you should already know what the composition of the css rules are. – Taplar Dec 26 '19 at 20:57
  • 1
    Both the classes you show have invalid declarations. You can only omit unit(and should) on zero-lengths. – connexo Dec 26 '19 at 20:58
  • https://stackoverflow.com/questions/324486/how-do-you-read-css-rule-values-with-javascript I would have a look at this question. It is not a jQuery answer, but it will give you more insight and maybe a solution. – Nathan Dec 26 '19 at 20:58
  • 1
    Does this answer your question? [Can jQuery get all CSS styles associated with an element?](https://stackoverflow.com/questions/754607/can-jquery-get-all-css-styles-associated-with-an-element) – Shiny Dec 26 '19 at 20:58
  • 1
    I'd ask why you feel the need to do this? Generally, this approach is a code smell, indicative of a larger issue – Rory McCrossan Dec 26 '19 at 21:14
  • If the answer I gave does not answer your question, please explain why and how in a comment to that answer. – connexo Dec 26 '19 at 21:27
  • Rory- Because the site uses LESS.css which is converted at compile time, and it's not a good idea to define values in more than one place. Since I can't include @size-sidebar-width from the sizes.less file in the Razor code, I'd need to pull it at runtime from the client and cache that value. – Ed Williams Dec 26 '19 at 21:43
  • Light - Although that question is different, it does include a way to pull the info from the styles directly. Thank you! – Ed Williams Dec 26 '19 at 21:47

1 Answers1

2

Assuming the page has only one stylesheet (index 0), its easy. Go like this:

function getStyleDeclaration(selector, property) {
  return [...document.styleSheets[0].cssRules].filter(
    rule => rule.selectorText === selector
  )[0].style[property];
}

function getStyleDeclarations(selector) {
  const declarations = [...document.styleSheets[0].cssRules].filter(
    rule => rule.selectorText === selector
  )[0].style;
  return Object.keys(declarations).reduce((acc, val) => {
    return { ...acc,
      [declarations[val]]: declarations[declarations[val]]
    }
  }, {});
}

console.log(getStyleDeclaration('.myClass1', 'width'));
console.log(getStyleDeclaration('.myClass2', 'color'));
console.log(getStyleDeclarations('.myClass2'));
.myClass1 {
  width: 50px;
}

.myClass2 {
  color: rgb(242, 242, 248);
  height: 100vh;
  width: 150em;
}
connexo
  • 53,704
  • 14
  • 91
  • 128