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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2771171/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 22:01:05  来源:igfitidea点击:

Control the dashed border stroke length and distance between strokes

cssbordercss-shapes

提问by AntonAL

Is it possible to control the length and distance between dashed border strokes in CSS?

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

This example below displays differently between browsers:

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

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

Big differences: IE 11 / Firefox / Chrome

大不同:IE 11 / Firefox / Chrome

IE 11 borderFirefox BorderChrome border

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

Are there any methods that can provide greater control of the dashed borders appearance?

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

采纳答案by snowflake

Css render is browser specific and I don't know any fine tuning on it, you should work with images as recommended by Ham. Reference: http://www.w3.org/TR/CSS2/box.html#border-style-properties

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

回答by misterManSam

The native dashed border property value does not offer control over the dashes themselves... so bring on the border-imageproperty!

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

Brew your own border with border-image

酿造你自己的边界 border-image

Compatibility: It offers great browser support(IE 11 and all modern browsers). A normal border can be set as a fallback for older browsers.

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

Let's create these

让我们创造这些

These borders will display exactly the same cross-browser!

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

Goal exampleGoal example with wider gaps

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

Step 1 - Create a suitable image

步骤 1 - 创建合适的图像

This example is 15 pixels wide by 15 pixels high and the gaps are currently 5px wide. It is a .png with transparency.

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

This is what it looks like in photoshop when zoomed in:

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

Example Border Image Background Blown Up

示例边框图像背景被放大

This is what it looks like to scale:

这是缩放的样子:

Example Border Image Background Actual Size

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

Controlling gap and stroke length

控制间隙和行程长度

To create wider / shorter gaps or strokes, widen / shorten the gaps or strokes in the image.

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

Here is an image with wider 10px gaps:

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

Larger gapscorrectly scaled = Larger gaps to scale

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

Step 2 - Create the CSS — this example requires 4 basic steps

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

  1. Define the border-image-source:

    border-image-source:url("http://i.stack.imgur.com/wLdVc.png");  
    
  2. Optional- Define the border-image-width:

    border-image-width: 1;
    

    The default value is 1. It can also be set with a pixel value, percentage value, or as another multiple (1x, 2x, 3x etc). This overrides any border-widthset.

  3. Define the border-image-slice:

    In this example, the thickness of the images top, right, bottom and left borders is 2px, and there is no gap outside of them, so our slice value is 2:

    border-image-slice: 2; 
    

    The slices look like this, 2 pixels from the top, right, bottom and left:

    Slices example

  4. Define the border-image-repeat:

    In this example, we want the pattern to repeat itself evenly around our div. So we choose:

    border-image-repeat: round;
    
  1. 定义边界图像源

    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. 定义边界图像切片

    在这个例子中,图像上、右、下、左边框的粗细为2px,并且它们之外没有间隙,所以我们的切片值为2:

    border-image-slice: 2; 
    

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

    切片示例

  4. 定义边界图像重复

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

    border-image-repeat: round;
    

Writing shorthand

写速记

The properties above can be set individually, or in shorthand using border-image:

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

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

Complete example

完整示例

Note the border: dashed 4px #000fallback. Non-supporting browsers will receive this border.

注意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>

回答by Harry

In addition to the border-imageproperty, there are a few other ways to create a dashed border with control over the length of the stroke and the distance between them. They are described below:

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

Method 1: Using SVG

方法一:使用SVG

We can create the dashed border by using a pathor a polygonelement and setting the stroke-dasharrayproperty. The property takes two parameters where one defines the size of the dash and the other determines the space between them.

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

Pros:

优点:

  1. SVGs by nature are scalable graphics and can adapt to any container dimensions.
  2. Can work very well even if there is a border-radiusinvolved. We would just have replace the pathwith a circlelike in this answer(or) convert the pathinto a circle.
  3. Browser support for SVGis pretty good and fallback can be provided using VML for IE8-.
  1. SVG 本质上是可缩放的图形,可以适应任何容器尺寸。
  2. 即使有border-radius牵连也能很好地工作。在这个答案中,我们只需将 the 替换pathcirclelike (或)将 the 转换为一个圆圈。path
  3. 浏览器对 SVG 的支持非常好,可以使用 VML for IE8- 提供回退。

