Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

The yellow overlay shows the bounds of the top right triangle. It overlaps with its adjacent triangle below, which means when the cursor is in the small area shared by both, the behavior is not consistent.

  <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>
like image 855
Dane Iracleous Avatar asked Apr 16 '14 11:04

Dane Iracleous


2 Answers

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

Corrected issues :

  1. IE ignored the overflow:hidden; property and the hover events were fired outside the visible triangles.
  2. For some reason there were lines apearing on the triangles in firefox.
  3. 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 ----- snapshot devtools showing the triangle boundaries




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

like image 146
web-tiki Avatar answered Oct 16 '22 09:10

web-tiki


Here is a completely different approach. It avoids the boundary issues completely.

It's worth noting that this approach is relatively limited when it comes to achieving the hover effect you had in place. I'm currently looking at alternatives.

EXAMPLE HERE - Works in FF/Chrome it fails in IE11.

HTML

<div class="t">
    <div class="clip">
        <div class="triangle"></div>
    </div>
    <div class="clip">
        <div class="triangle"></div>
    </div>
    <div class="clip">
        <div class="triangle"></div>
    </div>
    <div class="clip">
        <div class="triangle"></div>
    </div>
    <div class="clip">
        <div class="triangle"></div>
    </div>
    <div class="clip">
        <div class="triangle"></div>
    </div>
</div>

CSS

.t {
    width:500px;
    height:500px;
    position:relative;
}
.t > .clip {
    overflow: hidden;
    position: absolute;
    width: 50%;
    height: 50%;
    -webkit-transform-origin: 100% 100%;
}
.t > .clip:first-child {
    -webkit-transform: rotate(60deg) skewY(30deg);
}
.t > .clip:nth-child(2) {
    -webkit-transform: rotate(120deg) skewY(30deg);
}
.t > .clip:nth-child(3) {
    -webkit-transform: rotate(180deg) skewY(30deg);
}
.t > .clip:nth-child(4) {
    -webkit-transform: rotate(240deg) skewY(30deg);
}
.t > .clip:nth-child(5) {
    -webkit-transform: rotate(300deg) skewY(30deg);
}
.t > .clip:nth-child(6) {
    -webkit-transform: rotate(360deg) skewY(30deg);
}
.triangle {
    width: 200%;
    height: 200%;
    -webkit-transform: skewY(-42deg) skewX(-20deg) rotate(-15.5deg);
    background:#0079c5;
}
.triangle:hover {
    background:#009cff;
}
like image 20
Josh Crozier Avatar answered Oct 16 '22 08:10

Josh Crozier