将边框放置在div内部而不是其边缘上

694

我有一个<div>元素,我想在它上面加边框。我知道可以写style="border: 1px solid black",但这会在 div 的两侧各添加 2px,这不是我想要的。

我希望这个边框是距离 div 边缘 -1px。div 本身是100px x 100px,如果我添加了边框,则必须进行一些计算才能使边框出现。

有没有一种方法可以让边框出现,并确保盒子仍然是100px(包括边框)?


3
说句实话,我为那些在这里寻找带有偏移量的内边框的人发布了一个解决方案(链接:https://dev59.com/Cmkw5IYBdhLWcg3w2-TG#50347410)。 - Danield
15个回答

812

box-sizing属性设置为border-box

div {
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    width: 100px;
    height: 100px;
    border: 20px solid #f00;
    background: #00f;
    margin: 10px;
}

div + div {
    border: 10px solid red;
}
<div>Hello!</div>
<div>Hello!</div>

支持IE8及以上版本。详情请查看兼容性列表


16
为了提供更多的背景信息:http://css-tricks.com/box-sizing/ 或 http://paulirish.com/2012/box-sizing-border-box-ftw/ - isotrope
199
这个方案仅有的缺陷是必须声明一个高度才能使其正常工作,如果没有高度,边框仍会位于块外并影响呈现(即垂直节奏)。 - jerclarke
5
注:如果不设置高度,代码将无法正常工作,因此jeremyclarke的说明应包含在答案中。 副注:最大高度也可以起作用,只要该div使用了该属性,如果高度未达到最大高度,则不起作用。 - user3052629
11
box-sizing的供应商前缀可以被删除。http://caniuse.com/#search=box-sizing - myconode
6
不,那不是答案。你需要知道高度。box-shadow解决方案是正确的方法。 - Craig
显示剩余6条评论

574

53
喜欢这个解决方案,因为它可以使边框完全保持在盒子内部,而不管有没有设置高度。如果您想要的是在盒子外部根本没有任何影响的边框,那么它就非常完美。以下是一个顶部边框为2px的CSS代码:"inset 0px 2px 0px 0px #DDD"。 - jerclarke
17
首选解决方案。顺便说一下,现今所有主流浏览器都支持无需前缀的普通 box-shadow。 - Pointer Null
4
其中的一个缺点是,一些浏览器无法正确地打印盒阴影,并始终将其打印为 #000。如果您需要能够打印页面,这可能会成为一个致命问题。 - Rob Fox
3
这在 img 元素上不起作用,因为 box-shadow 会被渲染在图像下方。 - Organic
1
@cgogolin 不,这是完全可行的!例如:box-shadow: 0 10px 0 0 #f00; - caitriona
显示剩余8条评论

136

也许这个回答有点晚了,但我想分享一下我的发现。我找到了两种新的解决方法,这里的答案中没有提到:

使用CSS属性box-shadow实现内边框

是的,box-shadow用于向元素添加阴影效果。但你可以指定 inset 阴影,它看起来更像是内边框而不是阴影。你只需要将水平和垂直阴影设置为 0px,并且将 box-shadow 的 "spread" 属性设置为你想要的边框宽度。所以对于 10px 的 'inner' 边框,你可以写如下代码:

div{
    width:100px;
    height:100px;
    background-color:yellow;
    box-shadow:0px 0px 0px 10px black inset;
    margin-bottom:20px;
}

这里是一个jsFiddle示例,演示了box-shadow边框和“普通”边框之间的区别。这种方式可以使您的边框和盒子宽度总共为100像素,包括边框。

更多关于box-shadow的信息:这里

通过outline CSS属性创建边框

这里是另一种方法,但是这样边框会在盒子外部。这里有一个示例。 从示例中可以看出,您可以使用CSS的outline属性来设置不影响元素宽度和高度的边框。这样,边框宽度不会添加到元素的宽度中。

div{
   width:100px;
   height:100px;
   background-color:yellow;
   outline:10px solid black;
}

了解更多轮廓线相关信息:这里


2
+1 对于大纲的使用,这是一种非常有效的方法,甚至您的w3schools页面也提到:“只有在指定了!DOCTYPE时,IE8才支持大纲属性。” - Armfoot
6
注意:轮廓线不遵循边框半径(在Chrome中测试过)。 - Nick
5
现在似乎对此表示尊重。 - user3071284

68

你可以使用outlineoutline-offset属性,并将值设置为负数,而不是使用常规的border,这对我很有效:

div{
    height: 100px;
    width: 100px;
    background-color: grey;
    margin-bottom: 10px; 
}

div#border{
    border: 2px solid red;
}

div#outline{
    outline: 2px solid red;
    outline-offset: -2px;
}
Using a regular border.
<div id="border"></div>

Using outline and outline-offset.
<div id="outline"></div>


