如何使用CSS编写箭头

3

大家好,我正在尝试使用CSS编写像这样的箭头,我在codepen上查看了示例,但现在我在思考它是否真的可行?

arrows


尝试使用CSS三角形来制作箭头。 - Gibin Ealias
这是可能的,但你最终会使用 CSS 的方式可能不太合适。至少在实际项目中不应该这样做。在 SVG 中,您可以使用更简洁和易于理解的代码来完成此类操作,从而获得更好、更灵活的结果。 - Rob Monhemius
3个回答

5

这里有一个只使用一个元素和多个线性渐变作为背景的技巧,你可以单独调整每个箭头的大小/位置:

.arrows {
  width:300px;
  height:100px;
  position:relative;
  background:
  /* For the 3 lines*/
  linear-gradient(#000,#000) 10px 25px/2px calc(100% - 30px),
  linear-gradient(#000,#000) 50% 0/2px calc(100% - 2px),
  linear-gradient(#000,#000) calc(100% - 10px) 25px/2px calc(100% - 30px),
  /*for the arrows*/
  linear-gradient(to top left,transparent 50%,#000 0%) 10px 100%/10px 10px,
  linear-gradient(to top right,transparent 50%,#000 0%) 0px 100%/10px 10px,
  
  linear-gradient(to top left,transparent 50%,#000 0%) calc(50% + 5px) 100%/10px 10px,
  linear-gradient(to top right,transparent 50%,#000 0%) calc(50% - 5px) 100%/10px 10px,
  
  linear-gradient(to top left,transparent 50%,#000 0%) 100% 100%/10px 10px,
  linear-gradient(to top right,transparent 50%,#000 0%) calc(100% - 10px) 100%/10px 10px;
  background-repeat:no-repeat;
}
.arrows:before {
  content:"";
  position:absolute;
  top:20px;
  left:10px;
  right:10px;
  height:8px;
  border:2px solid;
  border-bottom:none;
  border-radius:10px 10px 0 0;
  box-sizing:border-box;
}
<div class="arrows"></div>

每个箭头如何工作?

对于每个元素,我们有线条极端点

  1. 对于线条,我们只需要使用纯色的linear-gradient,然后调整backround-size来控制线条:

因此,如果我考虑这个线性渐变:

body {
  height: 200px;
  border: 1px solid;
  margin:0;
  background: linear-gradient(#000,#000) 10px 25px/2px calc(100% - 30px) no-repeat;
}

我们可以这样阅读它:从10px,25px处画一条粗细为2px、长度为100%减去30px的线。 100%将指容器的高度。

  1. 对于端点,我们需要两个渐变,每个渐变都将创建一个矩形三角形。为此,我只需要为我的渐变指定一个对角方向(例如:to top right):

因此,如果我考虑这个线性渐变:

body {
  height: 200px;
  border: 1px solid;
  margin:0;
  background: linear-gradient(to top right, #000 50%, transparent 0%) 30px 30px/10px 10px no-repeat;
}

我们可以这样理解:从 30px,30px 开始,以 10px * 10px 的大小渐变,并填充其中的 50% 用黑色,沿着 右上方 方向。因此最终得到一个左边和底边均为 10px 的矩形三角形。
我们用相同的方式创建另一个极端,然后将它们靠近彼此以创建最终的视觉效果。

body {
  height: 200px;
  border: 1px solid;
  margin:0;
  background: 
   linear-gradient(to top right, #000 50%, transparent 0%) 30px 30px/10px 10px no-repeat,
   linear-gradient(to top left,  #000 50%, transparent 0%) 20px 30px/10px 10px no-repeat;
}

现在你所需要做的就是将所有这些线性渐变组合起来,并调整大小/位置以获得您的布局。
如果需要更多箭头,您可以轻松地进行缩放,只需添加更多的渐变即可。

.arrows {
  width:300px;
  height:100px;
  position:relative;
  background:
  /* For the lines*/
  linear-gradient(#000,#000) 10px 25px/2px calc(100% - 50px),
  linear-gradient(#000,#000) 19% 20px/2px calc(100% - 30px),
  linear-gradient(#000,#000) 50% 0/2px calc(100% - 2px),
  linear-gradient(#000,#000) 70% 20px/2px calc(100% - 80px),
  linear-gradient(#000,#000) calc(100% - 10px) 25px/2px calc(100% - 30px),
  linear-gradient(#000,#000) calc(50% + 20px) 60px/ 40px 2px,
  /*for the arrows*/
  linear-gradient(to top left,transparent 50%,#000 0%) 10px calc(100% - 20px)/10px 10px,
  linear-gradient(to top right,transparent 50%,#000 0%) 0px calc(100% - 20px)/10px 10px,
  
  linear-gradient(to top left,transparent 50%,#000 0%) 20% calc(100% - 8px)/10px 10px,
  linear-gradient(to top right,transparent 50%,#000 0%) calc(20% - 10px) calc(100% - 8px)/10px 10px,
  
  linear-gradient(to top left,transparent 50%,#000 0%) calc(50% + 5px) 100%/10px 10px,
  linear-gradient(to top right,transparent 50%,#000 0%) calc(50% - 5px) 100%/10px 10px,
  
  linear-gradient(to top left,transparent 50%,#000 0%) 72% calc(100% - 58px)/10px 10px,
  linear-gradient(to top right,transparent 50%,#000 0%) calc(72% - 10px) calc(100% - 58px)/10px 10px,
  
  linear-gradient(to top left,transparent 50%,#000 0%) 100% 100%/10px 10px,
  linear-gradient(to top right,transparent 50%,#000 0%) calc(100% - 10px) 100%/10px 10px,
  
  linear-gradient(to top left,transparent 50%,#000 0%) calc(50% + 42px) 62px/10px 10px,
  linear-gradient(to bottom left,transparent 50%,#000 0%) calc(50% + 42px) 52px/10px 10px;
 background-repeat:no-repeat;
}
.arrows:before {
  content:"";
  position:absolute;
  top:20px;
  left:10px;
  right:10px;
  height:8px;
  border:2px solid;
  border-bottom:none;
  border-radius:10px 10px 0 0;
  box-sizing:border-box;
}
<div class="arrows"></div>


哇,太棒了!我想问一下,如果我要调整浏览器大小,我应该使用@media,那么我需要编辑哪个变量呢? - GoodJeans
@GoodJeans 当然可以 :) .. 对于每个渐变,你有类似这样的东西 [ a b/c d ] .. a和b控制渐变的位置,就像x/y值一样,因此您指定了渐变从哪里开始。c和d值控制渐变的大小,因此您告诉渐变有多大,通过这个我控制每条线和每个箭头的大小。我的建议是只使用一个箭头,并通过更改值来玩耍,看看会发生什么,以便您了解如何修改每个值 ;) - Temani Afif
@GoodJeans 顺便问一下,你能像我一样使用%值并仅调整框的大小,这样渐变就会跟随此调整吗? - Temani Afif
@GoodJeans 我已经编辑了我的答案,并附上了详细的解释 :) - Temani Afif

3

对于箭头和线条,我使用了border

.content {
  margin-top: 30px;
  position: relative;
  border: 2px solid black;
  border-bottom: 2px;
  border-radius: 5px;
  width: 200px;
  height: 40px;
}

.content:before,
.content:after,
.center:before {
  content: '';
  width: 0;
  height: 0;
  border-width: 8px 8px;
  border-color: #000 transparent transparent transparent;
  border-style: solid;
  position: absolute;
}

.content:before {
  left: -8px;
  top: 36px;
}

.content:after {
  right: -8px;
  top: 36px;
}

.center:before {
  right: -8px;
  top: 60px;
}

.center {
  position: absolute;
  height: 60px;
  top: -24px;
  left: 50%;
  margin-left:-2px;
  border: 1px solid black;
}
<div class="content">
  <div class="center">
  </div>
</div>


0

箭头本身是由一个等边的高度和宽度为0的块创建的(只有边框构成可见元素)。然后,您只显示左边框以获得右箭头,右边框用于左箭头,依此类推。

https://css-tricks.com/snippets/css/css-triangle/

至于添加线条,这是通过使用高度为0的块级元素和水平线条所需的宽度以及宽度为0的垂直线条所需的高度来实现的。

我已经创建了以下CSS:

    <html>
        <head>
            <title>CSS Arrows</title>
            <style type="text/css">
                .arrow {
                    margin: 5px;
                }

                .arrow_sm {
                    border: 5px solid transparent;
                }

                .arrow_sm p {
                    font-size: 10px;
                    margin-top: -6px;
                }

                .arrow_md {
                    border: 10px solid transparent;
                }

                .arrow_md p {
                    font-size: 20px;
                    margin-top: -12px;
                }

                .arrow_lg {
                    border: 15px solid transparent;
                }

                .arrow_lg p {
                    font-size: 30px;
                    margin-top: -18px;
                }

                .arrow_right {
                    height: 0;
                    border-left-color: blue; 
                }

                .arrow_right {
                    padding-left: 2px;
                }

                .arrow_down {
                    width: 0;
                    border-top-color: red; 
                }

                .arrow_down p {
                    padding-top: 2px;
                    padding-bottom: 2px;
                    transform: rotate(90deg);
                    transform-origin: middle top 0;
                }

                .arrow_left {
                    height: 0;
                    text-align: right;
                    border-right-color: green; 
                }

                .arrow_left p {
                    text-align: right;
                    padding-right: 2px;
                }

                .arrow_up {
                    width: 0;
                    border-bottom-color: black; 
                }

                .arrow_up p {
                    margin: 0 0 -.4em -.2em;
                    transform: rotate(-90deg);
                    transform-origin: middle bottom 0;
                }

                .vertical_line {
                    width: 2px;
                }

                .horizontal_line {
                    height: 2px;
                }

                .line_v_sm {
                    height: 30px;
                    border-left: 2px solid green;
                }

                .line_v_md {
                    height: 45px;
                    border-left: 2px solid red;
                }

                .line_v_lg {
                    height: 60px;
                    border-left: 2px solid black;
                }

                .line_h_sm {
                    width: 30px;
                    border-top: 2px solid green;
                }

                .line_h_md {
                    width: 45px;
                    border-top: 2px solid red;
                }

                .line_h_lg {
                    width: 60px;
                    border-top: 2px solid black;
                }

                .inline {
                    display: inline-block;
                }

                .vertical_stem_sm {
                    margin-top: -.5em;
                    margin-left: .6em;
                    margin-bottom: -.5em;
                }

                .vertical_stem_md {
                    margin-top: -.8em;
                    margin-left: .9em;
                    margin-bottom: -.8em;
                }

                .vertical_stem_lg {
                    margin-top: -1.1em;
                    margin-left: 1.2em;
                    margin-bottom: -1.1em;
                }

                .horizontal_stem_sm {
                    margin-left: -.6em;
                    margin-right: -.6em;
                }

                .horizontal_stem_md {
                    margin-top: -7px;
                    margin-left: -.6em;
                    margin-right: -.6em;
                }

                .horizontal_stem_lg {
                    margin-top: -12px;
                    margin-left: -.6em;
                    margin-right: -.6em;
                }
            </style>
        </head>
        <body>
            <!-- arrow arrow_size arrow_direction //-->
            <div class="arrow arrow_sm arrow_right"><p>Right</p></div>
            <div class="arrow arrow_md arrow_right"><p>Right</p></div>
            <div class="arrow arrow_lg arrow_right"><p>Right</p></div>

            <div class="arrow arrow_sm arrow_down"><p>Down</p></div>
            <div class="arrow arrow_md arrow_down"><p>Down</p></div>
            <div class="arrow arrow_lg arrow_down"><p>Down</p></div>

            <div class="arrow arrow_sm arrow_left"><p>Left</p></div>
            <div class="arrow arrow_md arrow_left"><p>Left</p></div>
            <div class="arrow arrow_lg arrow_left"><p>Left</p></div>

            <div class="arrow arrow_sm arrow_up"><p>Up</p></div>
            <div class="arrow arrow_md arrow_up"><p>Up</p></div>
            <div class="arrow arrow_lg arrow_up"><p>Up</p></div>


            <div class="arrow arrow_sm arrow_right"></div>
            <div class="arrow arrow_md arrow_right"></div>
            <div class="arrow arrow_lg arrow_right"></div>

            <div class="arrow arrow_sm arrow_down"></div>
            <div class="arrow arrow_md arrow_down"></div>
            <div class="arrow arrow_lg arrow_down"></div>

            <div class="arrow arrow_sm arrow_left"></div>
            <div class="arrow arrow_md arrow_left"></div>
            <div class="arrow arrow_lg arrow_left"></div>

            <div class="arrow arrow_sm arrow_up"></div>
            <div class="arrow arrow_md arrow_up"></div>
            <div class="arrow arrow_lg arrow_up"></div>

            <div class="vertical_line line_v_sm"></div>
            <div class="vertical_line line_v_md"></div>
            <div class="vertical_line line_v_lg"></div>

            <div class="horizontal_line line_h_sm"></div>
            <div class="horizontal_line line_h_md"></div>
            <div class="horizontal_line line_h_lg"></div>

            <!-- Small arrow and stem for small arrow //-->
            <div style="margin-left: 70px;">
                <div class="arrow arrow_sm arrow_up"><p>Up</p></div>
                <div class="vertical_line line_v_lg vertical_stem_sm"></div>
            </div>

            <div class="arrow arrow_sm arrow_left inline"><p>Left</p></div>
            <div class="horizontal_line line_h_lg inline horizontal_stem_sm"></div>

            <div class="horizontal_line line_h_lg inline horizontal_stem_sm"></div>
            <div class="arrow arrow_sm arrow_right inline"><p>Right</p></div>
            <div style="margin-left: 70px;">
                <div class="vertical_line line_v_lg vertical_stem_sm"></div>
                <div class="arrow arrow_sm arrow_down"><p>Down</p></div>
            </div>

            <!-- Medium arrow and stem for medium arrow //-->
            <div style="margin-left: 90px;">
                <div class="arrow arrow_md arrow_up"><p>Up</p></div>
                <div class="vertical_line line_v_lg vertical_stem_md"></div>
            </div>

            <div class="arrow arrow_md arrow_left inline"><p>Left</p></div>
            <div class="horizontal_line line_h_lg inline horizontal_stem_md"></div>

            <div class="horizontal_line line_h_lg inline horizontal_stem_md"></div>
            <div class="arrow arrow_md arrow_right inline"><p>Right</p></div>
            <div style="margin-left: 90px;">
                <div class="vertical_line line_v_lg vertical_stem_md"></div>
                <div class="arrow arrow_md arrow_down"><p>Down</p></div>
            </div>

            <!-- Large arrow and stem for large arrow //-->
            <div style="margin-left: 120px;">
                <div class="arrow arrow_lg arrow_up"><p>Up</p></div>
                <div class="vertical_line line_v_lg vertical_stem_lg"></div>
            </div>

            <div class="arrow arrow_lg arrow_left inline"><p>Left</p></div>
            <div class="horizontal_line line_h_lg inline horizontal_stem_lg"></div>

            <div class="horizontal_line line_h_lg inline horizontal_stem_lg"></div>
            <div class="arrow arrow_lg arrow_right inline"><p>Right</p></div>
            <div style="margin-left: 120px;">
                <div class="vertical_line line_v_lg vertical_stem_lg"></div>
                <div class="arrow arrow_lg arrow_down"><p>Down</p></div>
            </div>
        </body>
    </html>

https://jsfiddle.net/2ykpwwgt/1/

由于某些原因,在JSFiddle中它的解析方式与我的浏览器不同。

好吧,你有一个想法和一个方法来玩耍。


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