当用光标悬停时,如何在CSS三角形上保持适当的边界?

时间:2021-03-16 08:41:35

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.

是否有可能将悬停固定在http://jsfiddle.net/2AXhR/上,以便在悬停时激活正确的三角形而不是有时相邻的三角形?有时错误的三角形被激活,因为每个三角形元素的边界区域实际上不是一个三角形,而是一个矩形,所以即使光标看起来在一个三角形的顶部,它实际上位于另一个三角形重叠的顶部并具有更高的z指数。

当用光标悬停时,如何在CSS三角形上保持适当的边界?

  <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>

3 个解决方案

#1


11  

----- 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. IE忽略了溢出:隐藏;属性和悬停事件是在可见三角形之外触发的。

  3. For some reason there were lines apearing on the triangles in firefox.
  4. 出于某种原因,在Firefox中的三角形上有一些线条。

  5. the cursor comes back to default if it is between the triangles.
  6. 如果光标位于三角形之间,则光标返回默认值。

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.

这个aproach使用skewX()来创建三角形。你不需要“边界技巧”来创建它们,也不需要溢出属性。使用这种技术,根本没有重叠元素,因此悬停事件不能同时触发两个元素。

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

第二个div隐藏了倾斜元素的一半以创建三角形,并使用+ CSS选择器在悬停时进行翻译。


----- DEMO V2 ----- 当用光标悬停时,如何在CSS三角形上保持适当的边界?

----- 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

Vesrion 1(原创):演示V1的小提琴

#2


3  

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.

这里的示例 - 在FF / Chrome中工作在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;
}

#3


3  

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.

我实际上是自己解决了这个问题。使用JavaScript,我为每个三角形设置了一个悬停事件:在悬停时,我将自己的z-index设置为20,将下一个三角形的z-index设置为21,将所有其余三角形的z-index设置为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.

它起作用的原因是因为所有的三角形都是从左上方顺时针开始的顺序。每个三角形与其下一个兄弟不正确地重叠,因此通过将下一个兄弟在z平面中向前移动,它允许正确定义三角形。

Compare these two JSFiddles, and you'll see the difference in hover behavior:

比较这两个JSFiddles,你会看到悬停行为的不同:

Unsolved: http://jsfiddle.net/2AXhR/

Solved: http://jsfiddle.net/2AXhR/1/

#1


11  

----- 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. IE忽略了溢出:隐藏;属性和悬停事件是在可见三角形之外触发的。

  3. For some reason there were lines apearing on the triangles in firefox.
  4. 出于某种原因,在Firefox中的三角形上有一些线条。

  5. the cursor comes back to default if it is between the triangles.
  6. 如果光标位于三角形之间,则光标返回默认值。

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.

这个aproach使用skewX()来创建三角形。你不需要“边界技巧”来创建它们,也不需要溢出属性。使用这种技术,根本没有重叠元素,因此悬停事件不能同时触发两个元素。

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

第二个div隐藏了倾斜元素的一半以创建三角形,并使用+ CSS选择器在悬停时进行翻译。


----- DEMO V2 ----- 当用光标悬停时,如何在CSS三角形上保持适当的边界?

----- 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

Vesrion 1(原创):演示V1的小提琴

#2


3  

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.

这里的示例 - 在FF / Chrome中工作在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;
}

#3


3  

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.

我实际上是自己解决了这个问题。使用JavaScript,我为每个三角形设置了一个悬停事件:在悬停时,我将自己的z-index设置为20,将下一个三角形的z-index设置为21,将所有其余三角形的z-index设置为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.

它起作用的原因是因为所有的三角形都是从左上方顺时针开始的顺序。每个三角形与其下一个兄弟不正确地重叠,因此通过将下一个兄弟在z平面中向前移动,它允许正确定义三角形。

Compare these two JSFiddles, and you'll see the difference in hover behavior:

比较这两个JSFiddles,你会看到悬停行为的不同:

Unsolved: http://jsfiddle.net/2AXhR/

Solved: http://jsfiddle.net/2AXhR/1/