Prevent CSS tooltip from going out of page/window

后端 未结 5 2085
时光说笑
时光说笑 2021-02-01 04:39

I have a CSS only tooltip which loads a span as a tooltip when you hover the link. However this is positioned with CSS but if the link is near to the t

5条回答
  •  灰色年华
    2021-02-01 05:01

    Unfortunately, if you want to keep your tooltip good positioning, it isn't possible using only CSS.

    Script solutions

    But, as you're already using some script, I suggest you this solution:

    • Use position: absolute to position the .ktooltiptext accordingly to .ref,
    • Use the .getBoundingClientRect() method to easily get the position and size of the tooltip,
    • Apply some correction if out of the window,
    • Also made some modifications in CSS.

    Snippet with only native JavaScript (avoiding jQuery, document will be lighter.)

    var ktooltips = document.querySelectorAll(".ktooltip");
    ktooltips.forEach(function(ktooltip, index){                // For each ktooltip
      ktooltip.addEventListener("mouseover", position_tooltip); // On hover, launch the function below
    })
    
    function position_tooltip(){
      // Get .ktooltiptext sibling
      var tooltip = this.parentNode.querySelector(".ktooltiptext");
      
      // Get calculated ktooltip coordinates and size
      var ktooltip_rect = this.getBoundingClientRect();
    
      var tipX = ktooltip_rect.width + 5; // 5px on the right of the ktooltip
      var tipY = -40;                     // 40px on the top of the ktooltip
      // Position tooltip
      tooltip.style.top = tipY + 'px';
      tooltip.style.left = tipX + 'px';
    
      // Get calculated tooltip coordinates and size
      var tooltip_rect = tooltip.getBoundingClientRect();
      // Corrections if out of window
      if ((tooltip_rect.x + tooltip_rect.width) > window.innerWidth) // Out on the right
        tipX = -tooltip_rect.width - 5;  // Simulate a "right: tipX" position
      if (tooltip_rect.y < 0)            // Out on the top
        tipY = tipY - tooltip_rect.y;    // Align on the top
    
      // Apply corrected position
      tooltip.style.top = tipY + 'px';
      tooltip.style.left = tipX + 'px';
    }
    .ref,
    .refs {
      position: relative;
    }
    
    .ktooltip {
      display: inline-block;
      text-indent: 0em;
    }
    
    .ref .ktooltiptext,
    .refs .ktooltiptext {
      visibility: hidden;
      width: 200px;
      background: #fff;
      border-radius: 6px;
      padding: 5px;       /* TAKIT: Changed here */
      top: -999px;        /* TAKIT: Changed here */
      left: -999px;       /* TAKIT: Changed here */
      border: 2px solid grey;
      line-height: normal;
      position: absolute; /* TAKIT: Changed here */
      z-index: 1;
    }
    
    .ref:hover .ktooltiptext,
    .refs:hover .ktooltiptext {
      visibility: visible;
    }

    My hope is in a bishop, 1 According to tradition Nicholas was bishop of Myra in Lycia (south-west Turkey today).
    and in almighty God and his never-ending miracles.
    Generous Saint Nicholas holds an office,
    there is a gold symbol in his sign. 20 One of Nicholas’s symbols was three bags of gold which were the dowry he provided for three girls

    Snippet with jQuery

    $(".ktooltip").mouseover(function(e) {
      var tooltip = $(this).siblings('.ktooltiptext'); // Get tooltip element (ktooltiptext)
      var tipX = $(this).outerWidth() + 5;             // 5px on the right of the ktooltip
      var tipY = -40;                                  // 40px on the top of the ktooltip
      tooltip.css({ top: tipY, left: tipX });          // Position tooltip
    
      // Get calculated tooltip coordinates and size
      var tooltip_rect = tooltip[0].getBoundingClientRect();
      // Corrections if out of window
      if ((tooltip_rect.x + tooltip_rect.width) > $(window).width()) // Out on the right
        tipX = -tooltip_rect.width - 5; // Simulate a "right: tipX" position
      if (tooltip_rect.y < 0)            // Out on the top
        tipY = tipY - tooltip_rect.y;    // Align on the top
    
      // Apply corrected position
      tooltip.css({ top: tipY, left: tipX }); 
    });
    .ref,
    .refs {
      position: relative;
    }
    
    .ktooltip {
      display: inline-block;
      text-indent: 0em;
    }
    
    .ref .ktooltiptext,
    .refs .ktooltiptext {
      visibility: hidden;
      width: 200px;
      background: #fff;
      border-radius: 6px;
      padding: 5px;       /* TAKIT: Changed here */
      top: -999px;        /* TAKIT: Changed here */
      left: -999px;       /* TAKIT: Changed here */
      border: 2px solid grey;
      line-height: normal;
      position: absolute; /* TAKIT: Changed here */
      z-index: 1;
    }
    
    .ref:hover .ktooltiptext,
    .refs:hover .ktooltiptext {
      visibility: visible;
    }
    
    

    My hope is in a bishop, 1 According to tradition Nicholas was bishop of Myra in Lycia (south-west Turkey today).
    and in almighty God and his never-ending miracles.
    Generous Saint Nicholas holds an office,
    there is a gold symbol in his sign. 20 One of Nicholas’s symbols was three bags of gold which were the dowry he provided for three girls

    With any of the above snippets, you can play with your window to see that the pop-up won't go outside on the right! It shouldn't go out on the top as well.


    ⋅ ⋅ ⋅

    A CSS only suggestion

    Now, if you don't care that much about the positioning of your tooltip, you can use this solution where I didn't change any of your HTML:

    • Use position: relative; on the span elements to use it as a reference,
    • Use position: absolute on the .ktooltiptext,
    • Use top and left to position the .ktooltiptext as you wish.

    Using that solution, the tooltip will keep its style, but would be aligned on the left, under the span element, so the tooltip should never go out on the right or on the top.

    p span { /* TAKIT: Changed here */
      position: relative;
    }
    
    .ktooltip {
      display: inline-block;
      text-indent: 0em;
    }
    
    .ref .ktooltiptext,
    .refs .ktooltiptext {
      visibility: hidden;
      width: 200px;
      background: #fff;
      border-radius: 6px;
      padding: 5px;       /* TAKIT: Simplified here */     
      border: 2px solid grey;
      line-height: normal;
      position: absolute; /* TAKIT: Changed */
      top: 20px;          /* TAKIT: Changed */
      left: 0;            /* TAKIT: Added to always align tooltip on the left of the span */ 
      z-index: 1;
    }
    
    .ref:hover .ktooltiptext,
    .refs:hover .ktooltiptext {
      visibility: visible;
    }

    My hope is in a bishop, 1 According to tradition Nicholas was bishop of Myra in Lycia (south-west Turkey today).
    and in almighty God and his never-ending miracles.
    Generous Saint Nicholas holds an office,
    there is a gold symbol in his sign. 20 One of Nicholas’s symbols was three bags of gold which were the dowry he provided for three girls

提交回复
热议问题