167

是否可以在 CSS 中控制虚线边框笔划之间的长度和距离?

下面的示例在浏览器之间显示不同:

div {
  border: dashed 4px #000;
  padding: 20px;
  display: inline-block;
}
<div>I have a dashed border!</div>

重大差异:IE 11 / Firefox / Chrome

IE 11 边框火狐边框镀铬边框

是否有任何方法可以更好地控制虚线边框的外观?

4

10 回答 10

186

原生虚线边框属性值不提供对虚线本身的控制......所以带上border-image属性!

酿造自己的边界border-image

兼容性:它提供了很好的浏览器支持(IE 11 和所有现代浏览器)。可以将普通边框设置为旧浏览器的后备。

让我们创建这些

这些边框将显示完全相同的跨浏览器!

目标示例 差距更大的目标示例

第 1 步 - 创建合适的图像

此示例为 15 像素宽 x 15 像素高,间隙当前为 5 像素宽。它是一个具有透明度的 .png。

这是放大后在 Photoshop 中的样子:

示例边框图像背景放大

这是缩放的样子:

示例边框图像背景实际大小

控制间隙和行程长度

要创建更宽/更短的间隙或笔划,请加宽/缩短图像中的间隙或笔划。

这是一张宽 10px 间隙的图像:

更大的间隙正确缩放 =规模差距更大

第 2 步 - 创建 CSS - 此示例需要 4 个基本步骤

  1. 定义边界图像源

    border-image-source:url("http://i.stack.imgur.com/wLdVc.png");  
    
  2. 可选- 定义边框图像宽度

    border-image-width: 1;
    

    默认值为 1。它也可以设置为像素值、百分比值或其他倍数(1x、2x、3x 等)。这会覆盖任何border-width集合。

  3. 定义边界图像切片

    在这个例子中,图片的上下左右边框的厚度是2px,它们之间没有间隙,所以我们的切片值为2:

    border-image-slice: 2; 
    

    切片看起来像这样,距离顶部、右侧、底部和左侧 2 个像素:

    切片示例

  4. 定义边界图像重复

    在这个例子中,我们希望模式在我们的 div 周围均匀地重复。所以我们选择:

    border-image-repeat: round;
    

写作速记

上面的属性可以单独设置,也可以使用border-image简写:

border-image: url("http://i.stack.imgur.com/wLdVc.png") 2 round;

完整示例

注意border: dashed 4px #000后备。不支持的浏览器将收到此边框。

.bordered {
  display: inline-block;
  padding: 20px;
  /* Fallback dashed border
     - the 4px width here is overwritten with the border-image-width (if set)
     - the border-image-width can be omitted below if it is the same as the 4px here
  */
  border: dashed 4px #000;
  
  /* Individual border image properties */
  border-image-source: url("http://i.stack.imgur.com/wLdVc.png");
  border-image-slice: 2;
  border-image-repeat: round;  
  
  /* or use the shorthand border-image */
  border-image: url("http://i.stack.imgur.com/wLdVc.png") 2 round;
}


/*The border image of this one creates wider gaps*/
.largeGaps {
  border-image-source: url("http://i.stack.imgur.com/LKclP.png");
  margin: 0 20px;
}
<div class="bordered">This is bordered!</div>

<div class="bordered largeGaps">This is bordered and has larger gaps!</div>

于 2014-11-11T05:29:11.137 回答
127

除了border-image属性之外,还有其他一些方法可以创建虚线边框,并控制笔划的长度和它们之间的距离。它们描述如下:

方法一:使用 SVG

我们可以通过使用 apath或 apolygon元素并设置stroke-dasharray属性来创建虚线边框。该属性有两个参数,其中一个定义破折号的大小,另一个确定它们之间的空间。

优点:

  1. SVG 本质上是可扩展的图形,可以适应任何容器尺寸。
  2. border-radius即使有参与,也能很好地工作。我们只需要在这个答案path中用circle类似的替换(或)将 转换为圆形。path
  3. 浏览器对 SVG的支持非常好,并且可以使用 IE8 的 VML 提供回退。

缺点:

  1. 当容器的尺寸没有按比例变化时,路径往往会缩放,从而导致破折号的大小和它们之间的空间发生变化(尝试将鼠标悬停在片段中的第一个框上)。这可以通过添加来控制vector-effect='non-scaling-stroke'(如在第二个框中),但浏览器对此属性的支持在 IE 中为零。

.dashed-vector {
  position: relative;
  height: 100px;
  width: 300px;
}
svg {
  position: absolute;
  top: 0px;
  left: 0px;
  height: 100%;
  width: 100%;
}
path{
  fill: none;
  stroke: blue;
  stroke-width: 5;
  stroke-dasharray: 10, 10;
}
span {
  position: absolute;
  top: 0px;
  left: 0px;
  padding: 10px;
}


/* just for demo */

div{
  margin-bottom: 10px;
  transition: all 1s;
}
div:hover{
  height: 100px;
  width: 400px;
}
<div class='dashed-vector'>
  <svg viewBox='0 0 300 100' preserveAspectRatio='none'>
    <path d='M0,0 300,0 300,100 0,100z' />
  </svg>
  <span>Some content</span>
</div>

<div class='dashed-vector'>
  <svg viewBox='0 0 300 100' preserveAspectRatio='none'>
    <path d='M0,0 300,0 300,100 0,100z' vector-effect='non-scaling-stroke'/>
  </svg>
  <span>Some content</span>
</div>


方法 2:使用渐变

我们可以使用多个linear-gradient背景图像并适当地放置它们以创建虚线边框效果。这也可以使用 a 来完成,repeating-linear-gradient但由于使用了重复梯度,因此没有太大改进,因为我们需要每个梯度仅在一个方向上重复。

.dashed-gradient{
  height: 100px;
  width: 200px;
  padding: 10px;
  background-image: linear-gradient(to right, blue 50%, transparent 50%), linear-gradient(to right, blue 50%, transparent 50%), linear-gradient(to bottom, blue 50%, transparent 50%), linear-gradient(to bottom, blue 50%, transparent 50%);
  background-position: left top, left bottom, left top, right top;
  background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
  background-size: 20px 3px, 20px 3px, 3px 20px, 3px 20px;
}

.dashed-repeating-gradient {
  height: 100px;
  width: 200px;
  padding: 10px;
  background-image: repeating-linear-gradient(to right, blue 0%, blue 50%, transparent 50%, transparent 100%), repeating-linear-gradient(to right, blue 0%, blue 50%, transparent 50%, transparent 100%), repeating-linear-gradient(to bottom, blue 0%, blue 50%, transparent 50%, transparent 100%), repeating-linear-gradient(to bottom, blue 0%, blue 50%, transparent 50%, transparent 100%);
  background-position: left top, left bottom, left top, right top;
  background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
  background-size: 20px 3px, 20px 3px, 3px 20px, 3px 20px;
}

/* just for demo */

div {
  margin: 10px;
  transition: all 1s;
}
div:hover {
  height: 150px;
  width: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='dashed-gradient'>Some content</div>
<div class='dashed-repeating-gradient'>Some content</div>

优点:

  1. 即使容器的尺寸是动态的,也可以扩展并且可以适应。
  2. 不使用任何额外的伪元素,这意味着它们可以留作任何其他潜在用途。

缺点:

  1. 浏览器对线性渐变的支持相对较低,如果你想支持 IE 9-,这是不行的。甚至像 CSS3 PIE 这样的库也不支持在 IE8- 中创建渐变模式。
  2. 无法在border-radius涉及时使用,因为背景不基于border-radius. 相反,它们会被剪掉。

方法 3:盒子阴影

我们可以使用伪元素创建一个小条(以破折号的形状),然后创建box-shadow它的多个版本以创建一个边框,如下面的片段所示。

如果破折号是正方形,那么单个伪元素就足够了,但如果它是矩形,我们需要一个伪元素用于顶部 + 底部边框,另一个用于左 + 右边框。这是因为顶部边框上破折号的高度和宽度将与左侧不同。

优点:

  1. 破折号的尺寸可以通过改变伪元素的尺寸来控制。间距可以通过修改每个阴影之间的间距来控制。
  2. 通过为每个盒子阴影添加不同的颜色,可以产生非常独特的效果。

缺点:

  1. 由于我们必须手动设置破折号的尺寸和间距,因此当父框的尺寸是动态的时,这种方法并不好。
  2. IE8 及更低版本不支持 box shadow。但是,这可以通过使用 CSS3 PIE 等库来克服。
  3. 可以使用,border-radius但定位它们会非常棘手,因为必须在圆上找到点(甚至可能transform)。

.dashed-box-shadow{
  position: relative;
  height: 120px;
  width: 120px;
  padding: 10px;
}
.dashed-box-shadow:before{ /* for border top and bottom */
  position: absolute;
  content: '';
  top: 0px;
  left: 0px;
  height: 3px; /* height of the border top and bottom */
  width: 10px; /* width of the border top and bottom */
  background: blue; /* border color */
  box-shadow: 20px 0px 0px blue, 40px 0px 0px blue, 60px 0px 0px blue, 80px 0px 0px blue, 100px 0px 0px blue, /* top border */
    0px 110px 0px blue, 20px 110px 0px blue, 40px 110px 0px blue, 60px 110px 0px blue, 80px 110px 0px blue, 100px 110px 0px blue; /* bottom border */
}
.dashed-box-shadow:after{ /* for border left and right */
  position: absolute;
  content: '';
  top: 0px;
  left: 0px;
  height: 10px; /* height of the border left and right */
  width: 3px; /* width of the border left and right */
  background: blue; /* border color */
  box-shadow: 0px 20px 0px blue, 0px 40px 0px blue, 0px 60px 0px blue, 0px 80px 0px blue, 0px 100px 0px blue, /* left border */
    110px 0px 0px blue, 110px 20px 0px blue, 110px 40px 0px blue, 110px 60px 0px blue, 110px 80px 0px blue, 110px 100px 0px blue; /* right border */
}
<div class='dashed-box-shadow'>Some content</div>

于 2015-07-09T11:19:42.810 回答
30

@kovart制作了一个很酷的工具,称为虚线边框生成器

它使用 svg 作为背景图像,以允许设置您想要的笔划破折号数组,并且非常方便。

然后,您只需将其用作元素的背景属性来代替边框:

div {
  background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='black' stroke-width='4' stroke-dasharray='6%2c 14' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
  padding: 20px;
  display: inline-block;
}
于 2020-05-23T16:31:47.627 回答
26

短一:不,不是。您将不得不使用图像。

于 2010-05-05T07:03:24.667 回答
26

Css 渲染是特定于浏览器的,我不知道对其进行任何微调,您应该按照 Ham 的推荐使用图像。参考:http ://www.w3.org/TR/CSS2/box.html#border-style-properties

于 2010-05-05T07:20:55.477 回答
9

行程长度取决于行程宽度。您可以通过增加宽度来增加长度,并通过内部元素隐藏部分边框。

编辑:pointer-events: none;感谢 benJ 。

.thin {
    background: #F4FFF3;
    border: 2px dashed #3FA535;  
    position: relative;
}

.thin:after {
    content: '';
    position: absolute;
    left: -1px;
    top: -1px;
    right: -1px;
    bottom: -1px;
    border: 1px solid #F4FFF3;
    pointer-events: none;
}

https://jsfiddle.net/ksf9zoLh/

于 2019-12-12T14:03:00.237 回答
8

更新 感谢 kovart 这个伟大的工具尝试它 https://kovart.github.io/dashed-border-generator/

生成虚线自定义边框的工具

我的回答是:

我最近遇到了同样的问题。我已经解决了这个问题,希望它会对某人有所帮助。

HTML + 顺风

<div class="dashed-border h-14 w-full relative rounded-lg">
    <div class="w-full h-full rounded-lg bg-page z-10 relative">
        Content goes here...
    <div>
</div>

CSS

.dashed-border::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: calc(100% + 4px);
  transform: translateY(-50%);
  background-image: linear-gradient(to right, #333 50%, transparent 50%);
  background-size: 16px;
  z-index: 0;
  border-radius: 0.5rem;
}
.dashed-border::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  height: 100%;
  width: calc(100% + 4px);
  transform: translateX(-50%);
  background-image: linear-gradient(to bottom, #333 50%, transparent 50%);
  background-size: 4px 16px;
  z-index: 1;
  border-radius: 0.5rem;
}
于 2021-01-09T09:29:20.047 回答
2
.outline {
    outline: 48px dashed #d5fb62;
    outline-offset: -4px;
    overflow:hidden;
}

如果溢出隐藏没有问题,否则大纲 4 而不是 48。

<div class="outline"></div>
于 2021-10-15T10:04:39.370 回答
0

我最近遇到了同样的问题。

我设法通过两个带有边框的绝对定位的 div(一个用于水平,一个用于垂直)来解决它,然后对其进行转换。外盒只需相对定位即可。

<div class="relative">
    <div class="absolute absolute--fill overflow-hidden">
        <div class="absolute absolute--fill b--dashed b--red"
            style="
                border-width: 4px 0px 4px 0px;
                transform: scaleX(2);
        "></div>
        <div class="absolute absolute--fill b--dashed b--red"
            style="
                border-width: 0px 4px 0px 4px;
                transform: scaleY(2);
        "></div>
    </div>

    <div> {{Box content goes here}} </div>
</div>

注意:我在这个例子中使用了超光速粒子,但我猜这些类是不言自明的。

于 2020-02-07T08:17:14.073 回答
-2

这将使用 div 上的 class="myclass" 制作橙色和灰色边框。

.myclass {
    outline:dashed darkorange  12px;
    border:solid slategray  14px;
    outline-offset:-14px;
}
于 2019-11-13T21:28:16.100 回答