【问题标题】:CSS specificity beat inline with !importantCSS 特异性击败内联 !important
【发布时间】:2014-09-19 00:41:00
【问题描述】:

这是我的网站:http://stage.samkeddy.com/

它使用几个媒体查询和一个由 javascript 提供支持的移动菜单按钮来响应。

这里是菜单按钮的javascript:

function toggleMenu () {
    if (menuIsVisible == false) {
        collapsibleMenu.style.height = 'auto';
        content.style.paddingTop = '290px';
        menuIsVisible = true;
    }
    else {
        collapsibleMenu.style.height = '0';
        content.style.paddingTop = '80px';
        menuIsVisible = false;
    }
}

所以你可以看到我需要调整内容div顶部的填充,以偏移菜单

但是,如果调整为移动设备大小,打开菜单,然后调整回桌面大小,则媒体查询不会修复填充,因为仍然存在来自 javascript 的内联样式。我尝试在桌面版 !important 上制作填充,但在调整大小时填充仍然不会改变,即使根据 this !important beats inline。

您可以通过打开尺寸(外观应该如何)、调整到移动宽度(导航将消失,您将看到菜单按钮)、单击菜单按钮(保持菜单打开)来进行测试,然后将站点大小调整回桌面宽度。您会看到填充仍然存在。如果您检查它,您会看到原始填充被划掉以支持内联样式。

我知道这可以通过使用 javascript 监控宽度并设置填充来实现,但我真的不想这样做,也不认为我应该这样做。

编辑:已解决

首先,我应该添加类,而不是在我的 javascript 中添加 CSS。

然后我假设将 !important 放在媒体查询之外会使其仅显示在桌面上,但它会接管所有媒体查询。所以把它放在一个查询中就可以了。请注意,如果我使用 2 个单独的菜单(移动/桌面),我不需要这个,但由于它是固定的并且 #content 需要填充,所以必须完成它。但是使用这种技术,您也可以只使用单个菜单,但以这种方式为菜单设置高度。我已经在 codepen 中演示了该技术:http://codepen.io/anon/pen/JFvay

【问题讨论】:

  • 你为什么不使用@media 查询来确定菜单的大小...对这些样式使用 javascript/jQuery 只会发现你即将陷入的人孔。
  • 您也可以停止使用那些内联样式。创建几个类并给元素一个或其他类。 (但当然可以尽可能使用媒体查询。)
  • 那么你的 !important 风格出现在你的开发工具中了吗?如果没有,也许你在该样式之前的某个地方有语法错误。
  • 媒体查询确实改变了菜单的大小,javascript 只是隐藏/取消隐藏它。我会尝试使用类然后更新。
  • 在不复制 htm 的情况下可以有两个不同的菜单。使用媒体查询以不同的方式格式化页面。您可能必须使用不同的显示属性,例如固定、混合边距 - 但可以这样做。

标签: javascript html css css-specificity


【解决方案1】:

将此代码添加到您的样式表应该可以解决问题,我刚刚使用开发者工具在您的网站上尝试过,它正在工作:

@media only screen and (min-width: 643.2px) {
    #content {
        padding-top: 80px !important;
    }
}

虽然我强烈建议您为移动设备创建一个单独的导航菜单并使用@media-queries 来显示它。

【讨论】:

  • 我将尝试进行 2 次导航。我可以看到它是如何更容易编码的,尽管有两组相同的 html 是一种耻辱。
  • 不确定是否可以使用php,但是如果您使用php为您做菜单,也许您可​​以编写自己的函数。这样你就不会制作 2 个单独的集合。或者根据您的菜单,您可以将其设置为相当容易分解。
  • 这是我成功的关键。我认为将 !important 放在媒体查询之外会使其仅显示在桌面上,但它会接管所有媒体查询。所以把它放在一个查询中就可以了。请注意,如果我使用 2 个单独的菜单(移动/桌面),我不需要这个,但由于它是固定的并且 #content 需要填充,所以必须完成它。但是使用这种技术,您也可以只使用单个菜单,但以这种方式为菜单设置高度。我已经在 codepen 中演示了该技术:codepen.io/anon/pen/JFvay
【解决方案2】:

您的核心问题是您将 CSS 和内联样式混合在一起。作为一般规则,避免将特定的 CSS 属性直接放在元素上,无论是在 HTML 中,使用 element.style.<property> =,还是通过 jQuery 的 .css() 功能。相反,您应该使用类将您想要的属性定义为 CSS 规则:

#collapsible-menu                       { height: auto;  }
#content                                { padding-top: 290px; }
#someelt.menu-visible #collapsible-menu { height: 0; }
#someelt.menu-visible #content          { padding-top: 80px; }

其中someelt 是一些更高级别的祖先元素。然后,你的 JS 就变得简单了

function toggleMenu() {
    document.getElementById('someelt').classList.toggle('menu-visible');
}

如果您的目标浏览器不支持classList(参见CanIUse),jQuery 提供了自己的类切换版本。

CSS 不是命令式语言,但如果您愿意,可以将上面最后两条规则的 #someelt.menu-visible 部分视为一种 if 语句:“如果菜单是可见,然后collapsible-menu缩小到零高度”,等等。在CSS作为一种编程语言(它是)的这个比喻中,menu-visible类的存在#someelt我想可以将其视为一种布尔“变量”。很可能,您的 JS 中将不再需要相应的变量。

无论如何,这样做的好处是,查看您的代码的人只需查看 CSS 文件即可所有查看您的 CSS 相关逻辑,而不必同时查看 CSS 和 JS,并且您可以在一处更改与 CSS 相关的内容。

【讨论】:

  • 这不是一个准确的描述,特别是如果您认为内联样式属性超出了 CSS 的范围。 !important 影响参与级联的所有样式声明,包括样式属性。如果内联样式声明没有 !important,则任何 !important 声明都应覆盖它。 (当然,如果内联样式声明确实有 !important,它仍然会获胜。)
  • 描述取自MDN。该特定文章中有很多不准确的信息。我明白为什么它说“这篇文章需要技术审查”。 - 它确实需要一个,非常
  • MDN 描述现已删除。
  • 非常感谢,这条评论帮助我实现了我想要的。我在css中定义了#content.openMenu和#mobile-nav.openMenu,然后通过javascript将类添加到这两个元素中。我还必须在这里回答另一个答案的一部分,即定义最小宽度,并使用重要标志将内容的填充顶部移动到那里,这样当它是桌面时它会被覆盖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 2011-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-19
相关资源
最近更新 更多