6

Is it possible to set two Values for a single attribute on a CSS ID, e.g.

height: 12em; height: 12rem;

for a single id? I know it's possible to do this with CSS, but I want to change the height via javascript, and have both values on one attribute, so that 'em' functions as a fallback for Browsers not supporting 'rem'.

Example:

function updateHeight() {
  var testElem = document.getElementById("testId");
  testElem.style.height = "12em";
  testElem.style.height = "12rem";
  //testElem.style.height = "12em; 12rem;"; doesn't work, applies "12em"
}
#testId {
  height: 8em;
  height: 8rem;
  background-color: black;
  color: white;
}
<!DOCTYPE html>
<html>

<head>
  <title>Test</title>
  <meta charset="utf-8" />
</head>

<body>
  <div id="testId">
    BlaBla
  </div>
  <button onclick="updateHeight()">Bla</button>
</body>

</html>

6
  • I guess you can write so, but the only applied version will be the last one, what you are trying to achieve ? Commented Jun 19, 2016 at 19:22
  • You can have hundreds of values, but if you use the same selector, only the last one will apply Commented Jun 19, 2016 at 19:23
  • I want a fallback, for Browsers not supporting 'rem'. Commented Jun 19, 2016 at 19:23
  • See this post, you can use a REM polyfill instead of worrying about fallbacks: stackoverflow.com/questions/19480195/… Commented Jun 19, 2016 at 19:25
  • According to this article you can use both px and rem and any browser which cannot use rem will fallback to using px. Commented Jun 19, 2016 at 19:31

2 Answers 2

3

You can use a class instead

function updateHeight() {
  var testElem = document.getElementById("testId");
  testElem.classList.add('high');
}
#testId {
  height: 8em;
  height: 8rem;
  background-color: black;
  color: white;
}

#testId.high { /* remember that ID is more specific than class */
  height: 12em;
  height: 12rem;
}
<!DOCTYPE html>
<html>

<head>
  <title>Test</title>
  <meta charset="utf-8" />
</head>

<body>
  <div id="testId">
    BlaBla
  </div>
  <button onclick="updateHeight()">Bla</button>
</body>

</html>

Or if the value is dynamic, you'd probably have to insert a style tag to be able to support CSS cascading

function updateHeight() {

  var value    = 12; // or something dynamic
  var styles   = '#testId {height: '+value+'em; height: '+value+'rem;}';
  var tag      = document.createElement('style');

  tag.innerHTML = styles;

  document.querySelector('head').appendChild(tag);

}
#testId {
  height: 8em;
  height: 8rem;
  background-color: black;
  color: white;
}
<!DOCTYPE html>
<html>

<head>
  <title>Test</title>
  <meta charset="utf-8" />
</head>

<body>
  <div id="testId">
    BlaBla
  </div>
  <button onclick="updateHeight()">Bla</button>
</body>

</html>

Sign up to request clarification or add additional context in comments.

Comments

3

Yes, you can. This is defined by CSS Cascade:

Each property declaration applied to an element contributes a declared value for that property associated with the element.

These values are then processed by the cascade to choose a single “winning value”.

The cascaded value represents the result of the cascade: it is the declared value that wins the cascade (is sorted first in the output of the cascade).

Then, if you use

height: 8em;
height: 8rem;

there will be 2 declared values for the property height: 8em and 8rem. The latter will will the cascade, becoming the cascaded value.

If some browser does not support one of them, the other one will be the only declared value, so it will win the cascade.

If some browser does not support any of them, the output of the cascade will be the empty list, and there won't be any cascaded value. The specified value will be the result of the defaulting processes (the initial value in this case, because height is not an inherited property).

However, with JavaScript there is a problem. setProperty, used under the hood by camel case IDL properties in .style, uses the set a CSS declaration algorithm, which overwrites existing declarations:

  1. If property is a case-sensitive match for a property name of a CSS declaration in declarations, let declaration be that CSS declaration.

  2. Otherwise, append a new CSS declaration with the property name property to declarations and let declaration be that CSS declaration.

There are some workarounds:

  • Use cssText instead of camel case IDL attributes:

    testElem.style.cssText += "; height: 12em; height: 12rem; ";
    
  • Check the style after setting it. If you get the empty string, it means it wasn't recognized.

    testElem.style.height = "12rem";
    if(!testElem.style.height) testElem.style.height = "12em";
    
  • Don't set the styles in the inline style declaration. Create a new stylesheet instead, or add some class to the element to trigger some CSS from an existing stylesheet.

2 Comments

That's right, I want to change the style with javascript, but than it only applies one style.
OK, I misunderstood the question. I have updated my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.