最近遇到了一个比较棘手的需求,大概如下图所示:
需要实现的功能点:
- 长按句子背景高亮;
- “火”的标志要显示在需要高亮句子右上侧;
另外还有几点补充说明:
- 页面的布局和嵌套是按照:
div.para > span.sent > button.word - 段落之间有水平空间,句子是首位相连的,需要高亮的是句子
我们面对的问题有如下几个:
- 如何实现图中的高亮?
- 如果定位“火”在句子的右上侧?
那么问题来了,如果实现呢?可以通过纯 CSS 方式实现吗?
句子高亮
在不考虑“火”的情况下,我们已经确定的页面结构可以简化如下:
<div class="container">
<div class="para">
<span class="sent">
<span class="word">The</span>
<span class="word">bad</span>
<span class="word">news</span>
<span class="word">is</span>
<span class="word">time</span>
<span class="word">files</span>
<span class="sign">.</span>
<span class="word">The</span>
<span class="word">good</span>
<span class="word">news</span>
<span class="word">is</span>
<span class="word">you're</span>
<span class="word">the</span>
<span class="word">pilot</span>
<span class="sign">.</span>
</span>
<span class="sent">
<span class="word">As</span>
<span class="word">night</span>
<span class="word">falls,</span>
<span class="word">the</span>
<span class="word">Qianlingshan</span>
<span class="word">sports</span>
<span class="word">park</span>
<span class="word">begins</span>
<span class="word">to</span>
<span class="word">buzz</span>
<span class="sign">.</span>
</span>
<span class="sent hi">
<span class="word">The</span>
<span class="word">bad</span>
<span class="word">news</span>
<span class="word">is</span>
<span class="word">time</span>
<span class="word">files</span>
<span class="sign">.</span>
<span class="word">The</span>
<span class="word">good</span>
<span class="word">news</span>
<span class="word">is</span>
<span class="word">you're</span>
<span class="word">the</span>
<span class="word">pilot</span>
<span class="sign">.</span>
<span class="word">As</span>
<span class="word">night</span>
<span class="word">falls,</span>
<span class="word">the</span>
<span class="word">Qianlingshan</span>
<span class="word">sports</span>
<span class="word">park</span>
<span class="word">begins</span>
<span class="word">to</span>
<span class="word">buzz</span>
<span class="sign">.</span>
</span>
<span class="sent">
<span class="word">The</span>
<span class="word">bad</span>
<span class="word">news</span>
<span class="word">is</span>
<span class="word">time</span>
<span class="word">files</span>
<span class="sign">.</span>
<span class="word">The</span>
<span class="word">good</span>
<span class="word">news</span>
<span class="word">is</span>
<span class="word">you're</span>
<span class="word">the</span>
<span class="word">pilot</span>
<span class="sign">.</span>
</span>
</div>
</div>
.hi {
background-color: #fff3d1;
}
最终得到的效果如下图所示:
句子的右侧不整齐,这显然不是我们想要的结果。其实解决办法也挺简单,从现象上来看,是单词左对齐导致的,如果我们使用两端对齐不就可以解决问题了吗?这时候如果你设置 sent 的样式 text-align: justify 会发现没有变化。原因很简单,MDN 官网对 text-align 的描述如下:
The text-align CSS property sets the horizontal alignment of the content inside a block element or table-cell box. This means it works like vertical-align but in the horizontal direction.
那这个时候只有一个选择了,那就是在 para 上使用 justify 。 新增 CSS 如下:
.para {
text-align: justify;
}
💯 完美!
右侧的“火”
最容易想到的实现方式,就是让“火”相对于句子绝对定位,根据设计图定位到相应的右侧位置即可。真的可以吗?我们可以做一下尝试:
<div class="container">
<div class="para">
// 省略上文
<span class="sent hi">
<img class="fire" src="https://media-image1.baydn.com/storage_media_image/qtvmnf/cb7402fb943df88d0f4285c614b81e51.47aee7d51547db425fea728a4c9ec426.png" alt="fire">
<span class="word">The</span>
<span class="word">bad</span>
<span class="word">news</span>
<span class="word">is</span>
<span class="word">time</span>
<span class="word">files</span>
<span class="sign">.</span>
<span class="word">The</span>
<span class="word">good</span>
<span class="word">news</span>
<span class="word">is</span>
<span class="word">you're</span>
<span class="word">the</span>
<span class="word">pilot</span>
<span class="sign">.</span>
<span class="word">As</span>
<span class="word">night</span>
<span class="word">falls,</span>
<span class="word">the</span>
<span class="word">Qianlingshan</span>
<span class="word">sports</span>
<span class="word">park</span>
<span class="word">begins</span>
<span class="word">to</span>
<span class="word">buzz</span>
<span class="sign">.</span>
</span>
// 省略下文
</div>
</div>
.hi {
background-color: #fff3d1;
}
.container {
padding: 10px 20px;
}
.para {
text-align: justify;
}
.sent {
position: relative;
}
.fire {
position: absolute;
right: 0;
top: 0;
width: 30px;
height: 30px;
}
最终效果如下图:
从图中可以看到,“火”的位置非常奇怪,经过调试发现,“火”的位置是根据“句子”的起始和结束的位置来进行定位的。
虽然定位没有能解决问题,但是我们的思路还是很明确的,必须脱离文档流,照着这个思路,我们想到了本文的主角 float 。
当我们使用 float: right 页面如下所示:
那这下就好办了,我们只需要让火往右侧偏移即可,使用如下代码:
// 省略其他 CSS 代码
.fire {
float: right;
width: 30px;
height: 30px;
margin-right: -30px;
}
最终得到如下图所示效果:
💯 完美!
总结
- 思路很重要,脱离文档流是一个很重要的思考方向;
- 需要掌握
float的相关特性; - 利用
margin-right: -30px进行右侧偏移,并将空间留给单词。