响应式Web设计:HTML5和CSS3实战(二)

四、CSS3 新特性

本章只关注一些对响应式设计有用的 CSS 技术、单位和选择符。希望大家学习之后能够解决自己做响应式设计时可能遇到的问题。

CSS 响应式多列布局

/* 以上代码的意思就是内容要填充的列宽度为12em,无论视口多宽。改变视口宽度会动态改变列数 */
main {
  column-width: 12em;
}

/* 固定列数,可变宽度 */

main {
  column-count: 4;
}

/* 添加列间距和分隔线  */
main {
  column-gap: 2em;
  column-rule: thin dotted #999;
  column-width: 12em;
}

断字

极小的空间内存放很长的文字信息,结果超出边界不换行,可以使用word-wrap: break-word;

/* 把它应用给包含元素 */
word-wrap: break-word;

截短文本

只要内容超出既定宽度(如果是在一个弹性容器里,可以设置为 100%),就会被截短。最后的 white-space: nowrap 声明是为了确保长出来的文本不会折行显示在外部元素中。

<style>
  .truncate {
    width: 520px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: no-wrap;
  }
</style>

<p class="truncate">
  OK, listen up, I've figured out the key eternal happiness. All you need to do
  is eat lots of scones.
</p>

css 创建分支

  1. 特性查询
/* 这段样式只有浏览器支持 flashing-sausages 属性才会应用 */
@supports (flashing-sausages: lincolnshire) {
  body {
    sausage-sound: sizzling;
    sausage-color: slighty-burnt;
    background-color: brown;
  }
}

/* 前提是浏览器支持 @supports ,可如果不支持,这两块代码都不会被应用 */

@supports (display: flex) {
  .Item {
    display: inline-flex;
  }
}
@supports not (display: flex) {
  .Item {
    display: inline-block;
  }
}

/* 如果你涵盖不支持 @supports 的设备,最好首先写默认的声明,然后再写 @supports 声明 */

.Item {
  display: inline-block;
}
@supports (display: flex) {
  .Item {
    display: inline-flex;
  }
}
  1. 组合条件
@supports ((display: flex) and (pointer: coarse)) or
  (transform: translate3d(0, 0, 0)) {
  .Item {
    display: inline-flex;
  }
}

可惜的是,并非所有浏览器都支持 @supports ,那怎么办呢?没关系,有一个非常棒的 JavaScript 工具可以解决这个问题: Modernizr

新 CSS3 选择符

  • 属性选择符
img[alt] {
  border: 3px dashed #e15f5f;
}
[data-sausage] {
  /* 样式 */
}
  • 子字符串匹配属性选择符
/* 以..开头 */
img[alt^="film"] {
}

/* 包含…… */
[attribute*="value"] {
}

/*  以……结尾 */

[attribute$="value"] {
}

CSS3 结构化伪类

/* 用于匹配列表中第一项的选择符 */
div:first-child {
}

/* 选择最后一项的选择符 */
div:last-child {
}

/* 选择奇数个 */
.nav-Link:nth-child(odd) {
}
/* 选择偶数个 */
.nav-Link:nth-child(even) {
}

/*  nth 选择符从第三项开始,每两项选择一项 */
span:nth-child(2n + 3) {
  color: #f90;
  border-radius: 50%;
}

/* 给所有不包含 .not-me 类的元素添加橙色背景和圆角 */
.div:not(.not-me) {
  background-color: orange;
  border-radius: 50%;
}

CSS 自定义属性和变量

CSS 自定义属性可以存储信息,这些信息可以在样式表的其他地方使用,也可以通过 JavaScript 操作。举个简单的例子,可以把 font-family 属性的值保存为自定义属性,然后再在需要的地方引用它。以下就是创建自定义属性的语法

/* 使用 :root 伪类把自定义属性保存在文档根元素上 */

