强大的现代CSS技术(汇总1)

随着浏览器跨越式的发展,微软也把EDGE替换了传统IE,高级CSS的应用迎来了属于他的时代。有云道:这是我学习过的CSS吗?以后在简历的CSS熟练程度改为“听过”。

本文将介绍如何用现代CSS技术用于克服CSS带来的旧问题,先行粗略介绍,后再另篇章展开。

1. 高级CSS选择器

如果你打算开发可用于其他页面或UI组件的可重用CSS文件,那么了解CSS选择器的工作原理至关重要。现在让我们来看看一些高级选择器

1.1. 通用选择器

通用选择器可用于网站的所有元素。例如,如果你想为页面中的所有元素设置特定的边距,那么需要这样写:

1
2
3
* {
margin: 1.5rem;
}

1.2. 属性选择器

如果想将特定样式应用于某些具有相似属性但类名不同的元素,则可以使用属性选择器

1
2
3
[class*="component_"] {
border: 2px solid blue;
}

属性选择器将对类名为 component_titlecomponent_label 的元素应用边框。

1.3. 子组合选择器

如果你想将导航栏中菜单的字体大小设置为粗体但导航内容是动态生成的,怎么办?它们没有任何特定的类。但你可以使用子组合选择器。

1
2
3
.navigation-menu > ul > li > a {
font-weight: bold;
}

1.4. 伪类选择器

不同颜色交替的表格怎么实现?猜猜如何只用几行CSS就做到这一点吗?答案是伪类

1
2
3
tbody tr:nth-child(odd) {
background-color: green;
}

代码将对表格中的奇数行应用绿色背景。

tr交替换色

除了oddeven,还可以使用n+13n+1等属性应用不同的属性到不同的行。下面列出常见的伪类选择器:

选择器
描述
ul li:first-child 选中ul父元素中的第一个li子元素
ul li:last-child 选中ul父元素中的最后一个子元素
ul li:nth-child(n) 选中ul父元素中的第n个子元素
ul li:nth-child(odd) 选中为奇数下标的li元素
ulli:nth-child(even) 选中为偶数下标的li元素
ul li:nth-child(2n) 选中为偶数下标的li元素 (n为自然数,初值为0,依次+1递增,2n 表示是 2*0=0 2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 这样子递增下去)
ul li:nth-child(3n+1) 选中为1 4 7 10这样顺序的下标li元素 (n为自然数,初值为0,依次+1递增,3n+1 表示是 3*0+1=1 3*1+1=4 3*2+1=7 这样子递增下去)
ul li:nth-child(-n+5) 选中前五个li元素 (n为自然数 初值为0 依次-1递增,-n+5表示是 5+0=5 5+[-1]=4 5+[-2]=3 这样子递增下去)
ul li:nth-child(n+5) 选中第五个起的li元素 (n为自然数 初值为0 依次+1递增,n+5表示是 5+0=5 5+1=6 5+2=7 这样子递增下去)
ul li:nth-last-child(n) 选中ul父元素中的倒数第n个子元素
ul li:first-of-type 选中ul父元素中类型为li的的第一个元素
ul li:last-of-type 选中ul父元素中类型为li的最后一个元素
ul li:nth-of-type(n) 选中ul父元素中类型为li的第n个元素
ul li:nth-last-of-type(n) 选中ul父元素中类型为li的倒数第n个元素

2. 更换旧的网格系统

bootstrap 网格解决了在不同分辨率的设备中均匀分布响应容器的问题。但随着时间的推移,只用于网格的库越发繁重,因此开发人员需要另一种解决方案。尽管bootstrap依然好用。现代CSS技术,例如网格,为我们提供了一种简化的解决方案。

1
2
3
4
5
6
7
8
9
10
$minColumnWidth: 10rem; // 这个只是在 sass 变量 
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax($minColWidth, 1fr));
grid-gap: 2rem;

& + .grid {
margin-top: $gridGap;
}
}

