# hover-visible的原理及使用方式 常见的交互场景,某个元素在一般情况下隐藏,当鼠标悬浮到父元素上之后,该元素显示 ![示例](../images/48.gif) FineUI中提供了两种方式实现这种效果,分开举例 # less .hover-visible() mixin ## 源码分析 利用less强大的混合功能,默认状态`visibility:hidden`,在父级容器hover时状态变成`visibility:visible` ```less .hover-visible(@cls) { & .@{cls} { visibility: hidden; } &:hover { & .@{cls} { visibility: visible; } } } ``` ## 应用示例 在编写less代码时,只需要在对应父级class下面加入`.hover-visible()`mixin即可 ```less .my-demo { .hover-visible(add-button); } ``` 编译为css ```css .my-demo .add-button { visibility: hidden; } .my-demo:hover .add-button { visibility: visible; } ``` ## .hover-visible有什么缺陷吗? 众所周知,`visibility:hidden`仅仅隐藏了元素,但依旧占据文档流位置的,入下图所示,这样白白浪费了节点右侧可以利用的空间,体验不好. ![示例](../images/46.png) 为了应对这种非常常见的场景,FineUI提供了一套样式方案: # .hover-visible-container .hover-visible-item 兄弟搭配,其力断金.一套class类名组合,提升编码效率. ## 源码分析 首先,基于`visibility:hidden`的不足,我们期望元素隐藏时能够`display:none`,父级元素hover时正常显示出来. 借助css3 `:where`和`:not`伪类,我们巧妙的实现了这一功能 ```less .bi-hover-visible-container { & .bi-hover-visible-item { visibility: hidden; } &:hover .bi-hover-visible-item { visibility: visible; } &:where(:not(&:hover)) .bi-hover-visible-item { display: none; } } ``` 用通俗语音解释,前两天规则很容易理解:默认状态`bi-hover-visible-item`隐藏,父节点hover时`bi-hover-visible-item`显示 最后一条是什么含义呢? 当父节点`bi-hover-visible-container`没被hover的时候,子节点`bi-hover-visible-item`的样式为`display: none` 这样一来,是不是完美了,正常状态被隐藏的元素不占据dom空间,当hover的时候,由于失去了`display: none`规则,那么其恢复成了原始的状态,`display:block`或`display:flex`,重新占据文档流 ![示例](../images/49.gif) ## IE浏览器上需要注意的点 由于IE浏览器不支持`:where`和`:not`,因此在IE上始终占据空间 其次对于使用`bi-hover-visible-container`和`bi-hover-visible-item`组合类名的形式,在IE上不能嵌套使用. `.bi-hover-visible-container` > `.bi-hover-visible-item` > `.bi-hover-visible-container` > `.bi-hover-visible-item` 的组合是不行的 对于这种场景,可以采用原始的less方法`.hover-visible()`处理