控制虚线边框的笔触长度和笔触之间的距离


124

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

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

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

较大的不同:IE 11 / Firefox / Chrome

IE 11边框Firefox边框镀铬边框

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

Answers:



157

原始的虚线边框属性值本身无法控制虚线...因此,请启用该border-image属性!

酿造自己的边界 border-image

兼容性:它提供了出色的浏览器支持(IE 11和所有现代浏览器)。可以将常规边框设置为旧版浏览器的后备。

让我们创建这些

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

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

第1步-创建合适的图像

此示例为15像素宽乘以15像素高,并且间隙当前为5px宽。这是具有透明度的.png文件。

这是放大后在photoshop中的外观:

示例边框图像背景被炸毁

这看起来像是要缩放:

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

控制间隙和行程长度

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

这是一个具有10px较大间隙的图像:

更大的差距 正确缩放= 更大的差距

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

  1. 定义border-image-source

    border-image-source:url("http://i.stack.imgur.com/wLdVc.png");  
  2. 可选 -定义border-image-width

    border-image-width: 1;

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

  3. 定义border-image-slice

    在此示例中,图像的顶部,右侧,底部和左侧边框的厚度为2px,并且它们之间没有间隙,因此我们的切片值为2:

    border-image-slice: 2; 

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

    切片示例

  4. 定义border-image-repeat

    在此示例中,我们希望模式在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>


请注意,border-style: solid如果您忽略后备广告,则需要指定(或类似内容)。
Robbendebiene

该解决方案不符合“边框颜色”属性的工作
迈克尔Rovinsky

100

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

方法1:使用SVG

我们可以使用pathpolygon元素并设置来创建虚线边框stroke-dasharray属性。该属性采用两个参数,其中一个定义短划线的大小,另一个确定它们之间的间距。

优点:

  1. SVG本质上是可扩展的图形,可以适应任何容器尺寸。
  2. 即使border-radius涉及到也可以很好地工作。我们只想已经取代pathcircle这个答案(或)转换path成一个圆圈。
  3. 浏览器对SVG的支持非常好,可以使用VML for IE8-提供回退。

缺点:

  1. 当容器的尺寸不按比例变化时,路径会按比例缩放,从而导致仪表板及其之间的间距发生变化(尝试将鼠标悬停在摘要中的第一个框上)。可以通过添加来控制vector-effect='non-scaling-stroke'(如第二个框中所示),但是IE中浏览器对此属性的支持为nil。


方法2:使用渐变

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

优点:

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

缺点:

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

方法3:框阴影

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

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

优点:

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

缺点:

  1. 由于我们必须手动设置破折号和间距的尺寸,因此当父级框的尺寸是动态的时,这种方法不好。
  2. IE8和更低版本不支持框阴影。但是,可以通过使用CSS3 PIE之类的库来克服这一问题。
  3. 可以与之配合使用,border-radius但定位它们将非常麻烦,因为必须在圆上(甚至可能在transform)上找到点。


如果您要使用svg解决方案,建议您添加pointer-events:none到svg中,以便能够与内容进行交互。
Sodj

奇妙的答案。
越轨

22

简短的一句话:不,不是。您将不得不处理图像。


5
截至2018
-godblessstrawberry

2
@WilliamHampshire我会使用这种技术youtu.be/vs34f9FiHps?t=779,但是请检查已接受的答案,您可能会更喜欢其他解决方案
godblessstrawberry

1
@godblessstrawberry谢谢!但是,那是使用SVG,所以仍然不仅仅使用CSS ...
William Hampshire

1
@WilliamHampshire我的意思是哈里回答的线程中有阴影的解决方案
godblessstrawberry

@godblessstrawberry您是否尝试过解决方案?解决方案逐段绘制虚线。这只是一个POC,实际上没有用!
于建荣

6

@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;
}

这是一个简单,便捷的解决方案
jamesioppolo

效果很好!
凯文·拉斐

3

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

.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;
}

https://jsfiddle.net/ok6srt2z/


但是这样一来,您将无法单击原始元素的内容,因为“ after”伪元素将覆盖它。因此最好的方法是使用SVG。
ili4

您可以添加pointer-events: none以防止覆盖问题。
benJ

0

我最近也有同样的问题。

我设法通过两个绝对定位的div来解决此问题,这些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>

注意:在此示例中,我使用了tachyons,但是我猜这些类是不言自明的。


-1

这将在div上使用class =“ myclass”形成橙色和灰色边框。

.myclass {
    outline:dashed darkorange  12px;
    border:solid slategray  14px;
    outline-offset:-14px;
}

如问题开头所述,通过“对虚线边框的外观提供更好的控制”,OP(原始海报)表示他希望控制每个虚线的长度。抱歉给您带来任何混乱。
Skylar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.