Moving the arrow from the bottom to the left side of the tooltip in the tooltip widget (jQuery UI 1.9)

StackOverflow https://stackoverflow.com/questions/13248357

문제

I'm using a speech bubble style tooltip based on the jquery ui tooltip widget 'Custom Styling' demo, but I'm having trouble properly displaying the arrow when I need it on the left side of the tooltip instead of on the top or bottom.

Can someone help me fix this code (it cuts off the tip and displays too large a section of the arrow)?

<style type="text/css"> 

   .ui-tooltip.menu_info {
        max-width: 200px;
    }      
* html .ui-tooltip {
    background-image: none;
}
body .ui-tooltip { border-width: 1px; }
    .ui-tooltip, .arrow:after, .arrow_left_side:after {
        background: white;
        border: 1px solid #999;       

    }       
    .ui-tooltip {
        padding: 10px 12px;
        color: Black;
        font: 8pt "Helvetica Neue", Sans-Serif;   
        max-width: 150px;
        border: 1px solid #999;
    position: absolute;
    }           
    .arrow_left_side {       
        height: 70px;
        width: 8px;    
        overflow: hidden;
        position: absolute;
        top: 0px;
        margin-top: 5px;
        left: -8px;
    }   
    .arrow_left_side:after {
        content: "";
        position: absolute;
        width: 25px;    height: 25px;
        -webkit-transform: rotate(45deg);
        -moz-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
        -o-transform: rotate(45deg);
        tranform: rotate(45deg);
    }
     </style>   
 <script>
$(function() {
    $('.menu_info').tooltip({
        position: {
            my: "left+20 center",
            at: "right center",
            using: function (position, feedback) {
                $(this).css(position);
                $("<div>")
                        .addClass("arrow_left_side")
                        .addClass(feedback.vertical)
                        .addClass(feedback.horizontal)
                        .appendTo(this);
            }
        }
    });
});
</script>
도움이 되었습니까?

해결책

Problem Description

The problem is caused by a combination of the CSS transformation and the overflow:hidden. The arrow is actually a square with width and height that is rotated 45o. The default origin point for the rotation is 50% 50% or center center which results in the "arrow" square being rotated around the middle which results in the edges being clipped by the overflow property.

It's best shown as an image or a demo (Webkit only), but the code used to demonstrate the problem is also below.

CSS rotation example

The 1st box shows the starting position of the "arrow" square, the 2nd box shows a small rotation around the center point. You can see that the edge is clipped already by the containing block's overflow:hidden. The 3rd shows a 45o rotation which demonstrates the problem you have. The 4th adds CSS to move the origin point to 0 25px, that is x=0, y=25px which is the bottom left corner, so you can see a small rotation around this point is looking better. The 5th pane shows a full 45o rotation around the modified origin. This looks much better and all that is left to do is reduce the width of the container to clip off the right hand side which leaves a left facing arrow. Then some simple CSS positioning to move it into place next to the tooltip content.

Solution

The modification needed to your CSS are small positioning changes on the container and the addition of an origin point for the rotation. I realise in the above description that I said an origin of 0 25px but in practice the arrow was still being clipped on the left side so I moved the origin out to 5px 25px instead.

.arrow_left_side {       
    margin-top: -5px;
    left: -10px;
}   
.arrow_left_side:after {
    -webkit-transform-origin: 5px 25px;
    /* for brevity, I have not added all the different browser prefix versions of transform-origin. If you need cross browser support, you will need to add these here */
}

See demo of the above changes

Demo Code

For completeness, here is the code to generate the above image. It's useful to interact with the demo by changing the rotation in the Chrome DevTools to see the square rotating in real time.

HTML

<div class="original"></div>
<div class="original-rotated-a-little"></div>
<div class="original-rotated-forty-five"></div>
<div class="original-with-transform-origin-rotated-a-little"></div>
<div class="original-with-transform-origin-rotated-forty-five"></div>

CSS

body {
    margin-left:50px
}
div {
    position:relative;
    height: 50px;
    width: 35px;    
    overflow: hidden;
    top: 0px;
    margin-top: 5px;
    left: -8px;
    border:1px dashed red;
}   
div:after {
    content: "";
    position: absolute;
    border: 1px solid #999;
    width: 25px;
    height: 25px;
}
div.original-rotated-a-little:after {
    -webkit-transform: rotate(15deg);
}
div.original-rotated-forty-five:after {
    -webkit-transform: rotate(45deg);
}
div.original-with-transform-origin-rotated-a-little:after {
    -webkit-transform-origin: 5px 25px;
    -webkit-transform: rotate(15deg);
}
div.original-with-transform-origin-rotated-forty-five:after {
    -webkit-transform-origin: 5px 25px;
    -webkit-transform: rotate(45deg);
}

Hope this helps :-)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top