使用CSS或JS进行工具提示定位

时间:2017-01-02 16:13:40

标签: javascript css tooltip

我正在使用CSS为Web应用创建工具提示。到目前为止,我有一个非常方便的工具提示与以下类:

  • tooltip-up
  • tooltip-down
  • tooltip-left
  • 工具提示右

每个的差异是箭头和动画。例如,“工具提示右”这个类的箭头朝向左侧,它从左侧向右侧动画。

enter image description here

当工具提示包含大量文本时,问题就出现了,当工具提示中有大量文本时,工具提示左侧,右侧和-up位置都不同。工具提示向下没有问题,因为默认情况下所有内容都向下包装。

enter image description here

所以我的问题是,是否有可能只用CSS来完美地定位工具提示。或者是否会涉及一些JS,如果是这样,你建议做什么?也许添加检查以查看工具提示有多少文本并为保证金添加一些内联css?作为一个例子,我试图复制http://foundation.zurb.com/sites/docs/v/5.5.3/components/tooltips.html,我们正在使用基础,但它和Angular似乎存在一些问题。

这是我到目前为止的一些代码:

  .tooltip-up,
  .tooltip-down,
  .tooltip-left,
  .tooltip-right {
    font-size: 12px;
    position: absolute;
    text-align: center!important;
    visibility: hidden;
    background-color: rgba($gray, 0.99);
    color: #fff;
    text-align: left;
    border-radius: 3px;
    width: 250px;
    height: auto;
    padding: 7px 10px;
    z-index: 1;
    opacity: 0;
    box-shadow: 0 2px 5px 0 rgba($solid-black, 0.16), 0 2px 10px 0 rgba($solid-black, 0.12);
    @include transition (.2s ease-in);
  }

  .tooltip-right {
    top: -35%;
    left: 135%;
    transform: translateX(-15%);
    margin-top: -10px;

    &:after {
      border-right: 7px solid rgba($gray, 0.99);
      border-bottom: 7px solid transparent;
      border-top: 7px solid transparent;
      top: 50%;
      content: " ";
      height: 0;
      left: -7px;
      position: absolute;
      width: 0;
      transform: translateY(-50%);
    }

  }

请注意,有四个工具提示类,因此您的解决方案也必须考虑左,右和顶部的工具提示。事先感谢您提供任何信息和帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用已经用于定位箭头的相同技巧:将translateY(-50%)position: absolutetop: 50%结合使用。

由于50%与工具提示相关,因此它始终保持居中。两个陷阱:

  • 注意您不要将工具提示翻译出视图
  • 有时,如果高度是奇数像素大小,文字会变得模糊。例如:高度为27px将使工具提示向下移动13.5px。

p { display: inline-block; position: relative; border: 1px solid red; }

.tooltip-right {
  box-sizing: border-box;
  font-size: 12px;
  position: absolute;
  text-align: center;
  background-color: black;
  color: #fff;
  text-align: left;
  border-radius: 3px;
  width: 250px;
  padding: 7px 10px;
  z-index: 1;
  opacity: .8;
  
  top: 50%;
  right: 0;
  /* width + arrow width = 250 + 7 = 257 */
  transform: translate3d(257px, -50%, 0);
}

.tooltip-right::after {
  content: "";

  border-right: 7px solid black;
  border-bottom: 7px solid transparent;
  border-top: 7px solid transparent;
  
  position: absolute;
  height: 0;
  width: 0;
  left: -7px;
  top: 50%;
 
  transform: translateY(-50%);
}
<h2>Use translateY for positioning</h2>
<p>
  <span>
    Lorem ipsum
  </span>
  <span class="tooltip-right">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
  </span>
</p>

答案 1 :(得分:0)

尝试:

.tooltip-up,
.tooltip-down,
.tooltip-left,
.tooltip-right {
    font-size: 12px; /* I think you should use the unit em instead for better scaling */
    position: absolute;
    text-align: center!important; /* why !important ? */
    visibility: hidden; /* I think you should remove this line since you set opacity to 0 */
    background-color: rgba($gray, 0.99);
    color: #fff;
    text-align: left; /* I think you should remove this line */
    border-radius: 3px;
    width: 250px; /* I think you should use the unit em instead */
    height: auto; /* I think you should remove this line, for auto is the default value */
    padding: 7px 10px; /* I think you should use the unit em instead */
    z-index: 1; /* I think you should set this to the next greatest value in your code, just in case */
    opacity: 0;
    box-shadow: 0 2px 5px 0 rgba($solid-black, 0.16), 0 2px 10px 0 rgba($solid-black, 0.12);
    @include transition (.2s ease-in);
}

.tooltip-right {
    top: -35%;
    left: 135%;
    transform: translateX(-15%);
    margin-top: -10px;

&:after {
    border-right: 7px solid rgba($gray, 0.99);
    border-bottom: 7px solid transparent;
    border-top: 7px solid transparent;
    top: 1em; /* Try what works best, but don't use % because when there's a lot of text, the arrow would fall off place */
    content: "";
    height: 0;
    left: -7px;
    position: absolute;
    width: 0;
    transform: translateY(-50%);
}

}