高级布局和效果的八个 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 ,并更改.containerpadding-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-cellvertical-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 也可以使用。

使用floatdisplay: inline-block ,可以通过 CSS 创建并排的列。

请参阅 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Same-Height Columns 1。

请注意使用box-sizing: border-box来正确调整.cols的大小。 请参阅上面的一致的 HTML 元素大小。

第一列和最后一列的边界不会一直向下; 它们与较高的第二列的高度不匹配。 要解决此问题,只需将overflow: hidden添加到.row 。 然后将每个.colmargin-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 。 每个元素都有不同的topleftbottomright值。 这消除了由下面详述的旋转产生的任何间距。
  • .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 技巧,请在下面的评论部分告诉我们。