Search code examples
javascriptcsscss-specificity

Are there any CSS rules that, when set to empty strings, override lower-specificity rules


I'm trying to determine which style applies to an element by taking into account both inline and class styles. Javascript parses both of these into objects, but styles that are not set are empty strings, not undefined. If styles that are "empty" (e.g. width:;) have no effect, regardless of how specific the rule, then my goal is trivial.

However, in order to override display:none with the default rule dynamically, I know that document.getElementById('ele').style.display = ''; works and, while I know it doesn't actually add a display inline style, are there any styles that do have an effect when set empty in CSS? If this is the case, I would have to parse the style and stylesheet strings manually to see if the property was defined.


Solution

  • Writing display:; or display:''; within a stylesheet or style declaration block is an invalid declaration.

    The style property of an element is a different story. It's a convenience mechanism to set and get the inline styles of an element. Setting a value is actually a shorthand for .setProperty and getting one a shorthand for .getPropertyValue.

    <div></div>
    
    =>
    element.style.display == ''
    element.getPropertyValue('display') == null
    

    Since no inline style is set there is no value for display, so getPropertyValue('display') returns null.

    Now that we know that.display is short for .getPropertyValue('display') let's look what the specification says about the returned value:

    Returns the value of the property if it has been explicitly set for this declaration block. Returns the empty string if the property has not been set

    So empty string equals no value.

    element.style.display = 'none'
    
    =>
    <div style="display: none;"></div>
    element.getPropertyValue('display') == 'none'
    

    As you can see we can easily set an inline style using .style. If we now try to set an invalid value it will be ignored:

    element.style.display = 'foo'
    
    =>
    <div style="display: none;"></div>
    element.getPropertyValue('display') == 'none'
    

    Nothing changes. Setting the value to an empty string works though, as it is equivalent to no style:

    element.style.display = ''
    
    =>
    <div></div>
    element.getPropertyValue('display') == null 
    

    Setting display to null would work too.