csscss-shapes

Is it possible to make a "double arrow" with css3 content technique?


Im looking for a way to recreate this button with CSS only.

enter image description here

I know about the triangle technique and I also know how to add a border to it, but unfortunately I don't know any way to recreate this button (without adding additional wrappers or using images).

The buttons I need this style on are <input["submit"]> and ordinary <a>'s.


Solution

  • 2024 solution, requiring no pseudos

    The shape is created with two conic-gradient() mask layers plus clip-path. Neither of these features was a thing back in 2013.

    .click-me {
        --ang: 120deg;
        --tri: .5*(.5turn - var(--ang));
        --ini: calc(-1*(var(--ang) + var(--tri)));
        --set: from var(--ini) at calc(100% - .5em);
        --x: calc(100% - .5lh*tan(var(--tri)));
        display: inline-block;
        margin: .5em;
        padding: 0 2em 0 1.5em;
        background: lightseagreen;
        mask: 
            conic-gradient(var(--set), 
                    red var(--ang), #0000 0%) -.1875em, 
            conic-gradient(var(--set), 
                    #0000 var(--ang), red 0%);
        color: #fff;
        font: clamp(.75em, 8vw, 2em)/ 2.25 verdana, sans-serif;
        text-transform: uppercase;
        white-space: nowrap;
        clip-path: 
            polygon(0 0, var(--x) 0, 
                100% 50%, var(--x) 100%, 0 100%);
        
        &:is(button, [type='submit']) { border: none }
        &[href] { text-decoration: none }
        
        &:is(:hover, :focus) { background: deepskyblue }
        &:focus { outline: none }
    }
    <button class='click-me'>click me</button>
    <input type='submit' value='click me' class='click-me'/>
    <a class='click-me' href='#'>click me</a>

    2013 solution, preserved for web history reasons

    With one element, you could do it using gradients and skewed pseudo-elements for a link:

    demo

    (you could actually do it using just gradients, but then a hover action won't be triggered on hover on the arrow shape itself, but on hover on the rectangular element containing it)

    HTML:

    <a class='boo' href='#'>click me</a>
    

    Relevant CSS:

    .boo {
      display: inline-block;
      position: relative;
      padding: .5em 2em;
      background: 
        linear-gradient(60deg, dodgerblue 50%, transparent 50%) 100% 0, 
        linear-gradient(-60deg, transparent 50%, dodgerblue 50%) 100% 100%,
        linear-gradient(-90deg, transparent 1em, dodgerblue 1em);
      background-repeat: no-repeat;
      background-size: 1em 50%, 1em 50%, 100% 100%;
    }
    .boo:before, .boo:after {
      position: absolute;
      right: -.2em;
      width: .5em; height: 50%;
      background: dodgerblue;
      content: '';
    }
    .boo:before {
      top: 0;
      transform: skewX(30deg);
    }
    .boo:after {
      bottom: 0;
      transform: skewX(-30deg);
    }
    

    EDIT:

    If your background is a solid color, not an image or a gradient, you could do it in a much simpler way, without using gradients (which means that this second method also has the advantage of working in IE9).

    demo #2

    .boo {
      display: inline-block;
      position: relative;
      padding: .5em 2em;
      background: lightblue;
    }
    .boo:before, .boo:after {
      position: absolute;
      right: -.3em;
      width: .5em; height: 50%;
      box-shadow: -.2em 0 0 white;
      background: inherit;
      content: '';
    }
    .boo:before {
      top: 0;
      transform: skewX(30deg);
    }
    .boo:after {
      bottom: 0;
      transform: skewX(-30deg);
    }