【问题标题】:How can I override "display:inline-block" with "display: block" in IE7?如何在 IE7 中用“display:block”覆盖“display:inline-block”?
【发布时间】:2011-11-08 21:24:35
【问题描述】:

这里有一些代码来说明我遇到的问题。 jsFiddle Demo

<div class="normal">
    <a href="#">Test</a>
    <a href="#">Test longer</a>
</div>
<div class="ib blockbyclass">
    <a href="#">Test</a>
    <a href="#">Test longer</a>
</div>
<div class="ib">
    <a href="#" style="display: block;">Test</a>
    <a href="#" style="display: block;">Test longer</a>
</div>
body{background-color: gray;}
div{float:left; margin: 5px;}
a {background-color: black; color: white;}
div.ib a {display: inline-block;}
div.normal > a {display: block;}
div.blockbyclass> a {display: block; }

我有某种类型的链接,在大多数情况下需要呈现为 inline-block,但在某些情况下需要呈现为块元素。具体来说,我希望它们各自出现在自己的行上并占据包含 div 的整个区域。在这种特殊情况下,包含链接的div 设置为浮动,因此它将根据其中最大的链接调整自身大小。 IE8、IE9、Firefox 和 Chrome 正确呈现这些链接,但无论我做什么 IE7 都拒绝忘记display: inline-block 规则。

如何让 IE7 以“块”模式显示这些元素?

