继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

html指令式tooltip文字提示,css实现,无脚本

慕码人8056858
关注TA
已关注
手记 1247
粉丝 350
获赞 1323
无图言屌

webp

分析执行流程
  1. 鼠标移入节点

  2. 检测是该节点是否存在开启实现tooltip实现的标识(类名,属性等)

  3. 检测主题、位置(类名,属性等)

  4. 生成 / 显示气泡


借鉴他人

让我们先来看看element-ui的tooltip样式

webp

很明显,气泡的位置是通过javascript脚本加上去的

webp


不多逼逼,让我们来定几个期望
  1. 不用javascript脚本,纯css实现

  2. 不用添加新元素(用after、before伪元素)

  3. 不用类名匹配,直接用属性选择器([attr])

  4. 支持默认样式(标签没定义主题、位置的时候)

  5. 指令式(直接在标签定义即可,接下来交给css匹配)

  6. 实现气泡的主题、位置

  7. sass预处理器开发(看不懂的同学可以转换成css


html定义指令规范

指令式声明

<button tooltip='我是内容鸭' effect='light' placement='top-left'>上左</button>
  • tooltip — 气泡显示的内容

  • effect — 气泡的主题(dark / light),默认dark;

  • placement — 气泡相对于父元素的位置(top / top-left/ top-right / right / right-top/ right-bottom...),默认top;


先写几个按钮

样式借鉴element-ui

webp


<div class="container">
  <div class="top">
    <button tooltip="上边" placement="top-left" effect="light">上左</button>
    <button tooltip="上左上左" placement="top">上边</button>
    <button tooltip="上右" placement="top-right">上右</button>
  </div>
  <div class="left">
    <button tooltip="左上左上左上左上左上左上左上左上左上左上" placement="left-top">左上</button>
    <button tooltip="左边" placement="left" effect="light">左边</button>
    <button tooltip="左右" placement="left-bottom">左下</button>
  </div>
  <div class="right">
    <button tooltip="右上右上右上右上右上右上右上右上" placement="right-top">右上</button>
    <button tooltip="右边" placement="right" effect="light">右边</button>
    <button tooltip="右下" placement="right-bottom">右下</button>
  </div>
  <div class="bottom">
    <button tooltip="下左下左" placement="bottom-left">下左</button>
    <button tooltip="下边" placement="bottom" effect="light">下边</button>
    <button tooltip="下右" placement="bottom-right">下右</button>
  </div></div>
css核心代码逻辑实现

hover监听鼠标移入、移出,[tooltip]匹配有该属性的标签,after为气泡,before为三角形

/* 匹配有tooltip属性的元素 */[tooltip] {
  position: relative;  /* 气泡默认样式 */
  &::after {
    display: none;
    content: attr(tooltip);
  }  /* 三角形默认样式 */
  &::before {
    display: none;
    content: '';
  }  /* 鼠标移入该元素,显示气泡、三角形 */
  &:hover {

    &::after {
      display: block;
    }

    &::before {
      display: block;
    }
  }
}

现在鼠标移入之后便有效果


webp


为了方便看到效果,测试可以把气泡、三角形默认为block
/* 气泡默认样式 */&::after {  display: block;  content: attr(tooltip);
}/* 三角形默认样式 */&::before {  display: block;  content: '';
}

目前效果如下

webp

设置气泡、三角形的默认样式

核心显示当然是设置绝对定位了

/* 气泡默认样式 */&::after {
  display: block;
  content: attr(tooltip);
  position: absolute;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 8px 15px;
  max-width: 200px;
  border-radius: 4px;
  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.4);
  z-index: 100;  @extend .tooltip-theme-dark; /* 继承默认主题(黑底白字) */
 }/* 三角形默认样式 */&::before {
  display: block;
  content: '';
  position: absolute;
  border: 5px solid transparent;
  z-index: 100;  @extend .triangle-theme-dark; /* 继承默认主题(黑底) */}

目前效果如下

webp


定制气泡、三角形主题色

定义好各两种主题

$white: #fff;$black: #313131;/* 气泡主题 */.tooltip-theme-dark {
  color: $white;
  background-color: $black;
}

.tooltip-theme-light {
  color: $black;
  background-color: $white;
  border: 1px solid $black;
}/* 三角形主题 */.triangle-theme-dark {
  border-top-color: $black;
}

.triangle-theme-light {
  border-top-color: $black; /* 暂时跟dark一样 */}

定制气泡、三角形位置(只示例一个方向)
/* 气泡位置 *//*----上----*/.tooltip-placement-top {  bottom: calc(100% + 10px);  left: 50%;  transform: translate(-50%, 0);
}.tooltip-placement-top-right {  bottom: calc(100% + 10px);  left: 100%;  transform: translate(-100%, 0)
}.tooltip-placement-top-left {  bottom: calc(100% + 10px);  left: 0;  transform: translate(0, 0)
}/* 三角形位置 *//*----上----*/.triangle-placement-top {  bottom: calc(100% + 5px);  left: 50%;  transform: translate(-50%, 0);
}.triangle-placement-top-left {  bottom: calc(100% + 5px);  left: 10px;
}.triangle-placement-top-right {  bottom: calc(100% + 5px);  right: 10px;
}
捕捉位置、主题

这里也算最核心的代码了,用属性选择器来匹配标签上的值,然后设置不同的样式

匹配气泡、三角形主题

&[effect="light"] {
  &::after {
    @extend .tooltip-theme-light;
  }

  &::before {
    @extend .triangle-theme-light;
  }
}

匹配气泡、三角形位置,12种位置

@each $placement in top,top-right,top-left,
right,right-top,right-bottom,
bottom,bottom-right,bottom-left,
left,left-top,left-bottom {
  &[placement="#{$placement}"] {
    &::after {
      @extend .tooltip-placement-#{$placement};
    }

    &::before {
      @extend .triangle-placement-#{$placement};
    }
  }
}

标签不存在placement 属性 / 为空的时候,默认继承top位置

&:not([placement]),
&[placement=""] {
  &::after {
    @extend .tooltip-placement-top;
  }

  &::before {
    @extend .triangle-placement-top;
  }
}

目前效果如下

webp

让我们把文字放长,把气泡、三角形的默认样式加上display:none看看

加个动画

分四个方向,上下左右,四个动画

@keyframes anime-top {  from {    opacity: .5;    bottom: 150%;
  }
}

@keyframes anime-bottom {  from {    opacity: .5;    top: 150%;
  }
}

@keyframes anime-left {  from {    opacity: .5;    right: 150%;
  }
}

@keyframes anime-right {  from {    opacity: .5;    left: 150%;
  }
}

匹配气泡位置从而来确定执行哪个动画,用[attr^=]选择,如 上左、上右也能匹配到

/* 设置动画 */@each $placement in top,
 right,
bottom,
left {
  &[placement^="#{$placement}"] {

    &::after,
    &::before {
      animation: anime-#{$placement} 300ms ease-out forwards;
    }
  }
}

最终效果如下


webp

关于主题为light的三角形样式

由于现在用的是before + broder,相当于单标签,实现不了啦,怎么都要利用两个以上,一黑一白然后叠加,现在after又用来做气泡了... 不过换种做法

&::before {  content: 'Δ';  color: #313131;
}

最后附上codepen地址https://codepen.io/anon/pen/yRBXBY

本文到此结束,喜欢的话给个like哦



作者:daydreammoon
链接:https://www.jianshu.com/p/42e04b89e291


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP