CSS button - transparent arrow on both sides

2019-02-26 02:28发布

问题:

I am trying to create the button below by using the pseudo-elements before and after. I do not want to manipulate the HTML DOM. I'm searching for a solution with pure CSS.

How is it possible to make the currently white border-color of these triangles transparent?

//EDIT: The marked topic does not answer my question because I need a different angle than just rotating a square. It is also not transparent. I don't want to manipulate the DOM.

//SOLVED: This is the result after using Kate Millers solution:

//EDIT2: There is another problem with the solution I use now:

Is there a way to fix the border-width of the triangles (left and right)? Here you can see how the size changes to 14.4 and 26.4px, 26.4px:

回答1:

The best solution is to reverse the triangles (so you're adding top and bottom triangles that match the button, but not on the sides). You can technically make "transparent" triangles, but you can't have that transparency apply to a different object.

One of the most important things I changed was that the background color and padding of the button has to apply to the span element (which means each button will need an interior span), not .btn.

If you replace all of your CSS about the buttons with the below, you'll have a solution that gets you at least 90% of the way there. The angle isn't perfect because it's stopping at the text. If you want to make the angle truly perfect, you'll probably need to do some absolute positioning, which would make it messy as your button sizes change.

The non-code way you can also achieve this is to create a .png or .svg with triangles that match the color of your button and insert them into the :before and :after with content: ' ';

body { margin: 20px; background:#c2c2c2; }

.btn {
  display: inline-block;
  text-shadow: 0 1px 0 #000;
  font-weight: bold;
  text-transform: uppercase;
}

.btn {
  padding: 11px 40px;
  color: #fff;
  position: relative;
  background: #a00;
}

.btn:before, .btn:after {
  content: '';
  border-top: 20px solid #a00;
  border-bottom: 20px solid #a00;
  position: absolute;
  top: 0;
}

.btn:before {
  border-left:20px solid transparent;
  left: -20px;
}

.btn:after {
  border-right:20px solid transparent;
  right:-20px;
}


.btn.inset:before, .btn.inset:after {
  content: '';
  border-top: 20px solid transparent;
  border-bottom: 20px solid transparent;
  position: absolute;
  top: 0;
}

.btn.inset:before {
  border-right:20px solid #a00;
  left: -40px;
}

.btn.inset:after {
  border-left:20px solid #a00;
  right:-40px;
}
<div class="btn">Text in my little banner button</div>
<div class="btn inset">Text in my little banner button</div>



回答2:

I don't use, and am not really familiar with, LESS... but you can create a similar element using a span and a wrapper with pseudo elements. It does take 2 triangles for each side (hence the span).

body { margin: 20px; background: #ddd; }

.btn {
  display: inline-block;
  padding: 11px 40px;
  color: #fff;
  position: relative;
  background: #a00;
  text-shadow: 0 1px 0 #000;
  font-weight: bold;
  text-transform: uppercase;
}

.btn:after,
.btn span:after,
.btn:before,
.btn span:before {
  content: "";
  width: 0;
  height: 0;
  display: block;
  position: absolute;
  right: 0;
  border: 10px solid transparent;
}
.btn:after {
  top: 0;
  border-right-color: #ddd;
  border-bottom-color: #ddd;
  }
.btn span:after {
  bottom: 0;
  border-right-color: #ddd;
  border-top-color: #ddd;
}
.btn:before {
  top: 0;
  left:0;
  border-left-color: #ddd;
  border-bottom-color: #ddd;
  }
.btn span:before {
  bottom: 0;
  left:0;
  border-left-color: #ddd;
  border-top-color: #ddd;
}
<div class="btn"><span>Text in my little banner button</span></div>

I realize the ends aren't really transparent, they just match the background color to appear transparent.