Cons:

缺点:

  1. When the dimensions of the container do not change proportionately, the paths tend to scale resulting in a change in size of the dash and the space between them (try hovering on the first box in the snippet). This can be controlled by adding vector-effect='non-scaling-stroke'(as in the second box) but the browser support for this property is nil in IE.
  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>



Method 2: Using Gradients

方法 2:使用梯度

We can use multiple linear-gradientbackground images and position them appropriately to create a dashed border effect. This can also be done with a repeating-linear-gradientbut there is not much improvement because of using a repeating gradient as we need each gradient to repeat in only one direction.

我们可以使用多个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>

Pros:

优点:

  1. Scalable and can adapt even if the container's dimensions are dynamic.
  2. Does not make use of any extra pseudo-elements which means they can be kept aside for any other potential usage.
  1. 可扩展,即使容器的尺寸是动态的也能适应。
  2. 不使用任何额外的伪元素,这意味着它们可以留到一边用于任何其他潜在用途。

Cons:

缺点:

  1. Browser support for linear gradientsis comparatively lower and this is a no-go if you want to support IE 9-. Even libraries like CSS3 PIE do not support creation of gradient patterns in IE8-.
  2. Cannot be used when border-radiusis involved because backgrounds don't curve based on border-radius. They get clipped instead.
  1. 浏览器对线性渐变的支持相对较低,如果您想支持 IE 9-,这是不行的。甚至像 CSS3 PIE 这样的库也不支持在 IE8- 中创建渐变模式。
  2. border-radius涉及时不能使用,因为背景不会基于border-radius. 他们反而被剪掉了。


Method 3: Box Shadows

方法 3:框阴影

We can create a small bar (in the shape of the dash) using pseudo-elements and then create multiple box-shadowversions of it to create a border like in the below snippet.

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

If the dash is a square shape then a single pseudo-element would be enough but if it is a rectangle, we would need one pseudo-element for the top + bottom borders and another for left + right borders. This is because the height and width for the dash on the top border will be different from that on the left.

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

Pros:

优点:

  1. The dimensions of the dash is controllable by changing the dimensions of the pseudo-element. The spacing is controllable by modifying the space between each shadow.
  2. A very unique effect can be produced by adding a different color for each box shadow.
  1. 破折号的尺寸可以通过更改伪元素的尺寸来控制。通过修改每个阴影之间的空间可以控制间距。
  2. 通过为每个框阴影添加不同的颜色可以产生非常独特的效果。

Cons:

缺点:

  1. Since we have to manually set the dimensions of the dash and the spacing, this approach is no good when the dimensions of the parent box is dynamic.
  2. IE8 and lower do not support box shadow. However, this can be overcome by using libraries like CSS3 PIE.
  3. Can be used with border-radiusbut positioning them would be very tricky with having to find points on a circle (and possibly even transform).
  1. 由于我们必须手动设置dash的尺寸和间距,当父框的尺寸是动态的时,这种方法是不好的。
  2. IE8 及更低版本不支持框阴影。然而,这可以通过使用像 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>

回答by Ham Vocke

Short one: No, it's not. You will have to work with images instead.

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

回答by ili4

Stroke length depends on stroke width. You can increase length by increasing width and hide part of border by inner element.

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

.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/

https://jsfiddle.net/ok6srt2z/

回答by Balthazar

There's a cool tool made by @kovartcalled the dashed border generator.

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

It uses an svg as a background image to allow setting the stroke dash array you desire, and is pretty convenient.

它使用 svg 作为背景图像,允许设置您想要的笔划虚线数组,非常方便。

You would then simply use it as the background property on your element in place of the border:

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

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

回答by razzz

I just recently had the same problem.

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

I managed to solve it with two absolutely positioned divs carrying the border (one for horizontal and one for vertical), and then transforming them. The outer box just needs to be relatively positioned.

我设法用两个带有边框的绝对定位的 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>

Note: i used tachyons in this example, but i guess the classes are kind of self-explanatory.

注意:我在这个例子中使用了 tachyons,但我想这些类是不言自明的。

回答by BJC

This will make an orange and gray border using the class="myclass" on the div.

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

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