高级布局和效果的八个 CSS 技巧
已发表: 2022-03-11在过去的几年里,Web 前端开发领域取得了长足的进步。 然而,正如用户所见,Web 前端仍然是相同的:使用 CSS 样式的 HTML 标记。
许多布局问题起初看起来很简单,但往往被证明是棘手的。 如果没有对某些 CSS 功能如何工作的广泛了解,这些高级布局似乎无法单独使用 CSS 实现。
在本文中,您将找到八个专家级的 CSS 技巧和窍门,它们利用鲜为人知的 CSS 特性来实现其中一些高级布局和效果。
1. 最大化 CSS 兄弟选择器
问题:不使用同级选择器会失去优化机会。
解决方案:只要有意义就使用兄弟选择器。 每当您使用项目列表,并且需要以不同的方式处理第一个或最后一个项目时,您的第一反应可能是使用:first-child
和:last-child
伪 CSS 选择器。
例如,当创建一个纯 CSS 的汉堡菜单图标时:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 1。
这是有道理的:除了最后一个之外,每个条都有一个边距底部。
然而,同样的效果也可以通过相邻的兄弟选择器 (+):
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 2。
这也是有道理的:第一个柱之后的所有内容都有一个边距顶部。 这个 CSS 技巧不仅节省了一些额外的字节(对于任何中型项目来说都可以轻松添加),而且还开辟了一个充满可能性的世界。
考虑这张卡片列表:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 3。
每个都有一个标题和文本,后者默认隐藏。 如果您只想使活动卡片的文本(使用.active
类)及其后面的内容可见,您可以仅使用 CSS 快速完成:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 4。
使用一点 JavaScript,这也可以是交互式的。
然而,仅仅依靠 JavaScript 会产生这样的脚本:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 5。
其中包含 jQuery 作为依赖项可以让您拥有一些简短的代码。
2. 一致的 HTML 元素大小
问题: HTML 元素在不同浏览器中的大小不一致。
解决方案:将所有元素的box-sizing
设置为border-box
。 长期以来,Internet Explorer 一直是 Web 开发人员的祸根,它做对了一件事情:它正确地调整了盒子的大小。
其他浏览器在计算 HTML 元素的宽度时只查看内容,其他所有内容都视为多余的。 一个width: 200px
像素的 div,具有 20 20px
的内边距和 2 2px
的边框,呈现为 242 像素宽。
Internet Explorer 将填充和边框视为宽度的一部分。 在这里,上面的 div 将是 200 像素宽。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen CSS Box Model Demo 1。
一旦你掌握了窍门,你会发现后一种方法更合乎逻辑,即使它不遵循标准。
如果我说宽度是 200 像素,天哪,即使我有 20 像素的填充,它也会是一个 200 像素宽的盒子。
在任何情况下,以下 CSS 使元素大小(以及布局)在所有浏览器中保持一致:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen CSS Box Model Demo 2。
第二组 CSS 选择器保护没有边框的 HTML 元素不受布局干扰。
box-sizing: border-box
非常有用,它是一个相对流行的 CSS 框架 sanitize.css 的一部分。
3.动态高度元素
问题:保持 HTML 元素的高度与其宽度成正比。
解决方案:使用垂直填充代替高度。
假设您希望 HTML 元素的高度始终匹配其 CSS 宽度。 height: 100%
不会更改与其内容高度匹配的元素的默认行为。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Dynamic Height Elements 1。
答案是将高度设置为 0 并使用 padding-top 或 padding-bottom 来设置.container
的实际高度。 任一属性都可以是元素宽度的百分比:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Dynamic Height Elements 2。
现在.container
将保持为正方形,无论它变得多宽。 overflow: hidden
防止长内容打破这个比例。
这种技术,经过一些修改,非常适合创建在任何大小下保持其纵横比的视频嵌入。 只需将嵌入与.container
的顶部和左侧对齐position: absolute
,将嵌入的两个尺寸设置为 100% 以便它“填满” .container
,并更改.container
的padding-bottom
以匹配视频的方面比率。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Dynamic Height Elements 3。
position: relative
for .container
确保iframe
绝对定位正常工作。 新的padding-bottom
只是纵横比的高度除以其宽度,乘以 100。例如,如果视频嵌入的纵横比为 16:9,则 padding-bottom 百分比应为 9 除以 16 (.5625)并乘以 100 (56.25)。
4.动态宽度元素
问题:保持 HTML 元素的宽度与其高度成比例。
解决方案:使用 font-size 作为元素尺寸的基础。
现在,反过来,或者容器的宽度随着高度的变化而变化呢? 这一次,它是font-size
的救援。 请记住,宽度和高度可以以em
为单位,这意味着它们可以是元素font-size
的比率。
一个font-size
为 40px、宽度为2em
、高度为1em
的元素将是 80 像素 (40 x 2) 宽和 40 像素 (40 x 1) 高。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Dynamic Width Elements。
想改变.container
的高度吗? 更改字体大小。
唯一需要注意的是,仅通过 CSS 无法使元素的字体大小自动匹配其父元素的高度。 然而,这种技术允许将 Javascript 调整大小脚本从以下位置缩减:
var container = document.querySelector( '.container' ); container.style.height = yourDesiredHeight + 'px'; container.style.width = yourDesiredHeight * yourDesiredRatio + 'px';
到:
document.querySelector( '.container' ).style.fontSize = yourDesiredHeight + 'px';
5.动态内容的垂直居中
问题:保持一个 HTML 元素(高度未知)在另一个元素中垂直居中。

