欢送关注我的公众号:前端侦探

通常状况下,hover 是无奈保留状态的。鼠标移入触发额定款式,一旦移出就还原了

el:hover{  color: red}

这就意味着,如果须要保留hover的状态,可能就不得不借助JS了,比方上面是某某书院的首页排行榜成果

这里的次要交互有以下几个

  1. 鼠标滑过触发选中态
  2. 鼠标移出列表后依然保留上一次的选中态(重点)
  3. 默认列表的第一项为选中态

目前官网的实现也是通过JS实现的,事实上,仅仅通过 CSS也是能够齐全做到的,须要用到transition延时的一些小技巧,一起看看吧

一、鼠标滑过触发选中态

所有的所有都离不开布局。

假如列表HTML是这样的

<ul class="list">    <li class="item">      <h3 class="title">将军,夫人喊你种田了</h3>      <p class="sumary">只是在休息室里打了个盹儿,一睁眼,居然穿成了现代目不识丁的乡下胖丫头。 好逸恶劳不说,还在村里作威作福。 十里八乡没人违心娶她,好不容易买了个金龟婿,大婚之日竟让人逃了。 恶霸老爹一怒之下去道上掳了个夫君给她。 就是……爹你掳的是不是有点不太对呀? * 婚后的苏胖丫很忙。 忙着革新恶霸爹爹与恶霸弟弟。 忙着抢救貌美如花的神将夫君。 忙着养育三个小小恶霸小豆丁。 一不小心,将本人忙成了大燕最位高权重的一品女侯!</p>    </li>  <li class="item">      <h3 class="title">被夺所有后她封神回归</h3>      <p class="sumary">【甜爽燃,团宠,玄学】 司扶倾一睁眼,不仅被夺了气运,人人还让她滚出娱乐圈。 轻活一次,她只想咸鱼躺,谁知当初圈内人只知拉踩营销,没点真本事,不好好磨炼演技,这样上来还能行?怎么也得拾掇拾掇。 司扶倾捏了捏手段,动了。 起初,网上疯狂骂她不自量力倒贴郁曜,辟谣她私生活不检点,而—— 国内天后:明天我能站在这里,多亏了倾倾 top1男顶流:离我妹妹远点@郁曜 就连国内运动会官网:祝贺司扶倾拿下第13枚集体金牌,等一个退圈 当天,全网瘫痪。 · 史书记录,胤皇年少成名,八方征战,平天下,安宇内,是大夏朝最年老的帝王,他完满弱小,心怀天下,却因病死于27岁,毕生短暂,无妻无妾,无子无孙,是有数人的白月光男神。 无人知晓,他再睁开眼,来到了1500年后。 这一次,他看见了他遐想过的盛世大夏。 · 不久后胤皇身份曝光,司扶倾得悉偶像居然就在身边,她钦佩万分,只想—— 司扶倾:努力奋斗,报效大夏! 胤皇:以身相许 司扶倾:??? 我二心奋发上进你却想要我? · 全能颜巅女神×杀伐清贵帝王 从全网黑到封神顶流,顺便和男神1v1</p>    </li>  ...</ul>

简略润饰一下

