32
头图
Welcome to my public account: front-end detective

Normally, hover cannot save state. Move the mouse in to trigger extra styles, which are restored once moved out

 el:hover{
  color: red
}

This means that if you need to keep the status of hover , you may have to resort to JS , for example, the following is the effect of the homepage ranking of a certain academy

Kapture 2022-09-26 at 18.37.28

The main interactions here are as follows

  1. Mouse over triggers the selected state
  2. After the mouse is moved out of the list, the last selected state is still retained (emphasis)
  3. The first item in the default list is selected

At present, the implementation of the official website is also achieved through JS , in fact, only through CSS can also be completely done, you need to use transition some small delay Skills, let's take a look

1. Mouse over to trigger the selected state

Everything is inseparable from the layout.

Suppose the list HTML is like this

 <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>

Just make up

 .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%);
}

The effect is as follows

image-20220917131014700

Now add the effect of hover

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

The effect is as follows

Kapture 2022-09-17 at 13.12.45

Very normal hover effect, nothing special, so how to keep the last state after removing it? Then look down

2. Retain the status of hover

Implementing hover preserving state requires such a little trick.

For example, add hover style to an element

 el:hover{
  color: red
}

Kapture 2022-09-17 at 13.18.58

If we add a delay to this element

 el{
  transition-delay: 1s;
}

then, there will be a delay when the mouse is moved in and out

Kapture 2022-09-17 at 13.20.43

Next, we cancel the delay at hover

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

Then, when the mouse is moved in, it will respond quickly, and there will still be a delay when it is moved out.

Kapture 2022-09-17 at 13.24.09

At this point, I believe everyone understands it. If the delay is set to be large enough, for example

 el{
  transition-delay: 9999s;
}

In this way, after the mouse is removed, it needs to go through 9999s before it becomes the original state, which is equivalent to retaining the hover state

Kapture 2022-09-17 at 13.28.42

This is the principle, let's look at the practical application.

3. After the mouse is moved out of the list, the last selected state is still retained

According to the above principle, we can easily achieve the retention state after hover , as follows

 /* 默认 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;
}

It should be noted that since it is transition , all state changes need to support transition attributes , such as hiding sumary here is height: 0 instead of display:none ,还有选中的背景色变化, background-image不支持过渡, ::before ,然后单独用opacity Control and other details, the effect is as follows

Kapture 2022-09-26 at 20.02.53

In this way, after the mouse leaves, the previous state is still retained. But we only need to keep the last one, not all, how to deal with it?

There is a need to change the way of thinking here. You can do this. When the mouse moves into the entire list, all the states will be cleared, so that only the current hover option will be retained, which is somewhat similar to JS in the thinking, first remove all .current , and then add .current to the current item, the implementation is as follows

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

In this way, the function of retaining the last selected state after the mouse is moved out of the list is hover .

Kapture 2022-09-17 at 13.54.53

4. The first item in the default list is the selected state

Let's implement the last function.

This is relatively easy and requires the use of the :first-child pseudo-class, which can match the first element.

But what needs to be considered is the issue of priority, this is the default state, the permissions should be the lowest, other hover styles should be able to override it, so it can be placed at the top, as follows

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

/* 清除所有hover */

/* 每一项hover */

This perfectly achieves the effect of the beginning of the article

Kapture 2022-09-17 at 14.04.17

Due to the CSS implementation, multiple lists are also fully reusable

Kapture 2022-09-26 at 20.22.33.gif

The complete code can be viewed online demo: CSS keep hover(runjs.work)

Fifth, to summarize

The above is through pure CSS to achieve all the skills to retain the mouse over style, mainly for the flexible use of transition-delay , the following summarizes

  1. The use of the realization principle transition-delay , let the "restore" time be long enough, so as to achieve the effect of the retention hover state
  2. The single selection effect can clear all the states when the mouse is moved into the entire list, so that only the current hover option will remain, which is somewhat similar to the thinking in JS
  3. It should be noted that all attributes must be supported transition , such as display:none does not support transition , need to be replaced by other styles

Of course, the entire implementation is quite demanding for CSS and selectors, and the actual project process may not be as fast as JS , but CSS can Why use JS to achieve it? In my opinion, JS should return to his job, concentrate on data logic interaction, and leave all visual aspects to CSS , but now CSS is not powerful enough , the implementation needs to use a lot of tricks and tricks, but, CSS has become strong enough now, such as :has pseudo-class, I believe that in the future CSS will become more and more more and more beautiful.

Finally, if you think it's good and helpful to you, please like, bookmark, and forward ❤❤❤

Welcome to my public account: front-end detective

XboxYan
18.2k 声望14.1k 粉丝