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

前端 未结 3 1241
旧巷少年郎
旧巷少年郎 2020-12-10 04:07

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 wron

相关标签:
3条回答
  • 2020-12-10 04:29

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

    0 讨论(0)
  • 2020-12-10 04:47

    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/

    0 讨论(0)
  • 2020-12-10 04:48

    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;
    }
    
    0 讨论(0)
提交回复
热议问题