3

Is possible to make an important property value from CSS selector a non important one?


For example: Bootstrap 3 defines .hide class as:

 .hide { display: none !important; }

Is possible to remove the important value without modifying the BS3 source code?

Thinking at somethingl iike

 .hide { display: none !remove-important; }

Note that I want to keep the same value! I don't want to set block !important to .hide class because that would not be correct...

I already added a new class .hide-non-important and used it where it was needed:

 .hide-not-important { display: none; }

...but the question is: is there any alternative to this?

devo
  • 21,875
  • 18
  • 78
  • 125
Ionică Bizău
  • 93,552
  • 74
  • 254
  • 426
  • I think it is a very bad judgment call on Bootstrap to [have added that](https://github.com/twbs/bootstrap/issues/6339) to any of its properties (at least without using some mixin for the programmer to choose to have the `!important` flag or not). While I can agree with the idea that `.hide` should always hide, `!important` assumes too much and is too inflexible to be a wise solution. – ScottS Sep 20 '13 at 19:47
  • @ScottS That's my opinion too... I've added [an issue in Bootstrap repository from Github](https://github.com/twbs/bootstrap/issues/10751). – Ionică Bizău Sep 21 '13 at 18:40

5 Answers5

3

You don't need to edit the original source code. Just create a stylesheet and place it after the Bootstrap stylesheets and add this to it:

 .hide { display: block !important; }

Now, having said this, I would be very careful about doing this. You don't know how many elements across your site have applied this class, and you will almost certainly get unanticipated results.

There is obviously a reason that this class has been applied, I would suggest either:

  1. don't do this

  2. add some other class to the element and add styles to that. Adjust your markup (or use js to apply the class if need be) to something like:

    <div class="hide custom-hide-reset"></div>
    

    Then add this style to the stylesheet you've created:

    .custom-hide-reset { display: none; }
    
BoltClock
  • 630,065
  • 150
  • 1,295
  • 1,284
Mister Epic
  • 15,703
  • 11
  • 68
  • 126
  • But this sets `block` value, I want `none` value to hide elements. – Ionică Bizău Sep 19 '13 at 15:56
  • You don't want to have !important applied, but you still want the style to be applied? I'm not sure I understand what you are trying to achieve at the end of the day. FWIW, there is no way to remove the !important modifier, it can only be overriden with another !important style. – Mister Epic Sep 19 '13 at 16:02
  • I already created a custom class (see the edit). Is there another alternative? – Ionică Bizău Sep 19 '13 at 16:08
  • 1
    No, once !important has been applied, it can only be overridden, not unapplied – Mister Epic Sep 19 '13 at 16:12
  • @Hannes: Because http://stackoverflow.com/questions/18851042/div-displayinitial-not-working-as-intended-in-ie10-and-chrome-29 – BoltClock Sep 19 '13 at 18:23
1

You can overwrite this with:

 body .hide { display: none !important; }

 .someclass.hide { display: none !important; }

those two examples have higher priority

Vladimir
  • 377
  • 1
  • 6
  • That will only work if the second rule appears after the first in your CSS - also specificity is irrelevant when an `!important` rule is used. – Jason Yaraghi Sep 19 '13 at 15:56
  • 1
    @Adrift: Specificity is relevant anywhere that you have more than one rule with the same property applying to the same element; `!important` is just another layer of precedence to consider. See [this answer](http://stackoverflow.com/questions/5805040/important-in-css-specificity-points/5805204#5805204). In this case, `.someclass.hide` would win regardless of order. – BoltClock Sep 19 '13 at 18:25
  • Ah ... yup I'm completely wrong :[ Thanks for pointing that out and for the relevant answer; +1 – Jason Yaraghi Sep 19 '13 at 18:37
  • 1
    @Adrift: No worries, thank *you* for the opportunity to revisit one of my older answers :) – BoltClock Sep 19 '13 at 18:42
  • @BoltClock +1 to both the answers you linked; I'm quite impressed you're only 21. – Andrea Ligios Sep 20 '13 at 08:08
1

You can override the current !important value by another one like

.col{ color:red !important; }
.col{ color:green; } // wont work
.col{ color:blue !important; } // will work and set color blue instead of red

DEMO.

Update :

This question is not about JavaScript but as an alternative you can accomplish the task using these technique, remove the rule using JavaScript and then add a new rule again.

function getCSSRule(ruleName, deleteFlag) {               
   ruleName=ruleName.toLowerCase();                       
   if (document.styleSheets) {                            
      for (var i=0; i<document.styleSheets.length; i++) { 
          var styleSheet=document.styleSheets[i];          
         var ii=0;                                        
         var cssRule=false;                               
         do {                                             
            if (styleSheet.cssRules) {                    
                cssRule = styleSheet.cssRules[ii];         
            } else {                                      
                cssRule = styleSheet.rules[ii];            
            }                                             
            if (cssRule)  {                               
                if (cssRule.selectorText.toLowerCase()==ruleName) { 
                    if (deleteFlag=='delete') {             
                        if (styleSheet.cssRules) {           
                            styleSheet.deleteRule(ii);        
                        } else {                             
                            styleSheet.removeRule(ii);        
                        }                                    
                        return true;                         
                    } else {                                
                    return cssRule;                      
                }                                       
            }                                          
        }                                             
        ii++;                                         
        } while (cssRule)                                
      }                                                   
   }                                                      
   return false;                                          
}                                                         

function killCSSRule(ruleName) {                          
    return getCSSRule(ruleName,'delete');                  
}                                                         

function addCSSRule(ruleName, v) {                        
    if (document.styleSheets) {                            
        if (!getCSSRule(ruleName)) {                        
            if (document.styleSheets[0].addRule) {           
                document.styleSheets[0].addRule(ruleName, v,0);
            } else {                                         
                document.styleSheets[0].insertRule(ruleName+'{'+v+'}', 0);
            }                                                
        }                                                   
    }                                                      
   return getCSSRule(ruleName);
}
// Check the rule before deleting
console.log(getCSSRule('.col')); // .col { color:red !important; }
// At first remove the current rule
killCSSRule('.col');
// Now assign nre rule
addCSSRule('.col', 'color: red');
// Check the rule after deleting
console.log(getCSSRule('.col')); // .col { color:red; }

DEMO. ( Source : Totally Pwn CSS with Javascript )

The Alpha
  • 131,979
  • 25
  • 271
  • 286
1

The stylesheet objecs are accessible from javascript

var sheets = document.styleSheets

Once you have the stylesheet array, you can iterate over the rules

var rules = sheets[i].cssRules || sheets[i].rules // browser dependency

Each rule has a style property, which is mutable in the usual way.

rule.style[cssPropName] = value;

There is a method on the sheet to delete a rule by index, either deleteRule or removeRule, depending on the browser.

Bottom line, you can find the rule and either edit it or delete and re-add it in a modified form.

Reference: http://www.javascriptkit.com/dhtmltutors/externalcss3.shtml#.Ujsin4ZmjAs

fred02138
  • 3,163
  • 1
  • 12
  • 17
1

Since the question can be splitted in

  • how can I remove !important from a rule applied to my page but
  • without changing its value and
  • without editing the original CSS file

For pure spirit of adventure only, I think it would be possible in the following way:

  1. load the CSS with jQuery;
  2. perform a replacement of its content, by searching .hide { display: none !important; } and replacing it with .hide { display: none; };
  3. apply the new in-memory altered CSS to the page.

Taking for good the solution posted in this answer, it could be modified with something (totally untested, just to get the idea) like:

$.get(myStylesLocation, function(css)
{
   var alteredCss = css.replace(".hide { display: none !important; }",".hide { display: none; }");
   $('<style type="text/css"></style>')
      .html(alteredCss)
      .appendTo("head");
});
Community
  • 1
  • 1
Andrea Ligios
  • 46,329
  • 24
  • 102
  • 208