解决方案:将外部元素设置为display: table
,然后将内部元素转换为 CSS table-cell
。 或者只是使用 CSS Flexbox。
可以使用line-height
将一行文本垂直居中:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的动态内容 1 的笔垂直居中。
对于多行文本或非文本内容,CSS 表格就是答案。 将.container
的显示设置为table
,然后使用display: table-cell
和vertical-align: middle
为.text
:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的动态内容 2 的笔垂直居中。
把这个 CSS 技巧想象成margin: 0 auto
的垂直等价物。 如果 Internet Explorer 的错误支持是可以接受的,那么 CSS3 的 Flexbox 是该技术的一个很好的替代方案:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的动态内容 3 的笔垂直居中。
6. 相同高度的柱子
问题:保持列的高度相同。
解决方案:对于每一列,使用较大的负margin-bottom
值,并使用同样大padding-bottom
将其取消。 CSS 表格和 Flexbox 也可以使用。
使用float
或display: inline-block
,可以通过 CSS 创建并排的列。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Same-Height Columns 1。
请注意使用box-sizing: border-box
来正确调整.cols
的大小。 请参阅上面的一致的 HTML 元素大小。
第一列和最后一列的边界不会一直向下; 它们与较高的第二列的高度不匹配。 要解决此问题,只需将overflow: hidden
添加到.row
。 然后将每个.col
的margin-bottom
设置为 99999px 并将其padding-bottom
设置为 100009px (99999px + 应用于.col
另一侧的 10px 填充)。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Same-Height Columns 2。
一个更直接的替代方案是 Flexbox。 同样,仅在不需要 Internet Explorer 支持时才使用它。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Same-Height Columns 3。
另一种具有更好浏览器支持的替代方案:CSS 表格(没有vertical-align: middle
)。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Same-Height Columns 4。
7. 超越框框
问题:方框和直线太陈词滥调了。
解决方案:使用transform: rotate(x)
或border-radius
。
从营销或宣传册网站中获取典型的一系列窗格:具有奇异点的垂直堆叠幻灯片。 它的标记和 CSS 可能看起来像这样:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Going Beyond the Box 1。
以使标记更加复杂为代价,这些四四方方的窗格可以变成一堆平行四边形。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Going Beyond the Box 2。
这里发生了很多事情:
每个窗格的高度由 .pane-container 控制。 负边距底部确保窗格紧密堆叠。
-
.pane-background
、它的子.mask-box
和它的孙子.image
都设置为position: absolute
。 每个元素都有不同的top
、left
、bottom
和right
值。 这消除了由下面详述的旋转产生的任何间距。 -
.mask-box
旋转 2 度(逆时针)。 -
.image
旋转 -2 度以抵消.mask-box
的旋转。 -
.mask-box
的溢出是隐藏的,因此其旋转的顶部和底部会夹住.image
元素。
在相关说明中,将图像变成圆形或椭圆形非常简单。 只需将border-radius: 100%
应用于img
元素。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Going Beyond the Box 3。
诸如此类的实时 CSS 修改减少了在将内容发布到网站之前对其进行准备的需要。 无需在 Photoshop 中将圆形蒙版应用于照片,Web 开发人员只需通过 CSS 应用相同的效果,而无需更改原始照片。
另一个优势是,通过保持内容不变并且不依赖于网站的当前设计,可以促进未来的重新设计或改造。
8.夜间模式
问题:在不创建新样式表的情况下实现夜间模式。
解决方案:使用 CSS 过滤器。
一些应用程序具有夜间模式,在这种模式下,界面会变暗,以便在弱光下更好地阅读。 在较新的浏览器上,CSS 过滤器可以通过应用类似 Photoshop 的效果来创建相同的效果。
一个有用的 CSS 过滤器是invert
,它(毫不奇怪)反转元素内所有内容的颜色。 这使得创建和应用一组新样式变得不必要。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Night Mode 1。
在黑色文本和白色背景上使用此过滤器可模拟夜间模式。 !important
确保这些新颜色覆盖任何现有样式。
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Night Mode 2。
不幸的是,图像看起来很奇怪,因为它的颜色与其他所有颜色都相反。 好消息是可以同时应用多个过滤器。 添加hue-rotate过滤器将图像和其他视觉内容恢复正常:
请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Night Mode 3。
为什么这行得通? hue-rotate(180deg)
只会产生与invert(1)
相同的效果。 这是通过 JavaScript 驱动的按钮切换时夜间模式 CSS 将如何工作的演示。
充分利用 CSS
除非浏览器或网站的构建方式在未来发生巨大变化,否则良好的 CSS 知识将仍然是 Web 开发领域的一项基本技能。
所有这些 CSS 技巧都有一个共同点:它们最大限度地利用 CSS 作为样式语言,让浏览器本身完成繁重的工作。 而且,如果做得好,这总是会产生更好的结果、更好的性能,从而带来更好的用户体验。
如果您有任何有趣且有用的 CSS 技巧,请在下面的评论部分告诉我们。