4

I'm trying to create a hollow css arrow in front of an image.

I got it… but it feels very dirty. Is there any better way to do this? Cross browser compatibility (IE8+) would be awesome.

SCSS

.arrowwrap {
    width:100%;
    padding:0;
    position:relative;
    overflow:hidden;
    margin:-$arrow_height 0 0 0;
    &:after {
        content:'';
        position:absolute;
        height:$arrow_height;
        width:50%;
        margin:-$arrow_height 0 0 -$arrow_width;
        left:0;
        z-index:99999;
        background:$box_color;
    }
    &:before {
        content:'';
        position:absolute;
        height:$arrow_height;
        width:100%;
        left:50%;
        margin:0 0 0 $arrow_width;
        z-index:99999;
        background:$box_color;
    }
    .arrowone {
        width: 0;
        height: 0;
        border-style: solid;
        border-width: $arrow_height $arrow_width 0 $arrow_width;
        /* border-color: transparent transparent #333 transparent; */
        border-color:transparent $box_color $box_color $box_color;
        margin:auto;
    }
}

http://jsfiddle.net/dhs2eba2/

web-tiki
  • 99,765
  • 32
  • 217
  • 249
Bitpunk
  • 198
  • 2
  • 11
  • 4
    Can't understand "it feels very dirty" – Alex Char Sep 09 '14 at 07:59
  • 1
    @Alek he means it requires a non-semantic arrow element and relies on both `before` and `after` in addition to it. It's a lot of markup for something he feels ought to be easier to do – Joe Sep 09 '14 at 08:08
  • related question : http://stackoverflow.com/questions/23758922/transparent-css-arrow-triangle-over-an-image/23759602#23759602 – web-tiki Sep 09 '14 at 08:17
  • You could do the same with a svg and a png as fallback, did you try that? – Beowolve Sep 09 '14 at 08:23
  • Another related question: http://stackoverflow.com/questions/19199684/triangle-in-css-inside-a-box – Harry Sep 09 '14 at 11:26

2 Answers2

4

If you want to minimise and remove all unsemantic markup you can do :

DEMO

This technique relies on pseudo elements and therefore prevents the use of unsemantic markup. Pseudo elements are supported by IE8+ see canIuse. It also needs the box-sizing property to enable responsive width (box-sizing: border-box is also supported by IE8+ see canIuse).

HTML :

<div class="wrap">
    <img src="http://placekitten.com/800/350" />
    <article>
        <h1>Hellow World, meow</h1>
    </article>
</div>

CSS :

body {
    background:#fad;
    padding:0;
    margin:0;
}

$arrow_width: 20px;
$arrow_height: 20px;
$box_color: #d3d030;

.wrap {
    img {
        width:100%;
        height:auto;
        vertical-align:bottom;
    }
    article{
        padding:20px;
        background:$box_color;
        color:#fff;
        position:relative;
    }
}
article:before, article:after{
    content:'';
    position:absolute;
    width:50%;
    bottom:100%;
    box-sizing:border-box;
}
article:before{
    left:0;
    border-bottom:20px solid #D3D030;
    border-right:20px solid transparent;
}
article:after{
    right:0;
    border-bottom:20px solid #D3D030;
    border-left:20px solid transparent;
}
web-tiki
  • 99,765
  • 32
  • 217
  • 249
1

Not sure about IE8, haven't got a copy on my VM, but you could approach it like this instead of pseudo elements

<div class="arrowborder">
    <div class="arrrowwrap arrowwrapleft"></div>
    <div class="arrrowwrap arrowwrapright"></div>
</div>

.arrrowwrap {
    box-sizing:border-box;
    width:50%;
    z-index:9999999;
    float:left;
}
.arrowwrapleft {
    border-right: $arrow_width solid transparent; 
    border-bottom: $arrow_height solid $box_color;
}
.arrowwrapright {
    border-left: $arrow_width solid transparent; 
    border-bottom: $arrow_height solid $box_color;
}

http://jsfiddle.net/dhs2eba2/8/

SubjectCurio
  • 4,702
  • 3
  • 32
  • 46