/* 
自定义属性以两个短划线开头,
接着是自定义属性的名字,
然后结尾与常规CSS属性一样,都是一个冒号 
*/
:root {
  --MainFont: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

/* 引用自定义属性的时候就可以用 var() */
.Title {
  font-family: var(--MainFont);
}

calc

/* 父元素宽度的一半减去10像
素 */
.thing {
  width: calc(50% - 10px);
}

CSS Level 4 选择符

  • :has 伪类
/* 给一个包含 figcaption 的 a 标签添加内边距 */
a:has(figcaption) {
  padding: 1rem;
}

/* 
    组合使用“取反”伪类 
    只有不包含 figcaption 的 a 标签才会添加这个内边距
*/
a:not(:has(figcaption)) {
  padding: 1rem;
}
  • 相对视口的长度
 vw:视口宽度
 vh:视口高度
 vmin:视口中的最小值,等于vw或vh中较小的值
 vmax:视口中的最大值,等于vm或vh中较大的值

Web 排版

可以相对于视口大小设置不同的文本大小

body {
  font-family: robotoregular;
  font-size: 2.1vw;
}

@media (min-width: 45rem) {
  html,
  body {
    max-width: 50.75rem;
    font-size: 1.8vw;
  }
}

@media (min-width: 55rem) {
  html,
  body {
    max-width: 78.75rem;
    font-size: 1.7vw;
  }
}

CSS3 的新颜色格式及透明度

  • RGB

    R、G、B 框,显示每个通道的分量值。把它们直接入对应到 CSS 的 RGB 值里就可以,语法是把它们放在一对括号中,按红、绿、蓝的顺序,前面加上 rgb 字样

  • HSL

    HSL(Hue Saturation Lightness,色相、饱和度、亮度)颜色系统。

.redness {
  color: hsl(359, 99%, 50%);
}
/* 如果想让它的颜色暗一些,可以只修改亮度的百分比: */
.darker-red {
  color: hsl(359, 99%, 40%);
}

五、CSS3 高级技术

text-shadow

/* 右侧偏移量 下方偏移两 模糊距离 色值 */
text-shadow: 4px 4px 0px hsla(140, 3%, 26%, 0.4);

/* 文字不需要模糊值,省略 blur 值 */
.text {
  text-shadow: -4px -4px #dad7d7;
}

盒阴影

  • 内阴影

box-shadow 属性可以用于建立一个 inset 阴影。使用的语法和普通盒阴影效果唯一的区别是,在前头添加了 inset 关键字

.inset {
  box-shadow: inset 0 0 40px #000;
}
  • 多重阴影

在代码里越接近顶层的效果在浏览器展示的时候也越接近“顶层”

box-shadow: inset 0 0 30px hsl(0, 0%, 0%), inset 0 0 70px hsla(0, 97%, 53%, 1);

背景渐变

线性渐变语法
  1. 确定线性渐变的方向,向下/向上/向左/向右/对角方向
/* 从红色渐变为蓝色的(默认从顶部开始)的渐变背景 */
.linear-gradient {
  background: linear-gradient(red, blue);
}

/* 从左到右 */
.linear-gradient {
  background: linear-gradient(to right, red, blue);
}

/* 对角 从底部左侧开始从红色渐变为蓝色 */
.linear-gradient {
  background: linear-gradient(to top right, red, blue);
}
  1. 色标:色标是用逗号进行分隔的。第一部分是颜色,第二部分是颜色的位置。一般建议不要混用单位
.linear-gradient {
  background: linear-gradient(
    #f90 0,
    #f90 2%,
    #555 2%,
    #eee 50%,
    #555 98%,
    #f90 98%,
    #f90 100%
  );
}
  1. 兼容旧式浏览器 : 要兼容不支持背景渐变效果的浏览器,只需要在之前定义一个背景颜色就可以了
.thing {
  background: red;
  background: linear-gradient(45deg, red, blue);
}

径向渐变

效果一般是从一个中心发散成为圆形或者椭圆形的渐变效果

.radial-gradient {
  margin: 1rem;
  width: 400px;
  height: 200px;
  background: radial-gradient(12rem circle at bottom, yellow, orange, red);
}

在定义了形状和大小后,我们定义渐变的位置。默认的位置是容器的中心。但是我们可以尝试一下其他做法。

  • at top right 表示径向渐变的中心在右上方
  • at right 100px top 20px 表示径向渐变的中心在距右边框 100 像素、上边框 20 像素处
  • at center left 表示径向渐变的中心在左边框中间处。

多张背景图片

  1. 可以使用背景大小( background-size )属性为每个图片设置大小
     auto :让图片保持其原生大小。
     cover :保持图片比例,拓展至覆盖整个元素。
     contain :保持图片比例,拓展图片让其最长边保持在元素内部

  2. 背景位置 background-position

建议不要使用缩写,并且先声明多重背景图片,然后声明背景大小,最后声明背景位置

css 滤镜

先要声明使用哪种滤镜,然后传入滤镜所需的参数

.filter-drop-shadow {
  filter: drop-shadow(8px 8px 6px #333);
}

可用的 css 滤镜效果

  1. filter:blur(3px) :使用一个简单的长度值(不是百分比)
  2. filter:brightness(2) :使用从 0 到 1 的值或者从 0%到 100%的值。0/0%意味着全黑,1/100%意味着正常没有变化,而任何更高的值意味着更高的亮度
  3. filter:contrast(2) :使用从 0 到 1 的值或者从 0%到 100%的值。0/0%意味着全黑,1/100%意味着 正常没有变化,而更高的值意味着更高的对比度。
  4. filter:drop-shadow(4px 4px 6px #333)
  5. filter:grayscale(.8) :使用从 0 到 1 或者从 0%到 100%的值来表示元素灰度化的程度。0 表示没有灰度化,而 1 表示完全灰度化。
  6. filter:hue-rotate(25deg) :使用从 0 度到 360 度表示颜色在色轮上的变化角度
  7. filter:invert(75%) :使用从 0 到 1 的值或者从 0%到 100%表示元素中反色的程度。
  8. filter:opacity(50%) :使用从 0 到 1 的值或者从 0%到 100%的值来改变元素的透明度
  9. filter:saturate(15%) :使用从 0 到 1 的值或者从 0%到 100%来表示图像的饱和度。高于 1/100%的值会增加额外的饱和度。
  10. filter:sepia(.74) :使用从 0 到 1 的值或者从 0%到 100%来为元素添加褐色滤镜。0/0%
    表示元素没有变化,而更高的值则表示褐色化程度的提升,1/100%表示最高的效果。

使用多个 CSS 滤镜:

.MultipleFilters {
  filter: opacity(10%) blur(2px) sepia(35%);
}

六、SVG

SVG 在 2001 年推出,直到高分辨率设备的出现才被广泛注意和采用。SVG 允许在代码中使用矢量点来描述二维图像。这种优势使 SVG 被广泛应用到图标、线条图和图表的表示中,因为矢量图是使用相对点来保存数据的,所以可以缩放到任意大小而不会损失清晰度。此外,由于 SVG 仅仅保存矢量点,相比于同等尺寸的 JPEG、GIF 和 PNG,其文件大小更小

视口主要描述在设备上能够观看内容的面积,一部手机的视口可能只有 320 像素宽 480 像素高,而桌面电脑则一般有 1920 像素宽 1080 像素高

组成

1.SVG 的根元素
<!--  width 、 height 和 viewbox 属性 -->
<svg width="198px" height="188px" viewBox="0 0 198 188"></svg>

视框(viewbox)则定义了 SVG 中所有形状都需要遵循的坐标系,可以把视框值 0 0 198 198 视为对矩形左上角和右下角的描述。前两个值被称为 min-x 和 min-y ,用于描述左上角的位置,而接下来的两个值被称作宽度和高度,可以描述右下角的位置。

<!--  viewbox 属性可以让你缩放图片,所以其中的形状为了填满SVG的宽度和高度,就会被放大。 -->
<svg width="198px" height="188px" viewBox="0 0 99 94"></svg>
2.命名空间

SVG 会有一个由生成它的图形编辑程序定义的命名空间( xmlns 是 XML 命名空间的缩写)
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"这些命名空间往往只是在生成 SVG 的程序中使用,所以在 Web 页面上展示 SVG 的时候它们并不是必需的。因此在优化流程中,为了减小 SVG 的大小,通常会把它们去掉

3.标题和描述标签

title 和 desc 标签提高了 SVG 文档的可读,这些标签可以用来在图像不可见的情况下描述图像的内容。然而,当 SVG 图片被应用为背景图片的时候,可以去除这些标签来减小文件大小。

4.defs 标签

是用于储存所有可以复用的元素定义的地方,如梯度、符号、路径等

5.元素 g

g 元素能把其他元素捆绑在一起。例如,你要画一辆车的 SVG,你会把用来构成车轮的形状用 g 标签集合起来。

<g
  id="Page-1"
  stroke="none"
  stroke-width="1"
  fill="none"
  fillrule="
evenodd"
  sketch:type="MSPage"
></g>
6.SVG 形状元素

SVG 拥有一系列可用的现成形状( path 、 rect 、 circle 、 ellipse 、 line 、 polyline 、polygon )。

7.SVG 路径

SVG 路径和其他 SVG 形状有所区别,因为它们是由任意数量的连接点组成的(允许你自由创造你想要的形状)

创建 SVG

在 Web 页面中插入 SVG

1.使用 img 标签
2.使用 object 标签

object 标签是 W3C 推荐的用于装载非 HTML 内容的容器
data 属性是你链接 SVG 资源的方式。 type 属性描述了内容的 MIME 类型
你也可以添加 width 和 height 属性,约束这个容器中的 SVG 的大小

<object data="img/svgfile.svg" type="image/svg+xml">
  <span class="fallback-info">Your browser doesn't support SVG</span>
</object>
3.作为背景图像插入

data URL:相对于 CSS 而言,这是用来引入外部资源的,如图像,如果使用这种方式对 SVG 进行编码,我建议不要采用 base64 编码,因为它对 SVG 内容的压缩并不如 text 好

4.内联 SVG
  1. 由于 SVG 仅仅是一个 XML 文档,所以你可以直接将它插入到 HTML 中
  2. 另外,如果你删除掉 svg 元素的 width 和 height 属性,SVG 就会自动缩放来填满容器。

七、CSS3 过渡、变形和动画

过渡 transition

当你知道动画的起始状态和终止状态,并且需要一个简单的变形方法时,使用 CSS 过渡。(顾名思义,允许我们在不同的状态之间切换)

<style>
  a {
    font-family: sans-serif;
    color: #fff;
    text-indent: 1rem;
    background-color: #ccc;
    display: inline-flex;
    flex: 1 1 20%;
    align-self: stretch;
    align-items: center;
    text-decoration: none;
    transition: box-shadow 1s;
  }
  /* 不想为第一个元素添加左边框的时候十分有用 */
  a + a {
    border-left: 1px solid #aaa;
  }
  a:hover {
    box-shadow: inset 0 -3px 0 #cc3232;
  }
</style>
<nav>
  <a href="#">link1</a>
  <a href="#">link2</a>
  <a href="#">link3</a>
  <a href="#">link4</a>
  <a href="#">link5</a>
</nav>

1.过渡的相关属性
transition-property 过渡的 css 的属性名
transition-duration 定义过渡效果持续的时长
transition-timing-function 定义过渡期间的速度变化
transition-delay 可选,用于定义过渡开始前的延迟时间

.style {
  /*...(其他样式)...*/
  transition-property: all;
  transition-duration: 1s;
  transition-timing-function: ease;
  transition-delay: 0s;
}

2.过渡的简写语法

transition: all 1s ease 0s;

3.在不同时间段内过渡不同属性

.style {
  /* 指定过渡 border 、 color 和 text-shadow */
  transition-property: border, color, text-shadow;

  /* 设定边框过渡效果应该2秒内完成、文字颜色3秒、文字阴影8秒 */
  transition-duration: 2s, 3s, 8s;
}

4.过渡调速函数

其实它们就是预置好的贝塞尔曲线,本质上是缓动函数。或者更简单地说,就是过渡在数学上的描述。可视化这些曲线通常更简单,所以我向你推荐http://cubic-bezier.com/http://easings.net/

变形 transform

当你需要在视觉上改变某个元素但又不想影响页面布局的时候,使用 CSS 变形

要记住,变形是在文档流外发生的。一个变形的元素不会影响它附近未变形的元素的位置。

2D 变形

 scale :用来缩放元素(放大和缩小)
 translate :在屏幕上移动元素(上下左右)
 rotate :按照一定角度旋转元素(单位为度)
 skew :沿 X 和 Y 轴对元素进行斜切
 matrix :允许你以像素精度来控制变形效果
 transform-origin 修改变形原点

3D 变形

动画 animation

当你想在一个元素上执行一系列关键帧动画时,使用 CSS 动画

八、实现响应式 Web 设计

  1. 首先为最小的视口编写 CSS,然后在媒体查询中修改其在较大视口下的表现
.rule {
  /* 小型视口样式 */
}
@media (min-width: 40em) {
  .rule {
    /* 中型视口样式 */
  }
}
@media (min-width: 70em) {
  .rule {
    /* 大型视口样式 */
  }
}
  1. 在真实设备上观察和使用
  2. 渐进增强。从选择支持的浏览器中选取它们共有的子集方法来开始编写你的前端代码(HTML、CSS、JavaScript)。然后,逐步优化你的代码以适应那些比较强大的浏览器和设备
  3. 分层的用户体验。将用户体验区分为“基本”体验和“增强”体验。基本体验是站点的最小可行版本,而增强体验则是包括所有功能并且最为美观的版本。当然,在你的层次里,可能要包括更多粒度。例如,不同浏览器应该根据相应的特征提供不同的体验
  4. 避免在生产中使用 CSS 框架

    首先,从技术上看,添加一个框架会为你的项目带来过多的冗余代码。其次,从美学的角度上看,因为这种框架十分普及,所以你的项目会和无数个其他项目看起来一模一样。最后,如果你只是在你的项目里复制粘贴代码,然后调整至符合你的需求,那么你就不可能充分理解它们的原理。只有通过定位和解决你遇到的问题,你才能掌握你项目中的代码

  5. 尽可能使用最简单的代码,不仅更易懂,而且支持度也更高(添加HTML类替代伪类选择器)
  6. 根据视口隐藏、展示和加载内容
  7. 性能
    (1) 减少你的资源数(例如,不要加载15个JavaScript文件,而应该将它们拼成一个)。
    (2) 减小你的页面大小(如果你能压缩图片,那么请压缩)。
    (3) 延迟加载非必需资源(如果你可以将CSS和JavaScript的加载延迟到页面加载完成后,就
    可以大幅缩短初始化时间)。
    (4) 保证页面尽快可用(通常是上述所有步骤的副产物)。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容