这些代码做了什么:

  • 首先定义了网格元素的最小宽度 $minColumnWidth
  • grid-template-columns 中使用了 repeat 函数,以便CSS将相同的参数应用于每一列。此外,使用auto-fit而不是数字的原因是,列将具有相同的宽度——无论使用多少列,都会拉伸并填充可用空间;
  • 代码中还使用了 minmax() 函数来设置每列的最大宽度,并将 1fr 作为最大值。这可以确保内容填满一列直至达到总可用空间;
  • 最后还添加了 gap 和可选规则,以在连续容器之间应用相同的值。

结果如下:

只有一个缺点,对于三个以上的列,在某些视图中,可能会出现孤立的列。

我们可以通过媒体查询来解决问题,但需要为多个媒体尺寸编写大量代码。

3. 保持元素高度的一致

曾几何时,我们通过 jQuery 计算以确保容器高度相等。那时,两个容器的内容不相等的时候,经常用各种手段,使得高度左右“一致”。但是现代CSS技术“网格系统(grid布局)”可以让这个过程变得更简单。

1
2
3
4
5
6
7
8
9
/* Parent container 父元素内容 */
.parent {
display: grid;
grid-auto-flow: column;
}
/* Child elements 子元素内容*/
.child {
height: 100%;
}

通过将 grid-auto-flow 切换为 rowcolumn ,我们可以拥有统一宽度或高度的容器

此外,还有 CSS flexboxflex布局)允许我们通过更简单的代码来使用相同的功能。

1
2
3
4
5
6
7
8
9
/* Parent elements */
.parent {
display: flex;

/* Child elements */
.child {
height: 100%;
}
}

那么,grid布局flex布局哪一个更好呢?答案是,两者各有优势。如果你想解决等高元素的问题,那么flexbox更优。但是,在flexbox中,元素的宽度可能并不相等。

当然,如果你需要,网格也可以处理等宽的元素。此外,如果想要每一行拥有最大列数,则可以使用网格处理数学。但是如果你使用flexbox,则需要为此定义计算。

4. 提升流畅滚动的用户体验

虽然现如今back to top链接用的少了,但曾经有一段时间确实很流行。方法是创建一个链接,允许用户在网站顶部向后滚动。那么如何使用现代CSS技术开发back-to-top链接呢?

4.1. 先创建内容

1
2
3
4
5
6
7
8
9
10
<header id="header">Title</header>
<main>
<article>
<!-- content goes here -->
</article>
<!-- Back to Top link -->
<div class="back-to-top-wrapper">
<a href="#header" class="back-to-top-link" aria-label="Go Back to Top">Top</a>
</div>
</main>

4.2. 添加smooth滚动到页面

1
2
3
html {
scroll-behavior: smooth;
}

4.3. back-to-top链接的样式

然后根据喜好设置back-to-top链接的样式,也可以添加漂亮的SVG图标替换手动样式。

4.4. 设置滚动条效果

下面选择滚动条的行为方式,定义滚动长度:

1
$scrollLength: 100vh; /* sass定义变量 */

在包装器中将滚动值设置为预定义的滚动长度:

1
2
3
4
.back-to-top-wrapper {
position: absolute;
top: $scrollLength;
}

给back-to-top链接添加必要的样式。记住要使用 position-sticky 以将其保持在特定位置。

1
2
3
4
5
6
7
8
9
.back-to-top-link {
// using 'fixed' as fallback when `sticky` not supported
position: fixed;
position: sticky;
// achieves desired positioning within the viewport
// relative to the top of the viewport once `sticky` takes over, or always if `fixed` fallback is used
top: calc(100vh - 5rem);
// ... other styles
}

这里处理 position-sticky 需要认识,还有 calc() 需要知道。

calc() 函数用于动态计算长度值

  • 需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
  • 任何长度值都可以使用calc()函数进行计算;
  • calc()函数支持 “+”, “-“, “*”, “/“ 运算;
  • calc()函数使用标准的数学运算优先级规则;

4.5. 完成

5. 通过添加替代项来提高网站的可访问性:focus

