:hover:before文本装饰无效果?

37

就像标题所述,我正在使用.icon-*添加图标。在将图标添加到超链接时:

<a href="#" class="icon-email icon-large">Email me!</a>

content属性插入的内容在悬停时显示下划线文本修饰。我想仅针对前面的内容禁用text-decoration

[class^="icon-"]:before, [class*=" icon-"]:before {
    font-family: 'IcoMoon';
    font-style: normal;
    speak: none;
}
.icon-mail:before {
    content: "\37";
}
[class^="icon-large-"]:before, [class*=" icon-large"]:before {
    font-size: 48px;
    line-height: 48px;
}
a[class^="icon-"]:before, a[class*=" icon-"]:before {
    margin-right: 5px;
    vertical-align: middle;
}
我尝试过这个方法,但它并没有起作用(装饰仍然可见):
a[class^="icon-"]:hover:before, a[class*=" icon-"]:hover:before {
    text-decoration: none;
    color: white;
}

你不能使用伪元素来完成这个任务,你需要使用JS。 - Bojangles
是的,您不能像那样在没有JavaScript的情况下双重使用伪元素和伪类。我建议使用JavaScript来处理:before而不是处理:hover。因为不是所有的浏览器都支持:before。但这只是我的个人意见。 - BumbleB2na
@BumbleB2na 至少支持IE8+,FF10.0.2+,Opera 11.61+,Safari 5.1.2+,Chrome 17 http://www.quirksmode.org/css/contents.html - gremo
@BumbleB2na:你可以这样做-伪元素只需要是选择器中的最后一个。 - BoltClock
我注意到类和属性选择器中存在一些错别字,尽管这与手头的问题无关。特别是,您的icon-large属性选择器可以简单地更改为.icon-large:before(但我假设您只将其作为独立类而不是其他类的前缀)。 - BoltClock
6个回答

58

在你的CSS中插入"display:inline-block;",就像下面这个样子:

.icon-mail:before {
    content: "\37";
    display:inline-block;
    text-decoration:none;
}

这里是 JS FIDDLE:

http://jsfiddle.net/73p2k/18/


1
非常感谢您分享这个技巧。我从来没有想过要添加它。 - Matt.
4
@acme,请查看最新的jsfiddler以支持IE。已在IE9中进行了测试 http://jsfiddle.net/73p2k/18/ - Pinoy2015
所以在IE中,您必须将 text-decoration:underline; 设置为 a:before 并且将 text-decoration:none; 设置为 a:hover:before。这似乎是一个bug。谢谢 Pinoy2015! - Philipp Michael
4
这个真的有效...只适用于inline-block.... 你能解释一下为什么会这样吗?你是如何得出这个结论的? - Alexandr
1
在我的情况下,这是实际解决方案。 - Marco Cazzaro

30

由于:before伪元素作为其生成元素的后代框的一部分(更具体地说,位于第一个子内容框的前面),所以它遵循text-decoration相关的普通后代框相同的规则

后代元素上的"text-decoration"属性对祖先的装饰没有任何影响。

有关详细信息,请参阅以下答案:

这方面没有好的解决办法...立即想到的唯一替代方法是:

  • Wrap the text in its own span element, then apply text-decoration to that span, as shown by skip405. The disadvantage is, of course, extra markup.

  • Use an inline block background image instead of inline text in an icon font with your :before pseudo-element (I've also corrected the inconsistencies with your class selectors):

    [class^="icon-"]:before, [class*=" icon-"]:before {
        display: inline-block;
        width: 1em;
        height: 1em;
        background-size: contain;
        content: "";
    }
    .icon-email:before {
        background-image: url(icon-mail.svg);
        background-repeat: no-repeat;
    }
    .icon-large:before {
        width: 48px;
        height: 48px;
    }
    a[class^="icon-"]:before, a[class*=" icon-"]:before {
        margin-right: 5px;
        vertical-align: middle;
    }
    

    The advantage this has over skip405's solution is that you don't have to modify the HTML, but given that it uses SVG vector background images and background-size, it won't work in IE8.

    If you do need IE8 support, then you have to fall back to bitmap images:

    .icon-email:before {
        background-image: url(icon-mail.png);
    }
    .icon-email.icon-large:before {
        background-image: url(icon-mail-large.png);
    }
    

非常感谢你的时间和出色的解释。我会采用额外的标记解决方案。 - gremo
请参阅以下更新的答案。 - Jay

4
你可以为:before元素设置高度和overflow:hidden,这样文字修饰就不会可见 :)

4

伪元素选择器必须是选择链中的最后一项。

你可以将样式应用于element:hover:before,但不能将其应用于element:before:hover


确实是这样,标题错了,问题是正确的。我会修复它。 - gremo

2
尝试使用仅 a 标记作为标记,但不幸的是。你可能需要一个解决方法,即将链接内部包装在另一个元素中,例如 span。因此,您可以在此元素上拥有下划线(而不是伪元素)- 这完全由 css 控制。
这里有一个实时示例:http://jsfiddle.net/skip405/fQHUH/

1

这个解决方案对我很有效。它排除了伪元素。 但是为此,您需要将<a>标签的内容包装在额外的元素中。

a:hover { text-decoration: none; }
a:hover > * { text-decoration: underline; }


<a href="#"><span>content</span></a>

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