.list{  list-style: none;  margin: 0;  padding: 0;  width: 400px;}.item{  position: relative;  padding: 10px 10px 10px 34px;  cursor: pointer;  counter-increment: num;}.title::before{  content: counter(num) ' ';  width: 25px;  line-height: 30px;  text-align: center;  color: #fff;  position: absolute;  font-size: 14px;  font-family: fantasy;  left: 4px;  background: center/100% 100% url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAA8CAMAAAAe9Wm0AAAAbFBMVEUAAACaov2SnPKXnvaXofiyuvuCjPOgqvi4vfiBjPSyuf6Ml/a0u/21vPtte/F/i/WTnfWNmPiyuv6Ik/Zue/GRnPinr/Wfp/Gyuv6Ml/ebo/KTnfOutfqEj/W3vvpue/G/xfd1gvN8iPRodfBFzp+BAAAAF3RSTlMAECA7U2BgdIiTn6Wsvr+/v9Df39/s/o6+GugAAAGPSURBVHjazdZhk4IgEAZgpS6z8iotPEBF8P//x1tJrTxQlrm5uff7MxubLBtF9sQfp+ywjRCJk+zLhPq6SUwuxokhp4/YT1SUVtWam4nSZObImyA2YXHZ022cYsirOzwYoYti7nJzuMOqeHPNvke5jxgP2DRNNqLSMzQQtXjUtv8cBTWiwqOqohcsKikt8ajkHI+4EGjEBWNnNGJ1jUe1Vp9YJLSSeKRkh0eyC0BdEJIBZ5J/h1TA/6SUOgcgjUdaT6gJQA0CjV85jFrq/ZU/UYtA7HFzG5iA1PcOMnbs0b7tU/mcCAhjO/NE52A8jmXKMHYdnukTzE141vhyGWaSTq97ksMQhOnEF8qYFJvXneDO++lU82VznG0giYDppBVzTTvIffdjZSGFVjA2JHeVuRDbopOC6TrJ7GUSx0a1vYGR8u1kQ5krce5hJAUjlRbuRtuyu8GFVopxZ6OtxW5wObU2P3Ewaby+jya6R7UYO+C3xpICbk3NFhptTToaZ6OtzS/WGm39iUdkmdFFv5pvdNPREWjicTcAAAAASUVORK5CYII=);}.title{  margin: 0;  padding: 8px 0;  font-weight: normal;}.sumary{  margin: 0;  overflow: hidden;  display: -webkit-box;  -webkit-box-orient: vertical;  -webkit-line-clamp: 2;  color: #666;  font-size: 14px;  color: 20px;  height: 0;}.item::before{  content: '';  position: absolute;  inset: 0;  border-radius: 8px;  opacity: 0;  z-index: -1;  background: linear-gradient(270deg, rgb(241, 236, 249) 0%, rgba(241, 236, 249, 0) 100%);}

成果如下

当初加上hover的成果

.item:hover .title{  color: rebeccapurple;}.item:hover .sumary{  height: 40px;}.item.item:hover::before{  opacity: 1;}

成果如下

很失常的hover成果,没什么特地的,那如何在移出后依然保留最初的状态呢?接着往下看

二、保留hover的状态

实现hover保留状态须要用到这样一个小技巧。

比方,给一个元素增加hover款式

el:hover{  color: red}

如果咱们给这个元素加一个延时

el{  transition-delay: 1s;}

那么,在鼠标移入和移出时都会有提早

接着,咱们在 hover的时候勾销延时

el:hover{  color: red;  transition-delay: 0s;}

那么,在鼠标移入的时候会迅速响应,移出的时候依然会有提早

到这里置信大家都明确了吧,如果把延时设置为足够大,比方

el{  transition-delay: 9999s;}

这样鼠标在移出后,须要经验9999s后才会变为原状,也就相当于保留了hover状态

原理就是这样,接下来看看理论利用吧

三、鼠标移出列表后依然保留上一次的选中态

依据下面的原理,咱们能够轻松的实现在hover后保留状态,如下

/* 默认 transition */.item::before,.item .sumary,.item .title{  transition: 0s 9999s;}/* 每一项hover */.item:hover .title{  color: rebeccapurple;  transition: none;}.item:hover .sumary{  height: 40px;  transition: none;}.item.item:hover::before{  opacity: 1;  transition: none;}

须要留神的是,因为是transition,所以所有的状态变动都是须要反对过渡属性的,比方暗藏sumary这里用的是height: 0而不是display:none,还有选中的背景色变动,因为background-image不反对过渡,所以换成了::before,而后独自用opacity管制等等一些细节,成果如下

这样在鼠标来到后,之前状态依然是保留的。然而咱们只须要保留上一次的,而不是所有的,如何解决呢?

这里须要换一种思路,能够这么做,鼠标在移入整个列表的时候就革除所有的状态,这样就只有以后hover的选项才会保留下来,有点相似于JS中的思维,先把所有的.current都移除,再给以后项增加.current,实现如下

/* 革除所有hover */.list:hover .title{  transition: none;  color: #333;}.list:hover .sumary{  transition: none;  height: 0;}.list:hover .item::before{  transition: none;  opacity: 0;}

这样就实现了鼠标移出列表后依然保留上一次的选中态的性能,有点像单选框的成果,只不过是hover触发的,成果如下

四、默认列表的第一项为选中态

上面来实现最初一个性能。

这个相对而言比拟容易,须要用到:first-child伪类,能够匹配到第一个元素。

不过须要思考的是优先级的问题,这个是默认状态,权限应该是最低的,其余hover款式都应该能够笼罩它,所以能够放在最后面,如下

/* 初始状态(第一个选中) */.item:first-child .sumary{  height: 40px;}.item:first-child .title{  color: rebeccapurple;}.item:first-child::before{  opacity: 1;}/* 革除所有hover *//* 每一项hover */

这样就完满实现了文章结尾的成果

因为是 CSS 实现,多个列表也是齐全复用的

残缺代码能够查看线上 demo:CSS keep hover(runjs.work)

五、总结一下

以上就是通过纯 CSS 实现保留鼠标滑过款式的全副技巧了,次要还是对transition-delay的灵活运用,上面总结一下

  1. 实现原理的利用transition-delay,让“还原”的工夫足够长,这样就实现了保留hover状态的成果了
  2. 单选成果能够在鼠标移入整个列表的时候就革除所有的状态,这样就只有以后hover的选项才会保留下来,有点相似于JS中的思维
  3. 须要留神所有属性必须是反对transition的,比方display:none就不反对transition,须要用其余款式代替

当然,整个实现对于 CSS 以及选择器要求是相当高的,理论我的项目过程中可能并不如 JS 实现来的快,然而,CSS可能实现的又何必动用 JS呢?在我看来,JS就应该回归本职,分心解决数据逻辑交互,视觉方面全副交给CSS就行了,只是当初CSS还不够弱小,实现须要用到很多奇技淫巧,然而,CSS当初曾经在变得足够弱小,比方:has伪类,置信将来CSS会越来越美妙。

最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤

欢送关注我的公众号:前端侦探