Is it possible to fix the hovering on / 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>
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>
Share
Improve this question
edited Feb 19, 2015 at 18:02
web-tiki
104k33 gold badges224 silver badges257 bronze badges
asked Apr 16, 2014 at 11:07
Dane IracleousDane Iracleous
1,7592 gold badges16 silver badges39 bronze badges
7
- 1 Works very good in Firefox 27, can't reproduce what you're describing. Where do you experience these issues or what exactly can one do to reproduce what you're trying to solve? Btw., good work so far. :) – try-catch-finally Commented Apr 20, 2014 at 20:45
- Is IE 8 a browser you need to support? – web-tiki Commented Apr 20, 2014 at 21:07
- 1 I just edited my post to include an image and a new JSFiddle, where you can modify the properties of the hexagon. Try placing your cursor just below the top right triangle. You'll notice that even though the cursor is outside its bounds, it still activates it rather than the adjacent triangle below. I do not need to support IE8. – Dane Iracleous Commented Apr 20, 2014 at 21:42
- You can create a triangle in each triangle, the internal triangle dimensions is exactly the dimensions of the triangular shape which is the rest of the rectangle, so the hover, or mouseOver will work just on the right triangle not all the rectangle – Mujtaba Fadhil Commented Apr 20, 2014 at 22:33
- @web-tiki did you read the code? IE8? really? – Yaron U. Commented Apr 20, 2014 at 22:44
3 Answers
Reset to default 12 +50----- 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
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;
}
I actually solved the problem on my own. Using JavaScript, I set a hover event for each triangle: On hover, I set its own z-index to 20, the next triangle's z-index to 21, and all the rest of the triangles' z-index to 19.
The code looks like this:
self.e.find(".t div").hover(
function() {
$(this).css({
'z-index': 20,
'border-color': "transparent transparent "+self.params['colorSelected']+" transparent"
});
if($(this).next().length) {
$(this).next().css("z-index", 21);
} else {
self.e.find(".t div").first().css("z-index", 21);
}
},
function() {
self.e.find(".t div").css({
'z-index': 19,
'border-color': "transparent transparent "+self.params['color']+" transparent"
});
});
The reason why it works is because all the triangles are in order starting from the top left going clockwise. Each triangle incorrectly overlaps its next sibling, so by bringing the next sibling forward in the z plane, it allows the triangles to be defined correctly.
Compare these two JSFiddles, and you'll see the difference in hover behavior:
Unsolved: http://jsfiddle.net/2AXhR/
Solved: http://jsfiddle.net/2AXhR/1/