覆盖 !important 样式

230

标题基本上已经概括了内容。

外部样式表有以下代码:

td.EvenRow a {
  display: none !important;
}

我已经尝试使用:

element.style.display = "inline";

并且

element.style.display = "inline !important";

但两者都无效。是否可能使用JavaScript覆盖!important样式?

这是为了一个Greasemonkey扩展程序,如果有区别的话。

12个回答

436

有几种简单的一行代码可以用来实现这个。

  1. 在元素上设置一个“style”属性:
  1. 在元素上设置“style”属性
element.setAttribute('style', 'display:inline !important');
  • 修改 style 对象的 cssText 属性:
  • element.style.cssText = 'display:inline !important';
    

    任何一个都可以完成工作。

    ===

    我编写了一个名为“important”的jQuery插件,用于操作元素中的!important规则: http://github.com/premasagar/important

    ===

    编辑: 如评论中所分享的,标准CSSOM接口(JavaScript与CSS交互的API)提供了setProperty方法:setProperty

    element.style.setProperty(propertyName, value, priority);
    

    例如:

    document.body.style.setProperty('background-color', 'red', 'important');
    

    1
    @Guss - 我所举的第一个例子是用于style属性,而非标签/元素。 - Prem
    78
    为了防止覆盖其他属性,你可能想要使用 element.style.cssText += ';display:inline !important;'; - user123444555621
    4
    @user123444555621,Premasagar。最好使用更好的选项:element.style.setProperty - Pacerier
    我正在尝试将变量值设置为属性值,但我无法使用以下语法:html.style.cssText = "background-color: \${bgColor}` !important;";html.setAttribute("style","background-color: `${bgColor}` !important;");`。我该怎么做? - Vahid
    显示剩余2条评论

    300

    element.style有一个setProperty方法,可以将优先级作为第三个参数:

    element.style.setProperty("display", "inline", "important")
    

    它在旧版IE中无法工作,但在现代浏览器中应该可以正常运行。


    3
    适用于 IE 9 的作品 https://msdn.microsoft.com/zh-cn/library/ie/ff975226(v=vs.85).aspx - salmatron
    9
    最佳解决方案,因为它不会覆盖整个样式属性,并且这是W3C希望它起作用的方式。 - stfn
    其缺点是我无法使用驼峰式的属性名称,如boxShadow - Pavan
    很容易就可以使用连字符形式,或者如果您需要自动转换,只需编写一个函数即可。@Pavan - alexia

    50

    我认为唯一的方法是将样式作为新的CSS声明添加,并在其后添加'!important'后缀。最简单的方法是在文档头部附加一个新的<style>元素:

    function addNewStyle(newStyle) {
        var styleElement = document.getElementById('styles_js');
        if (!styleElement) {
            styleElement = document.createElement('style');
            styleElement.type = 'text/css';
            styleElement.id = 'styles_js';
            document.getElementsByTagName('head')[0].appendChild(styleElement);
        }
        styleElement.appendChild(document.createTextNode(newStyle));
    }
    
    addNewStyle('td.EvenRow a {display:inline !important;}')
    

    使用上述方法添加的规则(如果您使用了!important后缀)将覆盖先前设置的其他样式。 如果您没有使用后缀,则请确保考虑到“优先级”等概念。


    11
    这可以用一行代码替代。请见下方链接: https://dev59.com/c3RB5IYBdhLWcg3w77kn#1577204 - Prem
    2
    你怎么找到真正触发样式的选择器?我认为这需要解析所有样式表,这是一项相当困难的工作。 - user123444555621
    坏处是有时无法覆盖“!important”,更好的方法是直接在元素中设置。 - uingtea

    4

    在@Premasagar的优秀回答基础上进行改进;如果您不想删除所有其他内联样式,请使用以下方法

    //accepts the hyphenated versions (i.e. not 'cssFloat')
    addStyle(element, property, value, important) {
        //remove previously defined property
        if (element.style.setProperty)
            element.style.setProperty(property, '');
        else
            element.style.setAttribute(property, '');
    
        //insert the new style with all the old rules
        element.setAttribute('style', element.style.cssText +
            property + ':' + value + ((important) ? ' !important' : '') + ';');
    }
    

    无法在Chrome中使用removeProperty(),因为它不会删除!important规则。
    无法在FireFox中使用element.style[property] = '',因为它只接受camelCase。


    1
    不妨使用更好的选项:element.style.setProperty - Pacerier

    1
    如果您想要在DOM元素样式属性中更新/添加单个样式,可以使用此函数:
    function setCssTextStyle(el, style, value) {
      var result = el.style.cssText.match(new RegExp("(?:[;\\s]|^)(" +
          style.replace("-", "\\-") + "\\s*:(.*?)(;|$))")),
        idx;
      if (result) {
        idx = result.index + result[0].indexOf(result[1]);
        el.style.cssText = el.style.cssText.substring(0, idx) +
          style + ": " + value + ";" +
          el.style.cssText.substring(idx + result[1].length);
      } else {
        el.style.cssText += " " + style + ": " + value + ";";
      }
    }
    

    style.cssText在所有主要浏览器中都得到了支持

    使用案例举例:

    var elem = document.getElementById("elementId");
    setCssTextStyle(elem, "margin-top", "10px !important");
    

    这里是演示链接


    这个答案提供了哪些额外的信息或改进? - Pogrindis
    这个函数很短,简单易懂。你可以添加重要选项。它不会删除所有元素样式。它会覆盖或添加元素样式属性中的单个样式。你不需要任何JS框架。最重要的是,这个函数在每个浏览器中都能正常工作。 - Marek Skrzyniarz

    0

    https://jsfiddle.net/xk6Ut/256/

    在JavaScript中覆盖CSS类的一种选项是使用样式元素的ID,以便我们可以更新CSS类。

    function writeStyles(styleName, cssText) {
        var styleElement = document.getElementById(styleName);
        if (styleElement) document.getElementsByTagName('head')[0].removeChild(
            styleElement);
        styleElement = document.createElement('style');
        styleElement.type = 'text/css';
        styleElement.id = styleName;
        styleElement.innerHTML = cssText;
        document.getElementsByTagName('head')[0].appendChild(styleElement);
    }
    

    ..

       var cssText = '.testDIV{ height:' + height + 'px !important; }';
        writeStyles('styles_js', cssText)
    

    0

    初始值不重置很重要。你没有设置p的颜色,而是em的颜色。实际上,将color:initial更改为color:green也可以解决问题。 - Pacerier

    0

    如果你通过JavaScript注入一个类(例如:'show'),而不是注入样式,它将起作用。但是在这里,你需要像下面这样的CSS。添加的类CSS规则应该在原始规则之后。

    td.EvenRow a{
      display: none !important;
    }
    
    td.EvenRow a.show{
      display: block !important;
    }
    

    0

    我们有另一种可能性从CSS中删除属性值。

    就像在js中使用replace方法一样。但是您必须确切地知道样式的ID,或者您可以编写一个for循环来检测它(计算页面上的样式数量,然后检查其中是否包含或匹配!important值。并且您还可以计算它们包含多少个,或者只需编写全局[regexp:/ str / gi]替换方法)

    我的方法非常简单,但我附上了一个jsBin示例:

    https://jsbin.com/geqodeg/edit?html,css,js,output

    首先我在CSS中将body背景设置为黄色!important,然后我用JS覆盖为深粉色。


    0

    修改 CSS 只是我的 GM 扩展所做的一部分。 - Enrico

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接