可访问性是网站的必备功能,且必须遵循WCAG指南。通常,在按钮或链接上移除 :focus 可以摆脱原生样式。然而,在这样做的同时,因为未能提供替代的焦点状态,结果就是使用键盘导航站点的人无法检测到当前的焦点元素。直接违背了可访问性的原则。

我们可能会觉得浏览器的默认 :focus 样式,使那些保存于页面的漂亮元素显得不那么好看。但是,它是为备用焦点样式添加代码的理想选择。例如,假设有一个按钮:

1
2
3
<div style="margin:30px auto; text-align:center;">
<button style="color:green;border:none;background:#fff;font-size:24px;" value="Button">Button</button>
</div>

若可以添加:

1
2
3
4
button:focus {
outline: max(1px, 0.1em) solid currentColor;
outline-offset: 0.25em;
}

currentColor 视为页面的主题颜色。在本例中为绿色。使用 outline-offset ,可以调整轮廓与元素的间距

6. CSS字体规则和创建流畅的排版比例

排版是增强网页外观和视觉效果的最佳方式。

6.1. 首选的字体单位

不知道应该使用 %remem还是px ?在定义排版时你需要做的第一件事是:忘记px。因为当用户在浏览器中放大或缩小时,·px· 不会按比例缩放。推荐单位是rem

  • rem的默认值为 16px,当用户在浏览器中放大时,用rem定义的字体大小保持一致;
  • em 与元素的字体大小规则成比例。因此只能在你希望子元素相对于父元素的间距行为时使用;
  • % 的行为与 em 几乎相似。但是,当你需要相对大小时,em 更可取。

6.2. 防止文本溢出

防止文本溢出是使网站面向未来的好方法。它确保了如果将来容器中的某些文本增加,文本也不会超出容器或其边界。

1
2
3
4
5
6
7
8
9
p,
li,
h1,
h2,
h3,
h4 {
// Help prevent overflow of long words/names/URLs
word-break: break-word;
}

6.3. 响应式排版

如果你在全局范围内选择了较大的字体大小,那么可能会在小型设备上遇到溢出问题。我们可以通过流体类型解决这个问题。即定义一个根据视口调整的字体大小值,就像响应式图像一样。可以使用代码来计算最小和基本字体大小。

1
font-size: unquote("min(max(#{$fluid-min}rem, #{$fluid-scaler}), #{$level-size})");

或者可以使用 vw(视口宽度)作为字体单位。

7. 设置单选按钮的样式

开发人员需要自定义样式的单选按钮,因为默认的HTML单选按钮在不同浏览器中的显示方式不同。以下是在Mac上运行的Firefox和Safari中中单选按钮的外观对比。

不仅如此,原生单选按钮不能随字体大小缩放。解决方案是创建统一的单选按钮,该按钮在所有浏览器上的显示都相同,并且与标签的字体大小一致。

先从HTML开始:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<label class="radio radio-gradient">
<span class="radio-input">
<input type="radio" name="radio">
<span class="radio-control"></span>
</span>
<span class="radio-label">Option 1</span>
</label>
<label class="radio radio-before">
<span class="radio-input">
<input type="radio" name="radio">
<span class="radio-control"></span>
</span>
<span class="radio-label">Option 2</span>
</label>

接着是CSS,我们使用SCSS来为单选按钮设置主题。创建自定义颜色变量:

1
2
3
:root {
--color: green;
}

接下来使用通用选择器来重置 box-sizing 方法。它将在计算任意元素的最终大小时包括边框和填充。

1
2
3
4
5
*,
*:before,
*:after {
box-sizing: border-box;
}

我们在标签中添加了 .radio 类。使用 grid-gap 将在按钮和标签之间添加一些间距。我们还将使用 :focus-withintransform 以便当该特定选项处于焦点时,标签的尺寸会扩大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.radio {
display: grid;
grid-template-columns: min-content auto;
grid-gap: 0.5em;
font-size: 2.25rem;
color: var(--color);

&:focus-within {
.radio-label {
transform: scale(1.05);
opacity: 1;
}
}
}

调整行高,添加过渡,并在选项未处于焦点时,降低标签的不透明度。

