Use css to create a custom arrow shape [duplicate]

2019-02-18 06:28发布

问题:

This question already has an answer here:

  • Arrow before and after a box with CSS 1 answer

I have a css arrow box overlaying an image slider but I need to make the tail indented and transparent so the image is seen behind it. Need the white portion to be transparent. See attached image and my css below. Thanks.

#flag { 
width: 400px; height: 80px; background: #231f20; position: relative;
}

#flag:before { 
content: ""; 
position: absolute; 
top: 0; 

width: 0; 
height: 0; 
border-top: 40px solid transparent; 

border-bottom: 40px solid transparent; 

border-left: 35px solid white;

}

#flag:after { 
content: ""; 
position: absolute; 
left: 400px; 
bottom: 0; 
width: 0; 
height: 0; 
border-top: 40px solid transparent;

border-bottom: 40px solid transparent;

border-left: 45px solid #231f20;

}

回答1:

This is pretty simple. You just need to set the color of top/bottom borders of the ::before pseudo-element to the background color and change the color of left border to transparent.

Then you could use margins/offsets to position the pseudo-element properly.

body { background-color: gold; }

#flag { 
  width: 400px; height: 80px; background: #231f20; position: relative;
  margin-left: 35px;
  color: white;
  line-height: 80px;
  text-align: center;
}

#flag:before { 
  content: ""; 
  position: absolute; 
  top: 0; 
  left: -35px;
  width: 0; 
  height: 0; 
  border-top: 40px solid #231f20; 
  border-bottom: 40px solid #231f20; 
  border-left: 35px solid transparent;

}

#flag:after { 
  content: ""; 
  position: absolute; 
  left: 400px; 
  bottom: 0; 
  width: 0; 
  height: 0; 
  border-top: 40px solid transparent;

  border-bottom: 40px solid transparent;

  border-left: 45px solid #231f20;
}
<div id="flag">This is it!</div>



回答2:

Simplest solution would be svg.

html, body {
  background: url(http://lorempixel.com/400/200/sports/) no-repeat;
  background-size: 100% 100%;
  width: 100%;
  height: 100%;
  margin: 0;
}
svg {
  position: relative;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
}
<svg width="225" height="50">
  <path d="M0,0 L200,0 L225,25 L200,50 L0,50 L25,25z" fill="black" />
</svg>


You could easily create complex arrow shapes.

html, body {
  background: teal;
  background-size: 100% 100%;
  width: 100%;
  height: 100%;
  margin: 0;
}
svg {
  position: relative;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<svg width="200" height="100" viewBox="-5 -5 210 110">
  <path d="M0,0 L155,40 L145,0 L200,50 L145,100 L155,60 L0,100 Q100,50 0,0z" stroke-linejoin="round" stroke="#222222" stroke-width="5" fill="#333333" />
</svg>


Making it even more complex by adding some quadratic bezier curves.

html,
body {
  background: teal;
  background-size: 100% 100%;
  width: 100%;
  height: 100%;
  margin: 0;
}
svg {
  position: relative;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<svg width="200" height="100" viewBox="-5 -5 205 107">
  <path d="M0,0 L155,40 L145,0 L200,50 L145,100 L155,60 L0,100 Q45,87.5 10,75 Q55,65 20,50 Q55,37 10,25 Q45,12.5 0,0z" stroke-linejoin="round" stroke="#222222" stroke-width="5" fill="#333333" />
</svg>




回答3:

Use :before's borders to draw the main rectangular part of the arrow, instead of a background on #flag. So set the border-top and border-bottom on #flag:before to be #231f20. That way, you can just set the border-left on #flag:before to be transparent.

Here's a modified version with different colors to help visualize which borders are drawing which part in this solution. http://jsfiddle.net/fuvwsn55/



回答4:

demo

#flag:before,
#flag:after{ 
  content: ""; 
  position: absolute; 
  border: 40px solid #231f20;
}
#flag:before { 
  left: -35px;
  border-left: 35px solid transparent;
}
#flag:after {
  right:-80px;
  border: 40px solid transparent;
  border-left: 40px solid #231f20;
}


回答5:

If you can split your flag into two divs (definitely not practical in all cases) you can get a smoothly rendered arrow (note, this WILL also skew your divs' content):

body
{
    background-color: gold;
}

#flag_top {
    width: 400px; height: 40px; background: #231f20; position: relative;
    	-webkit-transform: skew(40deg);
	   -moz-transform: skew(40deg);
	     -o-transform: skew(40deg);
    margin-left: 30px;
}
#flag_bottom {
    width: 400px; height: 40px; background: #231f20; position: relative;
    	-webkit-transform: skew(320deg);
	   -moz-transform: skew(320deg);
	     -o-transform: skew(320deg);
    margin-left: 30px;
}
<div id="flag_top">
</div>
<div id="flag_bottom">    
</div>