问题
Hi guys I'm trying to code an arrow like this in css, I'e viewed examples on codepen, but now I'm thinking whether it is actually possible?
回答1:
For arrow and lines i have use 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>
回答2:
Here is another trick using only one element and multiple linear-gradient as background and you can adjust the size/position of each arrow individually:
.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>
How does each arrow work?
For each element we have the line and the extremity:
- For the line, we simply need a
linear-gradient
with a solid color then we adjust thebackround-size
to control the line:
So if I consider this linear gradient:
body {
height: 200px;
border: 1px solid;
margin:0;
background: linear-gradient(#000,#000) 10px 25px/2px calc(100% - 30px) no-repeat;
}
We can read it as follow : Draw a line from 10px,25px
with a thickness of 2px and a length of 100%
minus 30px
. 100%
will refer to the height of the container.
- For the extremity we will need two gradients, each one will create a rectangle triangle. To do this I simply need to specify a diagonal direction to my gradient (for example:
to top right
):
So if I consider this linear gradient:
body {
height: 200px;
border: 1px solid;
margin:0;
background: linear-gradient(to top right, #000 50%, transparent 0%) 30px 30px/10px 10px no-repeat;
}
We can read it as follow: start my gradient from 30px,30px
with a size of 10px * 10px
and fill 50%
of it with black following the top right direction. So we will end up with a rectangle triangle having left and bottom side equal to 10px
.
We do the same to create the other extremity and we simply make them close to each other to create the final visual:
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;
}
Now all you have to do is to combine all these linear gradient and adjust size/position to obtain your layout.
You can easily scale for more arrows if needed as you simply need to append more gradient:
.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>
回答3:
An arrow in itself is created from an equilateral block of 0 height and width (with only the borders making up the visible element). And then you only show the left border to have a right arrow, the right border for the left arrow and so on and so forth.
https://css-tricks.com/snippets/css/css-triangle/
As far as adding the lines it's a matter of 0 height block elements and the required width for size of horizontal lines and 0 width and the required height for vertical lines.
I went ahead and created the following 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/
For some reason in JSFiddle it doesn't parse like it does in my browser.
Well, you got an idea and something to play with with one method
来源:https://stackoverflow.com/questions/48604103/how-to-code-an-arrow-using-css