【问题讨论】:

    标签: html css internet-explorer-7


    【解决方案1】:

    根据article display:inline-block 的行为与 IE7 中的 display:inline 类似,因此您可以进行一些小改动以仅支持 IE7(使用 simple hack for IE):

    div.ib a {
       display: inline-block; 
       *display: inline; /* IE7 and below */ 
    }
    

    我希望this 能按您的预期工作。


    编辑:

    好的。问题在于属性 hasLayout 解释herezoom:1height:any_value 都激活了 hasLayout,因此同时 display:inline-block; *display:inline 会覆盖下一个 display:block 声明,放置 height:30px(例如)返回属性 hasLayout。所以要做的就是删除this article中所说的hasLayout。

    我有this demo 来展示如何工作。因为height实际上是不可触摸的,所以我使用padding-bottomfont-size在其他浏览器中模拟height。请注意,最宽元素的width 保持不变。


    EDIT2:

    你有没有体贴jQuery的解决方案? (IE7中只给元素不同的widths)

    【讨论】:

    • 这似乎使 IE7 能够覆盖block 属性,但不幸的是,它也使得ib div 中没有应用blockbyclass 的元素将显示为inline。正如我在最初的问题中所说,“我有某种类型的链接,在大多数情况下需要呈现为内联块。”我需要应用 height 之类的 CSS 样式,而 inline 元素会忽略这些样式。
    • 只是想问你是否有必要属性display:inline-block必须完全明确,或者可以用其他方式模拟。
    • 只要行为相同,inline-block 可以通过其他方式进行模拟。在您更新的答案中给出的演示中,height: 30px 未应用,因为*display: inline 使 IE7 忽略高度值。
    • @StriplingWarrior 我又更新了,height:30px 几乎总是不能在 IE7 中使用,并不是因为*display:inline 是因为在我申请了display:block 之后。适用于hasLayout,我看到模拟height 的唯一方法是通过padding
    • +1 用于开箱即用的思考。从来没有想过为此使用 jQuery。不确定我想不想。但这是一个聪明的主意。
    【解决方案2】:

    更新:此处从 cmets 移出:

    问题在于div 浮动。当您浮动一个元素时,它将在页面正常流之外,因此,IE 将占据它 width:0; height:0; 并且当您将一些元素放入其中时,它们将创建自己的 heightwidth 和浮动元素将被渲染如何推动它们(我的英语真的很糟糕,很抱歉)。第一步,Ainline-block,所以它的 height 是例如 x。当您将其设为block 时,它应该填充其父级,但是,在IE 中,其父级具有width:0。所以你应该从div.ib a 中删除第一个inline-block 属性 你可以为浮动div 元素创建一个固定宽度 属性。

    div { float: left; margin: 5px; width: 80px; } 
    

    此外,据我所知,W3C 建议 浮动元素应具有固定宽度。 - IE 6 也需要固定高度才能正常工作!!!

    另一种方法-如果可以并且您的解决方案允许您-将第一个 inline-block 更改为 inline 仅用于 IE

    display: inline-block; 
    *display: inline; 
    

    width 解决方案(用于div)更加标准和灵活。

    结束更新

    但是,要在 IE 中覆盖 css-attribute,您有 3 种可选方法:

    1. 第一种方法是使用条件注释,使其内容仅对IE 可见。一个完整的例子是这样的:

      <!-- visible to IE less that 7 (6, 5, etc) -->
      <!--[if lt IE 7]> <link href="/Content/ie6.css" rel="stylesheet" type="text/css" /> <![endif]-->
      
      <!-- visible to IE 7 only -->
      <!--[if IE 7]> <link href="/Content/ie7.css" rel="stylesheet" type="text/css" /> <![endif]-->
      
      <!-- visible to IE 8 only -->
      <!--[if IE 8]> <link href="/Content/ie8.css" rel="stylesheet" type="text/css" /> <![endif]-->
      
      <!-- visible to IE 9 and above and also visible to other browsers -->
      <!--[if gt IE 8]><!--> <link href="/Content/normal.css" rel="stylesheet" type="text/css" /> <!--<![endif]-->
      

      如您所见,您有很多选项可以使用条件注释

    2. 另一种方法是使用CSS 特殊选择器,使某些选择器对IE 可见,并对其他浏览器隐藏它们。一个完整的例子是:

      /* normal */
      your-selector{
      }
      
      /* visible to IE 6 only */
      * html your-selector{
      }
      
      /* visible to IE 7  only */
      *:first-child + html your-selector{
      }
      
      /* visible to IE 7 and above */
      html > body your-selector{
      }
      
      /* visible to IE 8 and above */
      html > /**/ body your-selector{
      }
      
    3. 我知道的第三种方法是使用IE 专门的css-properties:

      /* normal selector */
      your-selector{
          /* normal property, visible to all browsers */
          color: #FF0;
          padding: 20px auto 35px;
      
          /* use special properties in name/value for IE */
      
          /* visible to ie 6 only */
          _color: #FF0;
          _padding: 15px auto 30px;
      
          /* visible to ie 7 and below (7, 6, 5, ...) */
          *color:#FF0;
          *padding: 15px auto 30px;
      }
      

    如果您有任何问题或需要澄清任何部分,请告诉我。

    【讨论】:

    • 我很惊讶这有这么多的赞成票,因为它没有解决实际问题(当然,我赞扬提问者赞成它,尽管它没有解决他的问题)。
    • @StriplingWarrior 我现在可以理解您的问题:D 问题出在div 浮动上。当您浮动一个元素时,它将在页面正常流之外,因此,IE 将占据它 width:0; height:0; 并且当您放入一些元素时,它们将创建自己的 heightwidth 以及floated-element 将被渲染如何推动它们(我的英语真的很糟糕,很抱歉)。第一步,Ainline-block 所以它 height 是例如 x。当您将其设为block 时,它应该填充其父级,但是,在IE 中,其父级的宽度为0! (在下一条评论中继续)
    • 你应该从div.ib a中删除第一个inline-block属性或者你可以为浮动的dev元素创建一个固定宽度的属性。 div { float: left; margin: 5px; width: 80px; } 另外,据我所知,W3C 建议浮动元素应具有固定宽度。 -IE 6 也需要固定高度才能正常工作!!!-.
    • 您应该更新您的答案以反映 cmets 中的内容。答案不太好,而 cmets 实际上描述了真正的问题。
    • 这并不是你不知道,而是因为 Galled 在你之前发布了答案,你应该已经投票了。
    【解决方案3】:

    您的问题是由inline-block 设置触发的hasLayout。引用http://www.satzansatz.de/cssd/onhavinglayout.html(我的重点已添加):

    “显示属性不同:虽然'inline-block'设置haslayout = true,以后不会通过在另一个规则集中用'block'或'inline'覆盖值来将标志重置为false .

    这与大多数可以重置的hasLayout 触发器不同。因此,我认为要解决您的问题,您需要反过来思考。您需要将block 作为a 标签的默认值,然后在需要时添加一个类以获取您的inline-block

    有点像http://jsfiddle.net/mmpX3/33/,其中blockbyclass 我替换为inlinebyclass(实际上是inline-block)。

    更新说明:您可能注意到,当您从inline-block 切换到block 时,它“有点工作”(文本行仍然向下移动)。那是因为它显示为一个块,但一个是 hasLayout 而不是一个。我不知道你的具体情况,但是如果你可以在包含div 上设置一个width,那么我上面提出的“反向思考”的次要解决方案是然后设置width: 100% 与您“重置”为 block 一起使用,例如:http://jsfiddle.net/mmpX3/64/

    更新警告:我不知道您是否有其他 css 计划应用于 a 标签,但如果其中任何一个触发 hasLayout,那么您需要注意为此(也许找到不同的方法)。例如,请参阅这个小提琴http://jsfiddle.net/mmpX3/69/,其中所有内容都设置为block,但因为我在a 标签上放置了min-height,它仍然存在与您原来的问题相同的问题。

    【讨论】:

    • +1。我希望避免这种方法,因为我正在生成带有实用程序类的ib 样式按钮,并且那里还有很多其他的东西。避免应用 inline-block-generating 类将需要一些伪代码,但看起来它可能最终成为让事情看起来像我想要的样子的唯一方法。
    • 你能不能把与ib 类关联的所有代码都保存在baseButton 类(或一些类似的)中,并应用第二类ib 作为标准except 在您不想要它的情况下,在这种情况下,您仍然通过blockbyclassblock 显示应用任何其他必要的更改?关键是避免设置inline-block(无论如何对于IE7)在css级联中,除非真的需要。如果您使用 3 个类,1 个用于基本样式,1 个用于 inline-block 本身,1 个用于 block,那么您避免使用每个设置 inline-block,除非您实际使用它。
    • 我将此标记为答案,但将赏金交给了 Galled (stackoverflow.com/q/8205404/120955)。请参阅他的答案以获取解释。感谢您的所有时间。
    • 好吧,我不能说我一点也不失望。但是,我很高兴我的信息帮助您解决了您的问题。这就是网站的全部意义所在。
    【解决方案4】:

    您可以将 IE7 的样式放在单独的 CSS 中,并使用 conditional comment 将其仅用于 IE7。

    <!--[if IE 7]>
    <link ...your IE7 specific stylesheet goes here ... >
    <![endif]-->
    

    确保这段代码位于常规 css 文件的链接下方。

    【讨论】:

    • 您能否详细说明在这种特定情况下如何使用此技术?在大多数情况下,无论用户的浏览器如何,我都需要链接显示为内联块元素。但我需要在页面的这一特定部分覆盖该行为。
    • 然后你必须为他们制作一个特定的选择器。如果该部分位于具有特定类的 div 中,则可以执行 div.ib.blockbyclass a { /* Matches all links inside the second div */ } 之类的操作。但这只是标准的 CSS 规则。我会摆脱您现在使用的内联样式属性。那一定会给你带来麻烦。
    • 你的意思是这样? jsfiddle.net/StriplingWarrior/UBxhV 还是不行。我的问题不在于找到可以应用我想要的样式的 CSS 选择器。正如我在原帖中所说,问题在于 IE7 拒绝让新样式真正覆盖旧样式。
    • 如果你按照我的指示去做。将 IE7 的覆盖放在单独的 CSS 文件中,并从条件注释中链接到它。这会导致 IE 7 加载该文件,而其他所有浏览器都不理会它。您可以设置一些其他更明显的样式,以检查文件是否确实已加载。也不是说 IE(就像 Chrome)有一个非常彻底的缓存,所以它可能已经缓存了你的 css 的以前/旧版本。
    • 我不能用 jsfiddle 做到这一点,但我只是使用硬盘上的本地文件完成了你所说的一切,我在 IE7 中得到了完全相同的结果(当然,这会破坏其他浏览器,因为它们不再加载特殊的覆盖样式)。问题是,我并不想让 IE7 的行为与其他浏览器不同:我试图让它的行为与其他浏览器相同。即使所有的 CSS 优先规则都说我的 block 样式需要覆盖 inline-block 样式,IE7 仍然将链接呈现为 inline-block
    【解决方案5】:
    display: inline-block 
    

    对于 IE7 看起来像:

    *display: inline;
    zoom: 1
    

    【讨论】:

    • 我已经使用这个技巧来说服块级元素(如divs)表现得像inline-block 元素。不幸的是,当应用于链接时,它的行为似乎与display: inline-block 相同。 jsfiddle.net/mmpX3/18
    • jsfiddle.net/mmpX3/50 在 IE 7 中查看。您可以设置此链接的高度 (*display: inline)
    • 是的,这允许您设置高度,但现在链接不会像block 元素那样扩展以占用它提供的所有空间。
    • 在您的示例中,所有元素都有显示:块。显示:inline-block 元素永远不会占用所有宽度:jsfiddle.net/mmpX3/65
    • 更近了,但是如果我的锚有高度,它突然就不能再工作了。 jsfiddle.net/mmpX3/77 :-(
    【解决方案6】:

    display: inline-block 在 IE7 中与默认情况下不内联的元素不兼容,因此 IE 将忽略 DIV 的此规则。例如,如果您将 DIV 更改为 SPAN,则此示例应该可以工作。

    【讨论】:

    • display: inline-block; 在链接上,而不是在 div 上。
    【解决方案7】:

    事情是这样的:如果您需要 a 标记锚在它们自己的行上呈现,它们是块元素,而不是内联...事实上,您所说的并没有表明需要内联块。您的 divs 是浮动的,因此它们会在左侧堆叠成一行(但不是内联;它们在文档流之外,因此是 float)。

    试试这个...让我们把它全部剥离。这是您提供给我们的 HTML:

    <div class="normal">
        <a href="#">Test</a>
        <a href="#">Test longer</a>
    </div>
    <div class="ib blockbyclass">
        <a href="#">Test</a>
        <a href="#">Test longer</a>
    </div>
    <div class="ib">
        <a href="#" style="display: block;">Test</a>
        <a href="#" style="display: block;">Test longer</a>
    </div>
    

    使用您提供的 CSS,在 Safari 和 Firefox 中,我看到三个块,每个块有两个链接,每个都在自己的行上。但是,您在 IE7 中看到的不是两个 inline-block 元素,而是两个 inline 元素 - 原因是 IE7 不支持 inline-block,因为 hasLayout 错误(某些微软创建了一个过于复杂的简单问题)。换句话说,它不能忘记inline-block,因为它根本不理解inline-block(您误解了这是必要的),并且通过其默认显示行为(即inline)对待a

    如果它们需要在单独的行上并占据容器的宽度,您所要做的就是这个(在.ib a 上演示,完全忽略blockbyclass 在这种情况下似乎只是一个红鲱鱼):

    .ib a {display:block;}
    

    多田!宽度继承自父容器,a 采用默认的a 样式,一切正常。所以看看这个:

    <div class="ib">
        <a href="#" style="display: block;">Test</a>
        <a href="#" style="display: block;">Test longer</a>
    </div>
    

    在这种情况下,这变得多余,因此没有必要。你已经在阻止这些元素了。

    <div class="ib">
        <a href="#">Test</a>
        <a href="#">Test longer</a>
    </div>
    

    你只是把一些非常简单的事情复杂化了。

    这是一个小提琴:http://jsfiddle.net/dhYjZ/1/

    【讨论】:

    • ib 类旨在模拟我在系统范围内用于按钮的类,它适用于inline-block,因为它们通常必须能够彼此内联显示,但仍然具有应用了高度和边距等面向块的属性。我希望我可以覆盖ib 类以使这些按钮在特定情况下以block 形式出现(该示例在所有其他浏览器中的工作方式),但听起来hasLayout 将使这成为不可能让我在IE7中做。我可能不得不创建另一个克隆 ib 的类,但使用 block 布局。
    【解决方案8】:

    看来float 应该归咎于此。并不是IE7没有将该项目标记为block,我认为这是由于divfloat没有宽度。可以在这里看到:

    http://jsfiddle.net/mmpX3/129/

    通常,在使用旧版浏览器时,我发现

    在您的情况下,我建议添加一个固定宽度作为 JS Fiddle,或者如果不需要,请删除 float。如果我能看到浮动div 的用例,我或许可以想出一个替代方案。

    我不知道为什么 floatdisplay:inline-block 的组合会阻止 display:block 被重新实例化。这听起来像是一个可以解决的典型 IE7 错误。

    【讨论】:

      【解决方案9】:

      我不太确定您所追求的最终结果是什么。您是否试图使黑色背景成为一个包含两个链接而不是 2 个矩形(每个链接 1 个)的整个矩形?

      如果是这样,为什么不将背景应用于DIV 而不是链接?

      编辑: 似乎 IE7 存在一个错误,当适用于元素的规则之一具有 display: inline-block 时,即使 display 的另一个值优先,IE7 也会混合显示元素。

      如果您看到 http://jsfiddle.net/P2N5c/16/ ,那么具有 display: block 的规则是第一个(如使用 #blocky 规则的规则)还是最后一个都没关系。

      到目前为止,我不确定如何防止此错误,但您可以通过避免同时提供ibblockbyclass 的链接来绕过它,而只是给它提供使它们阻塞的类。 IE。不要给他们ib。不要添加一个类来切换 DIV 的状态,而是将一个类替换为另一个。

      【讨论】:

      • 为了将来参考,澄清问题通常应以 cmets 的形式发布,而不是答案。我正在尝试使所有按钮占用与列表中最长的按钮一样多的空间,因此如果您单击按钮区域内的任意位置,它将具有与单击文本相同的效果。
      • @StriplingWarrior 昨天我没有评论权限。再澄清一点,您提到您有一个只有ib 的DIV,然后还获得了一个带有ib blockbyclass 的DIV。 blockbyclass 是与脚本一起添加的,还是在页面加载时存在?哦,我明白了,锚获得了换行符,但未能抓住整个宽度(在 IE7 中)。
      【解决方案10】:

      简单地说,我用display:inline; 替换我所有的display:inline-block; 用法,并且我也有条件地这样做,就像上面提供的答案一样。

      通过您的示例,我发现以下成功:

      body{background-color: gray;}
      div{float:left; margin: 5px;}
      a {background-color: black; color: white;display:block;}
      

      Jsfiddle:http://jsfiddle.net/zL3Ea/

      【讨论】:

      • 请问……为什么是减号?上面的代码在浮动 div 中创建了链接,因为在您指定的所有浏览器中都是阻塞的。
      • 郑重声明:我不是给你-1的人。但是,我对您在第一段中解释的内容与您在发布的代码中实际执行的内容之间的区别感到困惑。该代码中没有任何 display:inline; 或任何条件选择器。这只是一个疏忽吗?
      • 抱歉,这只是处理 display:inline-block 的一般方法;对于 IE7。第二部分应该是最多汁的。
      • 第二部分只是去掉了当我的blockbyclass 类不存在时我需要应用的 inline-block 指令。恐怕这没什么用。
      【解决方案11】:

      看起来工作完成了。 我是 fork 你的代码,试试看:http://jsfiddle.net/Lkwzx/1/

      这一行的秘密:div.ib a { display: inline-block; *display: inline; }

      【讨论】:

      • 为了记录,我没有对此投反对票。但这与 Galled 的答案相同,并且像他的一样,当blockbyclass 不存在时,它不会使ib 链接应用inline-block
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 2012-03-04
      • 2011-04-14
      • 1970-01-01
      相关资源
      最近更新 更多