一个问题是这个边框在div包含的元素之上。 - undefined

63

雅虎!这真的是可能的。我找到它了。

对于底部边框:

div {box-shadow: 0px -3px 0px red inset; }

顶部边框:

div {box-shadow: 0px 3px 0px red inset; }

48
尽管此问题已经得到了充分的回答,使用box-shadowoutline属性的解决方案,但我想稍微扩展一下,为那些像我一样搜索具有偏移量内边框解决方案的人提供帮助。
假设您有一个黑色的100px x 100px div,并且您需要用白色边框嵌入它 - 它具有5px(例如)的内部偏移 - 仍然可以使用上述属性来实现。

box-shadow

诀窍在于要知道允许多个box-shadow,其中第一个阴影在顶部,随后的阴影具有更低的z-ordering。
因此,box-shadow声明将是:
box-shadow: inset 0 0 0 5px black, inset 0 0 0 10px white;

div {
  width: 100px;
  height: 100px;
  background: black;
  box-shadow: inset 0 0 0 5px black, inset 0 0 0 10px white; 
}
<div></div>

基本上,该声明的意思是:先渲染最后的(10px白色)阴影,然后在其上方渲染前面的5px黑色阴影。

outlineoutline-offset一起使用

为了达到与上述相同的效果,outline声明应为:

outline: 5px solid white;
outline-offset: -10px;

div {
  width: 100px;
  height: 100px;
  background: black;
  outline: 5px solid white;
  outline-offset: -10px;
}
<div></div>

NB: 如果你觉得这很重要,需要注意的是,outline-offset 在IE浏览器中不被支持


Codepen演示


40
使用伪元素:pseudo element

.button {
    background: #333;
    color: #fff;
    float: left;
    padding: 20px;
    margin: 20px;
    position: relative;
}

.button::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border: 5px solid #f00;
}
<div class='button'>Hello</div>

使用::after,您可以对所选元素的虚拟最后一个子元素进行样式设置。content属性创建一个匿名替换元素

我们使用绝对定位相对于父元素来包含伪元素,这样您就可以在主元素的背景中具有自定义的背景和/或边框。

此方法不会影响主元素内容的位置,这与使用box-sizing: border-box;是不同的。

考虑以下示例:

.parent {
    width: 200px;
}

.button {
    background: #333;
    color: #fff;
    padding: 20px;
    border: 5px solid #f00;
    border-left-width: 20px;
    box-sizing: border-box;
}
<div class='parent'>
    <div class='button'>Hello</div>
</div>

这里.button的宽度受到父元素的限制。设置border-left-width可以调整内容框大小,从而影响文本位置。

.parent {
    width: 200px;
}

.button {
    background: #333;
    color: #fff;
    padding: 20px;
    position: relative;
}

.button::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border: 5px solid #f00;
    border-left-width: 20px;
}
<div class='parent'>
    <div class='button'>Hello</div>
</div>

使用伪元素方法不会影响内容框大小。

根据应用程序的情况,使用伪元素方法可能是一种理想的行为,也可能不是。


如果你的方框内包含一张图片,这是最佳解决方案。其他所有方法都会缩小图片尺寸。 - Jason
1
如果你需要边框不同边的不同颜色,这个解决方案非常棒。 - undefined

10

11年过去了,但这里是答案:

只需使用 outline 属性:
outline: 0.2vw solid red;

希望我能帮到在 11 年后看到此问题的人。


2
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Prateek Varshney
人们已经提到了大纲。 - BlueEyesWhiteDragon
即使这是11年后,我仍然感谢您的答案。 - Cristian Rusanu

6

我知道这篇文章有点老了,但由于搜索关键词“内边框”直接带我来到这里,所以我想分享一些可能值得在这里提及的发现。 当我在悬停状态下添加边框时,我得到了OP所说的效果。边框会增加盒子的尺寸,使其跳动。 还有两种方法可以解决这个问题,它们也适用于IE7。

1)已经将边框附加到元素上,只需更改颜色即可。这样数学计算已经包括在内。

div {
   width:100px;
   height:100px;
   background-color: #aaa;
   border: 2px solid #aaa; /* notice the solid */
}

div:hover {
   border: 2px dashed #666;
}

2) 通过负 margin 来弥补边框。这样仍然可以添加额外的像素,但元素的定位不会跳动。

div {
   width:100px;
   height:100px;
   background-color: #aaa;
}

div:hover {
  margin: -2px;
  border: 2px dashed #333;
}

3
为了在新旧浏览器之间呈现一致,添加一个双容器,外部容器设置宽度,内部容器设置边框。
<div style="width:100px;">
<div style="border:2px solid #000;">
contents here
</div>
</div>

这显然只有在精确的宽度比具有额外的标记更重要时才需要这样做!

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