Clickable: https://gist.github.com/2644661
.arrowgasm(@position: top, @size : "4px", @background-color : #88b7d5,
@border-width: "2px", @border-color : #c2e1f5, @arrowClass : "arrow_box"){
(~".@{arrowClass}") {
position: relative;
background: @background-color;
border: @size solid @border-color;
}
(~".@{arrowClass}:after"), (~".@{arrowClass}:before") {
bottom: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
(~".@{arrowClass}:after") {
.b(@position, @background-color);
border-width: @size;
left: 50%;
margin-left: @size * -1;
}
(~".@{arrowClass}:before") {
.b(@position, @border-color);
border-width: @size + @border-width ;
left: 50%;
margin-left: ( @size + @border-width ) * -1;
}
.b(top, @border-color) { border-bottom-color: @border-color; }
.b(right, @border-color) { border-left-color: @border-color; }
.b(bottom, @border-color){ border-top-color: @border-color; }
.b(left, @border-color) { border-right-color: @border-color; }
} =triangle($direction: up, $size: 10px, $color: #000)
width: 0
height: 0
@if $direction == up
border-left: $size solid transparent
border-right: $size solid transparent
border-bottom: $size solid $color
@else if $direction == down
border-left: $size solid transparent
border-right: $size solid transparent
border-top: $size solid $color
@else if $direction == left
border-top: $size solid transparent
border-bottom: $size solid transparent
border-right: $size solid $color
@else if $direction == right
border-top: $size solid transparent
border-bottom: $size solid transparent
border-left: $size solid $color =triangle($direction: top, $size: 10px, $color: #000)
width: 0
height: 0
border: $size solid transparent
border-#{$dir}-color: $colorOP adds two triangles to whatever it is applied to, one for the border color, another to cover it up with the background color. And it doesn't require any additional elements... it just adds these to whatever you are applying it to.
It took me a moment to realize exactly what was going on to make this work. For those interested: borders are styled in such a way that they angle toward the edges if the border is large enough:
\ /
/ \
That gives you four "V"s to work with. Therefore, to create the arrow, you simply need to hide all but the appropriate border. The border around the arrow is accomplished by underlaying another "V".Ultimately, how the border is joined at the corners is undefined by the specification:
http://www.w3.org/TR/css3-background/#border-style
> Note: This specification does not define how borders of different styles should be joined in the corner. [...]Many rendering engines will join borders at an angle, producing those diagonal lines.
Adding border is a bit problematic but I'm sure solution could be found, just a question of few more minutes. Also, it should be doable in IE with filters.
The problem, more than anything, is the way these css-only triangles get aliased. Since they're a side-effect of rendering borders, they never get properly anti-aliased the way fonts and shape edges do, and as a result the edges end up jagged at certain sizes and color combinations.
Maybe it's time to propose a mask-shadow property?
I need to do exactly this in a google maps infobox, BUT with the dawn shadow... :( back to images I guess.
Thanks!
BTW, to hone your CSS skills, try dropping into Firebug or Chrome's developer tools and just playing around -- very easy way to learn and get CSS stuff done. The CSS panel lets you change rules and values and see the effects immediately. I know in Chrome I use the up/down arrows on a value to slide objects and spacing around on the screen regularly. The panel also helps greatly in understanding cascading; see also the "computed styles" section.
Anyway, I do have fun playing around with the FF style tools. It is quite cool and informative.
It looks awful on IE7 actually, the footer also degrades un-gracefully.
It is definitely a very cool and clean hack (more of these on HN, please), but not semantic at all: in the source there is not indication that the box is pointing at something or where it is pointing.
Looking at the domain name I thought it was a public request for a new CSS property like
p {
border-bottom-right-cap: solid-arrow-outward;
}This is a nice little tool to help automate the production of the code for simple ones.
If the light source moved along with the triangle, no shadow under the arrow would be required (imo).
I already feel sorry for anyone that will be debugging this mess.
I prefer to say that “IE8 is broken when attempting to render the demo page,” but either way, good catch.