1
2
3
4
5
.radio-label {
line-height: 1;
transition: 180ms all ease-in-out;
opacity: 0.8;
}

对包装自定义控件和本机输入的按钮添加 display-flex 。对焦点状态使用双框阴影,并确保基本按钮和焦点状态之间存在差异。

1
2
3
4
5
6
7
8
9
10
11
12
13
.radio-input {
display: flex;

input {
opacity: 0;
width: 0;
height: 0;

&:focus + .radio-control {
box-shadow: 0 0 0 0.05em #fff, 0 0 0.15em 0.1em currentColor;
}
}
}

添加按钮处于选中阶段时的样式。

1
2
3
.radio-gradient input:checked + .radio-control {
background: radial-gradient(currentcolor 50%, rgba(255, 0, 0, 0) 51%);
}

创建 :before 元素,以设置按钮未选中时的动画。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.radio-before {
.radio-control {
display: grid;
place-items: center;
}

input + .radio-control::before {
content: "";
width: 0.5em;
height: 0.5em;
box-shadow: inset 0.5em 0.5em currentColor;
border-radius: 50%;
transition: 180ms transform ease-in-out;
transform: scale(0);
}
input:checked + .radio-control::before {
transform: scale(1);
}
}

最后,添加样式到单选按钮和正文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.radio-control {
display: block;
width: 1em;
height: 1em;
border-radius: 50%;
border: 0.1em solid currentColor;
transform: translateY(-0.05em);
}
body {
min-height: 100vh;
display: grid;
place-content: center;
grid-gap: 2rem;
padding: 1rem;
}

最终结果如下,且各浏览器是统一效果:

8. 保持页脚的底部位置

虽然单页应用程序不会有太多这方面的问题,但如果你正在创建静态网页,那么你可能会发现页脚经常浮动。我们可以通过两种方法摆脱这个问题。

8.1. 方法一:grid

代码如下:

1
2
3
4
5
body {
min-height: 100vh;
display: grid;
grid-template-rows: auto 1fr auto;
}

代码先保持 body 的最小高度。然后使用 grid-template-rows 正确分隔内容。该方法使用小数单元来计算可用空间并将其分配到多行。因此,它将填充页眉和页脚之间的所有可用空间。

8.2. 方法二:flexbox

使用flexbox,方法更简单。

1
2
3
4
5
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}

首先,通过 min-height 确保 body 伸展到屏幕的全高。然后,设置 flex-direction 保留堆叠的块元素并保持文档行为正常。

9. 动画图片

以前用户需要很艰难地使用 jQueryposition:absolute 为图像标题和图像大小设置动画。但是,现如今,只需几行代码就可以为标题设置动画并在鼠标悬停图片时触发动画。请看:

1
2
3
4
5
6
7
8
9
10
11
.image-caption {
// existing styles
transition: transform 500ms ease-in;
will-change: transform;
}
// The transition property helps to animate the caption. We can trigger the animation on hover using -
.image:hover {
.image-caption {
transform: translateY(0);
}
}

解决了鼠标悬停的问题。那么,如果有人使用键盘浏览网页怎么办。在这种情况下,我们可以使用 focus 取代 hover

1
2
3
4
5
6
7
8
9
.image:focus {
outline: none;
}
.image:hover,
.image:focus{
.image-caption {
transform: translateY(0);
}
}

10. 边界半径和盒状阴影的高级使用

感谢CSS3的 border-radius 属性,现在的开发人员可以很从容地创建圆角框。例如:

1
border-radius: 20% 50%;

或,截图就略了。

1
border-radius: 3vw 4vw 8vw 2vw;

我们可以使用相对于元素大小的百分比值。如果要保持一致性,像 vw(视口单位)这样的相对单位会很有帮助。这样一来,我们就有了在移动设备上会变小,在桌面上会变大,但保持一致的圆形。

还有一个有趣的属性可以帮助我们为页面元素添加良好和舒缓的用户体验,那就是 box-shadow。通常盒状阴影用于添加卡片或按钮等元素的立体化。例如:

1
box-shadow:3px 4px 5px 0px rgba(0, 0, 0, 0.38);

