这是 CSS 生活中的一个事实,任何块级元素的“边框”都会被计算到其最终的布局框大小中。这意味着,如果您在悬停时添加一个边框到一个以前没有完全相同大小边框的元素上,您将会导致布局发生变化。这绝对是我最讨厌的事情之一,当我看到它出现在最终的设计中时。我发现这些小小的变化,即使只有 1 个像素,也会让人感觉不和谐和笨拙。(一个简短的视频示例)
CSS 为我们提供了一个非常有用的属性,它允许创建不会影响布局的边框,那就是outline属性。Outline 很不错,但它也有局限性,您无法只应用其中的一面。它要么全部应用,要么不应用。此外,outline 只能应用在元素的外部。我们将使用普通的border属性来解决这个问题,从而创建一些内部边框。
问题 CSS
#example-problem a img, #example-problem a { border: none; float: left; }
#example-problem a:hover { border: 3px solid black; }
这段 CSS 在悬停时应用了一个边框,而之前并没有边框。由此导致布局问题。
修复方案 #1:内部边框
#example-one a img, #example-one a { border: none; overflow: hidden; float: left; } #example-one a:hover { border: 3px solid black; } #example-one a:hover img { margin: -3px; }
这段 CSS 在图片的四边应用了一个负边距,该边距的大小与边框的大小相同。这将把边框拉到内部,不会导致布局发生变化。
修复方案 #2:外部边框
#example-two a img, #example-two a { border: none; float: left; } #example-two a { margin: 3px; } #example-two a:hover { outline: 3px solid black; }
这段 CSS 使用 outline 属性来确保布局不发生变化。或者,您可以应用与背景色相同的边框颜色,并在悬停时仅更改其颜色,但这更优雅。
感谢 Ney Ricardo Barão,他从 这个网站 获得了这个想法。
修复方案 #3:更改盒子模型
如果元素的宽度包含了边框宽度,就不会出现这个问题。 所以您可以更改它。
修复方案 #4:裁剪
读者 Mattijs Bliek 提供了另一个想法
然而,当图片位于一个包含元素内部时,有一个更简单的跨浏览器解决方案。您可以使用 css clip 属性来裁剪图片,然后应用一个常规边框。您只需要将图片的裁剪区域移动与边框宽度相同的像素数。例如,如果您有一个 60×60 的图片,并且想要一个 1 像素的边框,您可以在左侧裁剪 1 像素,顶部裁剪 1 像素,并将其宽度和高度设置为 58 像素(所有这些都通过 css clip 属性完成)。
再说一次,outline 并不被所有浏览器支持,是吗?如果您对图片设置了固定宽度/高度,为什么不直接使用 3 像素的白色边框 - 与背景色相同?
Outline 在 IE 8 中不起作用。
查看 w3schools 参考页面 上关于 css 属性的说明
Outline 仍然是正确的做法。必要时,一定要考虑使用 IE 条件样式表。
我倾向于认为“正确”的方式应该是用户使用的浏览器支持的方式,无论 WC3 说的是什么。
选项 #1 是一个好主意。谢谢你的提示。
抱歉,我的意思是“W3C”。
就我个人而言,我认为现在该停止为 IE 做出例外了。设计符合标准,忽略 Internet Explorer。
当事情开始出错时,公众就会意识到 IE 的问题,而微软将面临着修复他们的垃圾代码或失去市场份额的选择,因为愤怒的用户会离开。
Firefox 的市场份额高达 20%(Safari、Opera、Chrome 等的总和也很高),而且还在不断上升,人们每天都在离开 IE。现在该改变了。
当你在一个流量很大的网站上工作时,你不能忽略 IE。如果你这样做,你的公司会受到损失。
如果我们可以用 javascript 做到,为什么不呢?我认为这将是比 IE 条件样式表更好的解决方案。
我认为我们现在不应该在 IE8 中测试,因为它是一个实际上不支持某些微软网站的浏览器;)。我一直使用修复方案 #1,因为我不想让 outline 覆盖其他内容,例如其他图片。
干杯
Simon
简单但超级棒。很棒的提示!
不错 :) 酷
我甚至不知道这个标签 *脸红*. 除了主流浏览器中的 IE 之外,还有其他浏览器不支持它吗?
内部边框解决方案真是太棒了。我一直觉得,如果你想在悬停时添加边框,图片之间必须有间隙,这很烦人,不过可惜的是它在 IE8 中不起作用。
另一个在发布之前就出现的缺陷。
正是像这样的小细节才造就了网络上“漂亮、专业的网站”和“你表弟给你做的这个?”之间的区别。干净、快速,最重要的是易于实现!
谢谢你的提示
太棒了!
或者,在修复方案 #2 中,您可以使用“border”代替 outline,并在悬停时添加 margin:0px。
https://css-tricks.cn/image-rollover-borders-that-do-not-change-layout/ - 外部边框似乎在 IE7 中不起作用
example-problem a img, #example-problem a { border: 3px solid transparent; float: left; }
example-problem a:hover { border: 3px solid black; }
好技巧!之前不知道内部边框修复方法
这个问题太烦人了。太可惜了,我们不能只做 border-align: inside; 或者其他什么东西。不过这些都是不错的解决方法,值得记在本子上。
我被这个说法弄糊涂了,它说在 IE 8 中不起作用?我使用 IE Tester 的最新版本,用 IE8 RC1,演示页面按预期工作?
至于其他 IE 的支持,内部边框似乎在 IE 6 和 7 中也能按预期工作。但外部边框完全不起作用。
查看 Outline 支持,我遇到的所有资源都表明 Outline 在 IE 中根本不支持。我已经把这句话记在脑子里好几年了。有人告诉我它不起作用,我就从没测试过。现在我测试了,它竟然可以?
好吧,那里完全是错误的。
“查看 Outline 支持,我遇到的所有资源都表明 Outline 在 IE 中根本不支持。我已经把这句话记在脑子里好几年了。有人告诉我它不起作用,我就从没测试过。现在我测试了,它竟然可以?”
简单且不错的技巧。
不错!很酷的技巧
我喜欢选项 #1,
对于选项 #2,如何在 jQuery 中使用 CSS。
$(‘#example-two a’).hover(function() {
$(this).css(‘outline’,’3px solid #000′);
}, function() {
$(this).css(‘outline’,’0′);
});
但这并不是真正的 CSS 方法.. :(
图像在网格中,布局发生偏移一直是个问题…
感谢分享解决方案… :D
谢谢 Chris!你回邮件给我时,我并不知道 outline 属性,这真是个很棒的学习机会。
感谢分享!
修复 #3:背景颜色和填充。(图像缩小了)
哇,这真是个更好的实现方式。我以前总是把图像封装在一个 div 中,然后让它的背景发生变化。(顺便说一句,我现在知道更好的方法了!)
非悬停时使用透明边框怎么样?
这与是否显示边框无关,而是边框的位置。;) 无论你是否让它可见,都需要那个空间。
Simon.
twitter.com/simoncolijn
我一直用 Ryan 的方法,但是用颜色代替透明
example-problem a img, #example-problem a { border: 3px solid *white*; float: left; }
example-problem a:hover { border: 3px solid black; }
一开始就设置 3 像素的白色边框,我认为你把问题复杂化了。
我从没听说过内部边框;好吧,我可能用过,只是没意识到,或者没记下代码。:P
真可爱!非常实用的技巧。
以前从没用过负边距。很巧妙的技巧。
我认为
background-color
可以解决很多问题,#example-one a {background-color:none;}
#example-one a:hover {background-color:black}
#example-one a img {margin: 3px}
以前从没用过负边距,很棒的教程
感谢您的技巧!
正如 Chris(另一个)所说,对于修复 #2,我会使用 margin: 0 和 border 而不是 outline。
非常酷
先设置一个默认边框,然后只在悬停时改变颜色,而不是改变宽度,这有多难???
Outline 用于浏览器指示元素何时被选中,因此不适合悬停效果。
简单且聪明,我喜欢修复 #1
感谢您提供简单易学的 CSS 悬停教程!这是 W3C 兼容的 CSS 吗?
来源:w3schools
非常感谢,我甚至不知道
outline
属性!你也可以使用 box shadows..
box-shadow : 0px 0px 0px 5px #000;
使用 box-sizing(修复 3)有缺点吗?我注意到它现在默认包含在 underscore.me 等入门主题中,它似乎是最不 hackish 的..?
我使用的一个修复方法是,对于列表等单边边框,向所有列表项添加一个边框,如果需要,只需更改边框颜色。这样可以防止布局发生变化。