一个非常实用的CSS小技巧,帮你应对各种场景

举报
零一01 发表于 2021/07/15 22:41:23 2021/07/15
【摘要】 问题背景 在设计页面时,我们经常会遇到类似这样的页面布局: 图中一个容器内有多个内容块,每块都有一个底部的下划线,但是一般为了美观,最后一个内容块儿的下划线是要去掉的 接下来我们看看通常情况下,是如何处理这种样式的: <!DOCTYPE html> <html lang="en"> <head> <meta char...

问题背景

在设计页面时,我们经常会遇到类似这样的页面布局:

图片

图中一个容器内有多个内容块,每块都有一个底部的下划线,但是一般为了美观,最后一个内容块儿的下划线是要去掉的

接下来我们看看通常情况下,是如何处理这种样式的:

<!DOCTYPE html>
<html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 此处为基本的展示样式,可以忽略不看 */ .container{ border: 1px solid black; border-radius: 10px; width: 300px; height: 500px; margin: 100px auto; } .child{ margin: 0 auto; width: 200px; height: 98px; border-bottom: 1px solid rgb(172, 163, 163); line-height: 98px; } /* 此处为重点要看的样式 */ .last{ border-bottom: 0; } </style>
</head>
<body> <div class="container"></div> <script> const elementList = ['我是内容1','我是内容2','我是内容3','我是内容4','我是内容5'] const container = document.querySelector('.container') // 动态地向容器添加子元素 elementList.forEach((v, i, a) => { const el = document.createElement('div') /* 判断添加的子元素是否为最后一个 若是,则给一个 last 类名 */ el.className = i == a.length - 1 ? 'child last' : 'child' el.innerHTML = v container.appendChild(el) }) </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

上述代码中,假设我们不知道一共要往容器中添加多少个子元素,所以只能每次添加时都判断一下是否为最后一个,若是的话,就添加一个 last 类名用于清除 border-bottom

这样的确完成可以解决问题,但却存在一个**「缺陷」,那就是如果在添加完这些内容以后,又动态地要往这个容器内追加更多的内容时,上一次的最后一个内容块儿底部是没有下划线的,因为它被添加了一个 last 类名,此时就类似于「下拉加载更多」**这样一个场景,我们来非常简单地模拟一下:

<!DOCTYPE html>
<html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 此处为基本的展示样式,可以忽略不看 */ .container{ border: 1px solid black; border-radius: 10px; width: 300px; height: 500px; margin: 100px auto; overflow: scroll; } .child{ margin: 0 auto; width: 200px; height: 98px; border-bottom: 1px solid rgb(172, 163, 163); line-height: 98px; } /* 此处为重点要看的样式 */ .last{ border-bottom: 0; } </style>
</head>
<body> <div class="container"></div> <script> const container = document.querySelector('.container') const elementList = ['我是内容1','我是内容2','我是内容3','我是内容4','我是内容5'] function debounce(fn, delay=500) { let timer = null return function(...args) { if(timer) clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, args) clearTimeout(timer) }, delay) } } // 防抖处理 let addMore = debounce(function(container, list) { list.forEach((v, i, a) => { const el = document.createElement('div') el.className = i == a.length - 1 ? 'child last' : 'child' el.innerHTML = v container.appendChild(el) }) }) // 页面初次加载,向容器中动态添加内容 addMore(container, elementList) // 为容器添加滚动事件 container.addEventListener('scroll', function() { addMore(container, elementList) }) </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

我们来看看容器向下滚动后会出现什么情况:

图片

在上述动图中可以很清晰地看到,每次加载的一段内容后,上一段内容的最后一个内容块儿底部是没有下划线的,这就非常得不友好了

接下来就来介绍一个css小技巧来解决上述问题的尴尬

解决方案

这里可以用到css的**「兄弟选择器」**,即 element1 + element2,其表示的是选择 element1 之后的处于同一层级的所有 element2

我们来看一下具体的代码实现:

<!DOCTYPE html>
<html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 此处为基本的展示样式,可以忽略不看 */ .container{ border: 1px solid black; border-radius: 10px; width: 300px; height: 500px; margin: 100px auto; overflow: scroll; } .child{ margin: 0 auto; width: 200px; height: 98px; line-height: 98px; } /* 此处为重点要看的样式 */ .child + .child { border-top: 1px solid rgb(172, 163, 163); } </style>
</head>
<body> <div class="container"></div> <script> const container = document.querySelector('.container') const elementList = ['我是内容1','我是内容2','我是内容3','我是内容4','我是内容5'] function debounce(fn, delay=500) { let timer = null return function(...args) { if(timer) clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, args) clearTimeout(timer) }, delay) } } // 防抖处理 let addMore = debounce(function(container, list) { list.forEach((v, i, a) => { const el = document.createElement('div') el.className = 'child' el.innerHTML = v container.appendChild(el) }) }) // 页面初次加载,向容器中动态添加内容 addMore(container, elementList) // 为容器添加滚动事件 container.addEventListener('scroll', function() { addMore(container, elementList) }) </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

上述代码中的 .child + .child 表示选择类名为 child 之后的所有同一层级的类名为 child 的元素,因此第一个类名为 child 的元素是无法被选择到的,因此为了达到效果,我们选择为选择到的每个元素设置 border-top,这样就达到了想要的效果,并且即使之后动态地添加了更多的元素,也不会有什么问题

效果验证:

图片

总结

简单总结一下本文介绍的css小技巧有什么**「优点」**:

  1. 使得项目代码更加简洁
  2. 不会像传统的处理方法那样有多余的类名
  3. 能适应动态改变的元素

希望这个小技巧对你们有所帮助,如果还有别的更巧妙的方法,可以评论告诉我哈~

强烈推荐

给你们推荐一下我的个人博客,拥有大量优质文章、面试宝典、算法精选,欢迎访问~

文章来源: lpyexplore.blog.csdn.net,作者:「零一」,版权归原作者所有,如需转载,请联系作者。

原文链接:lpyexplore.blog.csdn.net/article/details/116766867

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。