这里水平偏移了3px,垂直偏移了4px,还有5px的模糊半径、无扩散半径和灰色阴影。你可以根据自己的选择调整值以增强框的外观。

box-shadow 的一个独特功能是,可以添加多个图层。例如:

1
box-shadow: 2px 4px 0 4px yellowgreen, 4px 8px 0 8px yellow, 8px 10px 0 12px red;

使用box-shadow为图像添加晕影效果,即使用嵌入阴影。

1
2
3
4
5
.image-container {
width: 30vmin;
height: 30vmin;
box-shadow: inset 0 0 4vmin 3vmin rgba(0, 0, 0, 0.5);
}

11. 保持元素居中

早些时候,如果我们需要将元素保持在页面的中心,必须使用绝对定位并定义 leftrighttopbottom值。好吧,这样痛苦的日子已经一去不复返了。现代CSS技术为我们提供了一种简单的解决方案,可以帮助在多种分辨率下保持居中位置。

使元素水平和垂直居中,只需向元素添加两个属性,grid布局

1
2
display: grid;
place-content: center;
我在中间,父元素添加: display: grid;align-items: center;justify-content: center;

如果你想使用 flexbox 以便与页面上其他 flexbox 元素保持一致性,则需要三行代码,flex布局

1
2
3
display: flex;
align-items: center;
justify-content: center;

如果想将元素放置在任何特定轴的中心对齐,该怎么办?在这种情况下,必须删除display属性。对于垂直居中对齐:

1
align-content:center;

结果如下:

我在中间,但没有垂直居中?

而如果想要保持元素水平居中,而不是对齐内容,须使用 justify-content

1
justify-content:center;
我在中间,父元素添加:display: flex;align-items: center;justify-content:center

上面提到的解决方案是针对 gird布局 的。对于 flex布局,代码有所不同。垂直对齐的代码是这样的:

1
2
3
4
justify-content: center;
flex-direction: column;
/* For horizontal alignment, you will need */
justify-content: center;

12. 使用CSS绘制形状

现代CSS技术帮助我们摆脱了使用脚本来绘制对象的麻烦。现在有很多方法可用于创建基本的CSS形状。下面让我们看看如何创建CSS三角形。

12.1. 使用border属性

border属性可以帮助创建三角形。先从容器开始:

1
2
3
4
.triangle {
border-style: solid;
border-color: transparent;
}

使用 border-width 属性并为边框的左侧赋予颜色。

1
2
3
4
5
6
7
.triangle {
border-style: solid;
border-color: transparent;
/* top | right | bottom | left */
border-width: 7px 0 7px 10px;
border-left-color: blue;
}

结果如下所示:

我们可以打乱 border-widthtoprightbottomleft 值来改变三角形的方向。

12.2. 使用线性渐变

线性渐变可以与 background-image 属性一起使用。首先创建容器,给出尺寸并阻止 background-repeat

1
2
3
4
5
.triangle {
width: 8em;
height: 10em;
background-repeat: no-repeat;
}

接着添加渐变。使容器的一半呈蓝色。添加两个渐变后,形状像容器中的镜像三角形。

1
background-image: linear-gradient(32deg, blue 50%, rgba(255, 255, 255, 0) 50%), linear-gradient(148deg, blue 50%, rgba(255, 255, 255, 0) 50%);

现在,让我们试着让其看起来像一个三角形。更改背景大小:三角形将有100%的宽度和50%的高度。

1
background-size: 100% 50%;

最后,为了防止重叠,必须添加背景位置,因为两个渐变的默认位置都是0 0。

1
background-position: top left, bottom left;

现在的形状看起来像三角形了。但是,这种方法有一个缺点。图形不会响应。如果纵横比发生变化,则可能需要重新计算度数。

13. 总结

CSS正在快速发展。开发人员正致力于创建纯CSS库,以减少对脚本的依赖并缩减网站的大小,使其对SEO更加友好。

内容摘录自:https://mp.weixin.qq.com/s/Ng1ZWBcAtMCzIPU4ydOagg

--------------本文结束 感谢您的阅读--------------