How can I maintain proper boundaries on CSS triangles when hovering with cursor?

css, css-shapes, html, javascript

Solution

----- Version 2, cleaner, better (fixes IE and FF issues) -----

Corrected issues :

- IE ignored the `overflow:hidden;` property and the hover events were fired outside the visible triangles.

- For some reason there were lines apearing on the triangles in firefox.

- the cursor comes back to default if it is between the triangles.

Description :

This aproach uses `skewX()` to create the triangles. You don't need the "border trick" to create them and you don't need the `overflow` property either. With this technique, there no overlapping elements at all so hover events can't fire two elements at the same time.

A second div hides half the skewed element to create the triangle and is translated with it on hover using the `+` CSS selector.

----- DEMO V2 -----

Markup :

<div class="t">
    <div class="wrap">
        <div class="triangle"></div>
        <div class="mask"></div>
    </div>
   <div class="wrap">
        <div class="triangle"></div>
        <div class="mask"></div>
    </div>
    <div class="wrap">
        <div class="triangle"></div>
        <div class="mask"></div>
    </div>
    <div class="wrap">
        <div class="triangle"></div>
        <div class="mask"></div>
    </div>
    <div class="wrap">
        <div class="triangle"></div>
        <div class="mask"></div>
    </div>
    <div class="wrap">
        <div class="triangle"></div>
        <div class="mask"></div>
    </div>
</div>

CSS :

.t div{
    position:absolute;
    top:0; left:0;

    transform-origin:0 0;
    -ms-transform-origin:0 0;
    -webkit-transform-origin:0 0;

    transition:all 1s;
    -webkit-transition:all 1s;
    -moz-transition:all 1s;
}

.t .wrap{
    top:50%; left:50%;

    -ms-transform: skewX(30deg);
    -webkit-transform: skewX(30deg);
    transform: skewX(30deg);
}

.t .wrap .triangle {
    position:relative;
    width: 200px;
    height: 173px;
    background-color: #0079c5;
    cursor:pointer;
    z-index:1;
}
.t .wrap .mask{
    width:100%;
    height:115.5%;
    background-color: #fff;
    left:100%;
    z-index:2;

    -ms-transform: skewX(-30deg) rotate(30deg);
    -webkit-transform: skewX(-30deg) rotate(30deg);
    transform: skewX(-30deg) rotate(30deg);
} 

.t .wrap .triangle:hover{
    background-color: #009cff;

    transform:  translate(10%, 10%);
    -webkit-transform: translate(10%, 10%);
    -moz-transform: translate(10%, 10%);
}

.t .triangle:hover + .mask{
    -ms-transform: skewX(-30deg) rotate(30deg) translate(17.5%, 0);
    -webkit-transform: skewX(-30deg) rotate(30deg) translate(17.5%, 0);
    transform: skewX(-30deg) rotate(30deg) translate(17.5%, 0);
}

.t > div:nth-child(2){
    -ms-transform: rotate(60deg) skewX(30deg);
    -webkit-transform: rotate(60deg) skewX(30deg);
    transform: rotate(60deg) skewX(30deg);
}
.t > div:nth-child(3){
    -ms-transform: rotate(120deg) skewX(30deg);
    -webkit-transform: rotate(120deg) skewX(30deg);
    transform: rotate(120deg) skewX(30deg);
}

.t > div:nth-child(4){
    -ms-transform: rotate(-60deg) skewX(30deg);
    -webkit-transform: rotate(-60deg) skewX(30deg);
    transform: rotate(-60deg) skewX(30deg);
}
.t > div:nth-child(5){
    -ms-transform: rotate(-120deg) skewX(30deg);
    -webkit-transform: rotate(-120deg) skewX(30deg);
    transform: rotate(-120deg) skewX(30deg);
}
.t > div:nth-child(6){
    -ms-transform: rotate(-180deg) skewX(30deg);
    -webkit-transform: rotate(-180deg) skewX(30deg);
    transform: rotate(-180deg) skewX(30deg);
}

Vesrion 1 (original) : fiddle for demo V1

Problem

Is it possible to fix the hovering on http://jsfiddle.net/2AXhR/ so that the correct triangle is activated on hover instead of its sometimes adjacent one? Sometimes the wrong triangle is activated because each triangle element's bounding area is not actually a triangle, but a rectangle, so even though the cursor may appear to be on top of one triangle, it is actually on top of another one that overlaps and has a higher z-index. ``` <style type="text/css"> .t { position:relative; top:55px; left:5px; } .t div { position:absolute; width: 0px; height: 0px; border-style: solid; border-width: 0 100px 173.2px 100px; border-color: transparent transparent #0079c5 transparent; transition:all 1s; -webkit-transition:all 1s; -moz-transition:all 1s; cursor:pointer; transform-origin:200px 173px; -webkit-transform-origin:200px 173px; -moz-transform-origin:200px 173px; z-index:10; } .t div:hover { z-index:20; border-color: transparent transparent #009cff transparent; } .t div:nth-child(1) { transform:rotate(30deg); -webkit-transform:rotate(30deg); -moz-transform:rotate(30deg); } .t div:nth-child(1):hover { transform:rotate(30deg) translate(-15%, -10%); -webkit-transform:rotate(30deg) translate(-15%, -10%); -moz-transform:rotate(30deg) translate(-15%, -10%); } .t div:nth-child(2) { transform:rotate(90deg); -webkit-transform:rotate(90deg); -moz-transform:rotate(90deg); } .t div:nth-child(2):hover { transform:rotate(90deg) translate(-15%, -10%); -webkit-transform:rotate(90deg) translate(-15%, -10%); -moz-transform:rotate(90deg) translate(-15%, -10%); } .t div:nth-child(3) { transform:rotate(150deg); -webkit-transform:rotate(150deg); -moz-transform:rotate(150deg); } .t div:nth-child(3):hover { transform:rotate(150deg) translate(-15%, -10%); -webkit-transform:rotate(150deg) translate(-15%, -10%); -moz-transform:rotate(150deg) translate(-15%, -10%); } .t div:nth-child(4) { transform:rotate(210deg); -webkit-transform:rotate(210deg); -moz-transform:rotate(210deg); } .t div:nth-child(4):hover { transform:rotate(210deg) translate(-15%, -10%); -webkit-transform:rotate(210deg) translate(-15%, -10%); -moz-transform:rotate(210deg) translate(-15%, -10%); } .t div:nth-child(5) { transform:rotate(270deg); -webkit-transform:rotate(270deg); -moz-transform:rotate(270deg); } .t div:nth-child(5):hover { transform:rotate(270deg) translate(-15%, -10%); -webkit-transform:rotate(270deg) translate(-15%, -10%); -moz-transform:rotate(270deg) translate(-15%, -10%); } .t div:nth-child(6) { transform:rotate(330deg); -webkit-transform:rotate(330deg); -moz-transform:rotate(330deg); } </style> <div class="t"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </div> ```

Original source