【PWA】响应式开发

╰+哭是因爲堅強的太久メ 2022-06-03 08:46 424阅读 0赞

PWA 是专门应对手机开发而提出的概念,不过,由于手机端在国内四分五裂的局面看来(还包括 PC/Pad),屏幕尺寸的不同,网页设计的样式和大小当然也是完全不一样的。为了让 Web 能完美的在多端上运行,这里,我们就需要进行响应式开发。

响应式的目的就是让一个网站尽可能的适配所有大小的网页。当然,响应式开发所用到的技术也是非常之多,不过,主要的还是 CSS 。

meta 标签

meta 标签之所以重要,是因为它在手机端适配上起到的作用可以说是非凡的意义。meta 标签分很多种,比如:

  1. <meta name="keywords" content="your tags" />
  2. <meta name="description" content="150 words" /> <meta name="robots" content="index,follow" /> <meta name="author" content="author name" /> <!-- 定义网页作者 --> <meta name="google" content="index,follow" /> <meta name="googlebot" content="index,follow" /> <meta name="verify" content="index,follow" /> //...

meta 标签根据 name 的不同有着自己独特的任务,大部分是设计 SEO 的,我这里就不详谈了。meta 与响应式相关的 nameviewport。它是为了防止页面被浏览器/用户私自缩放而制定的。如何使用呢?很简单,在 head 标签中直接添加:

  1. <head>
  2. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> </head>

下图是设置了之后的效果:

iphonescale.jpg-88.2kB

不过,上述 viewport meta 标签对 PC 是无效的,所以,在 PC 上无需担心。我先简单讲解一下 viewport 里面的基本属性:

  • width: viewport 的大小
  • device-width: 当前设备屏幕的宽度
  • height: viewport 的高度
  • device-height: 当前设备屏幕的高度
  • initial-scale: 当前页面的缩放比例。1.0 是不缩放
  • maximum-scale: 当前页面的最大缩放比。
  • user-scalable: 能让用户能够进行缩放页面(大部分情况是双击)。为了取消一些浏览器的 click 延迟,需要设置为 no

media query

MQ(media query)是在 CSS2.1 提出来的概念,在 CSS3 中得到增强。它主要是针对屏幕的相关参数的变化,做出相关的文件选取或者显示区别。具体用法为:

  1. <link rel="stylesheet" type="text/css"
  2. media="screen and (max-device-width: 480px)"
  3. href="shetland.css" />
  4. <style> @media (max-width: 600px) { .facet_sidebar { display: none; } } </style>

只有满足 MQ 要求的样式/CSS 才能被应用,不过,不管用不用 MQ,所有的 CSS StyleSheet 都会被下载。所以,这就比较尴尬。我们来先来看一下语法。 这是所有的语法值:

  1. media_query_list: <media_query> [, <media_query> ]*
  2. media_query: [[only | not]? <media_type> [ and <expression> ]*]
  3. | <expression> [ and <expression> ]*
  4. expression: ( <media_feature> [: <value>]? )
  5. media_type: all | aural | braille | handheld | print |
  6. projection | screen | tty | tv | embossed | speech
  7. media_feature: width | min-width | max-width
  8. | height | min-height | max-height
  9. | aspect-ratio | min-aspect-ratio | max-aspect-ratio
  10. | color | min-color | max-color
  11. | color-index | min-color-index | max-color-index
  12. | monochrome | min-monochrome | max-monochrome
  13. | resolution | min-resolution | max-resolution
  14. | scan | grid

我们先来看一下基础属性。

基础属性

首先,我们这里不会对所有的基础属性进行讲解,只会选常用的。基础属性需要对属性进行赋值,例如:

  1. height:200px

width

定义设备的宽度。当然配套的就有:max-widthmin-width。还有啥 device-width/device-height 这两个属性,它们已经从标准从废除了,一般都用 width/height进行替代。 最经常用到的就是 min-widthmax-width 这两个属性。

  • min-width 表示 >= 该宽度值。min-width: 200em
  • max-width 表示 <= 该宽度值。max-width: 200em

举个实在的例子,假如有一个元素要在 500px~800px 之内显示,其它范围内隐藏,使用 media query 就应该写为。

  1. // 范围在 [500,800] 之内
  2. @media (max-width: 800px) and (min-width:500px) {
  3. .facet_sidebar {
  4. display: block;
  5. }
  6. }
  7. // 范围在 [500,800] 之外隐藏
  8. @media (max-width: 500px) , (min-width:800px) {
  9. .facet_sidebar {
  10. display: none;
  11. }
  12. }

height

定义设备的高度,不过这个不常用到。用法和 width 一样,只是它是用来定义高度的。

  1. // 范围在 [500,800] 之内
  2. @media (max-height: 800px) and (min-height:500px) {
  3. .facet_sidebar {
  4. display: block;
  5. }
  6. }

device-ratio

该属性表示设备屏幕的宽高比,这主要是对完美主义设置的,不同屏幕的比例不一样,带来的视觉也会发生变化。注意,在赋值的时候,应该写为:宽/高。中间用 / 连接。例如,针对 3:7 和 1:1 的屏幕应用不同的 CSS:

  1. // 3:7
  2. <link rel="stylesheet" type="text/css"
  3. media="device-ration: 3/7"
  4. href="3-to-7.css" />
  5. // 1:1
  6. <link rel="stylesheet" type="text/css"
  7. media="device-ration: 3:7"
  8. href="3-to-7.css" />

另外,还有两个配套的:max-device-ratiomin-deivce-ratio。用法和上面的一样,这里我就不多说了。

orientation

该属性是用来检测屏幕的翻转,即,横向和纵向。不过,它的取值有点怪。

  • landscape:横向模式。大家可以理解为一般风景的时候都是广角,能够将很大的美景收入眼中。
  • portrait:纵向模式(也就正常模式)。本意是肖像画的意思,大家想想 蒙娜丽莎的微笑的画就 OK。

用法也简单:

  1. @media (orientation: portrait) { ... }

resolution

该属性对于 retina 屏幕来说很有效,这支持两种单位,一个是 dpi(dots per inch)dppx(Dots Per Pixel)。这里,我们需要对这两个单位做一些解释,首先是 dpi。

dpi 表示每单位英寸面积内有多少像素点(注意,是物理像素点)。一般来说,Web 是大于 72dpi 的。不过,该单位不常用到 Web 中,通常是针对打印机和照相机相关参数的描述(特别是打印机,主要是该单位)。

dppx 每个设备像素(即,CSS 中的 px 单位)中包含几个物理像素,该单位和 dpr 完全,只是不同的叫法。dpr 是 device-pixel-ratio,像素分辨率。它的计算公式为:

  1. 设备像素比 = 物理像素 / 设备独立像素

一般,retina 的 dppx 是 2。不过,iphone6 一下是 2,iphone6p 是 2.64,而 iphone 6 Plus 以上是 3(尴尬)。一般情况下,我们只要对 2 和 3 做相关处理即可。当然,他还有 min-resulotionmax-resolution 两个配套处理。

  1. @media (min-resolution:2dppx){ ... }

逻辑处理

在 MQ 中,逻辑处理和程序中的一样,有:andnot,(表示或),only。例如:

  1. @media (max-width: 800px) and (min-width:500px) {
  2. .facet_sidebar {
  3. display: block;
  4. }
  5. }

在 MQ 中,还有几个常量值,表示设备的类型,常用的有:allhandheldprintscreen等等。

  • all:所有设备适用
  • handheld: 手提设备
  • print:打印设备
  • screen:屏幕设备

例如:

  1. @media screen and (max-width: 800px) and (min-width:500px) {
  2. .facet_sidebar {
  3. display: block;
  4. }
  5. }

不同资源文件

media 不仅可以用在 CSS 中,还可以直接运动到 link,用来筛选我们网站需要的资源,比如,根据 resolution 来进行区分:

  1. <link rel="stylesheet" media="screen and (resolution: 0.75dppx )" href="ldpi.css" />
  2. <link rel="stylesheet" media="screen and (resolution: 1.0dppx )" href="mdpi.css" /> <link rel="stylesheet" media="screen and (resolution: 1.5dppx )" href="hdpi.css" /> <link rel="stylesheet" media="screen and (resolution: 2.0dppx )" href="retina.css" />

或者横竖不同的样式:

  1. <link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css"> // 竖放加载
  2. <link rel="stylesheet" media="all and (orientation:landscape)"href="landscape.css"> // 横放加载

flex 布局

弹性布局是在 2009 年提出的,这是区别于以往常规布局的一种新的布局方式。它是基于一维(x/y)方向进行布局。最新提出的 grid 二维布局,则是面向未来的大型网站的布局结构。这里,我们不贪多,先讲一下 flex 的一维布局方式。

基本术语

首先声明一点,flex 布局,不仅仅是你使用 display:flex 就行。这是一个完整的概念,是由许多标签属性共同组成的。我们先来看一下它的基本术语:

flexbox.png-11.5kB

其中,最为重要的是主轴(main axis) 和 辅轴(cross axis),容器(container) 和 子元素(items)的概念。我们一个一个来介绍一下:

  • main axis:主轴是 flex item 在设置尺寸大小,排列方式的参照物。是有 flex-direction 设置。

    • main-start / main-end:主轴的开头/末尾
    • main-size:主轴的尺寸大小
  • cross axis:辅轴是垂直于主轴的方向。

    • cross-start / cross-end:辅轴的开头/末尾
    • cross-size:辅轴的大小
  • container:是 flexbox 的容器元素。使用 display:flex 来进行命名。
  • items:是容器的第一级子元素。两者的区别,可参照下图:

image\_1b9q3kbmruuvimv7k01hpjckh9.png-10kB

在 flexbox 中,可以根据作用对象的不同,将属性分为父容器属性和元素属性。下面,我们就这两类来展开讲解。

容器属性

定义一个容器很简单,直接使用 display:flex 进行修饰即可:

  1. // inline-flex 是修饰行内不可分离的 flexbox 布局
  2. .container {
  3. display: flex; /* or inline-flex */
  4. }

flex-direction

该标签可以用来设置 主轴 的方向,通常有 4 种:

  1. .container {
  2. flex-direction: row | row-reverse | column | column-reverse;
  3. }
  • row:从左到右(按照中国排版标准来定义)。默认值
  • row-reverse:反向,从右到左排列。
  • column:自上而下
  • column-reverse:自下而上

具体排布可参照如图:

image\_1b9q46ps0fhp19pcj931k2h0em.png-2.4kB

flex-wrap

该标签定义是否可以进行换行。默认情况下,所有弹性盒子里的元素都会排列在一行里。它有 3 个属性值:

  1. .container{
  2. flex-wrap: nowrap | wrap | wrap-reverse;
  3. }
  • nowrap:不换行。超出的元素会根据剩余空间的大小来确定自身的大小。默认值
  • wrap:可以换行,如果元素超出容器的尺寸,则可以排列到下一行中。
  • wrap-reverse:反向换行,该属性和上一个的区别在于,多余的那一行将会替代原来的位置。差异如图:

image\_1b9q4feem12pi1etd1vldhetrmv13.png-7.4kB

flex-flow

该标签没啥说的,就是 flex-direction 和 flex-wrap 的合并标签。

  1. flex-flow: <‘flex-direction’> || <‘flex-wrap’>

justify-content

用来定义子元素在主轴上排列的方式。可用属性值有 5 个:

  1. .container {
  2. justify-content: flex-start | flex-end | center | space-between | space-around;
  3. }
  • flex-start:items 紧贴着 container 的 main-start 排列。默认值
  • flex-end:items 紧贴着 container 的 main-end 排列
  • center:items 在 container 里,居中排布
  • space-between:items 会带上空隙,在 container 中均匀排布,不过,首尾 item 紧贴边。
  • space-around:每个 item 会均匀分配一些空隙,首尾只有一份空隙,其余有两份,因为,其余是两个 item 的和。具体差异如图:

image\_1b9q4qtg0h7717k2kk11g7q1sqo1g.png-13.8kB

align-items

定义元素在辅轴上的排列。它的几个值和 justify-content 差不多:

  1. .container {
  2. align-items: flex-start | flex-end | center | baseline | stretch;
  3. }
  • flex-start: items 紧贴在辅轴的 cross-start
  • flex-end:items 紧贴在辅轴的 cross-end
  • center:items 在辅轴上,居中排列。
  • baseline:items 根据内容的 baseline 对齐排列。
  • stretch:items 充满整个辅轴。具体排布如下图:

image\_1b9q5c3hclgjm0qocq1v9imlh1t.png-15kB

align-content

该标签是用来定义多行情况下,行元素整体的排布。(如果只是一行,就没必要了。)具体属性有:

  1. .container {
  2. align-content: flex-start | flex-end | center | space-between | space-around | stretch;
  3. }
  • flex-start:多行元素紧贴着 main-start 排布
  • flex-end:多行元素紧贴着 main-end 排布
  • center:多行元素在辅轴上,居中排布
  • space-between:多行元素根据空隙,在辅轴上均匀排布,并且,首尾贴边
  • space-around:每行元素两端会自动带上一份空隙,不过,首尾两端只有一份,其余有两份(是两行空隙之和)
  • stretch:每行元素均匀充满整个主轴,默认值。具体排布见图:

image\_1b9q5tcpd13oqqpu1veu1g62tod2a.png-17.3kB

接下来,我们来看一下 items 相关的 flexbox 属性。

items 属性

在 items 设置相关的属性,是直接在子元素中设置,而不是在父容器中。只要是父容器下的第一级子元素都被称作为 items。接下来,我们就来看一下,与之相关的标签属性。

order

默认情况下 items 是 HTML 中的顺序来排布的,不过,你可以通过 order 标签来手动更改他们的顺序。数值越大,排列的位置约靠后

  1. // 有 3 个元素。item_1 排第一个
  2. .item_1 {
  3. order: 2;
  4. }
  5. // 当设置 order 之后 item_1 变为最后一个

flex-grow

该标签从来设置子元素自身可以占据多大的空隙,接受的值只能为 >=0 的整数,默认为 0。例如:

  1. .item_1 {
  2. flex-grow: 1;
  3. }
  4. .item_2 {
  5. flex-grow: 1;
  6. }

此时,会将空隙平均分为两份,item_1 和 item_2 各占一份。如果这样:

  1. .item_1 {
  2. flex-grow: 1;
  3. }
  4. .item_2 {
  5. flex-grow: 2;
  6. }

那么,空隙一共会分为 3 分,item_1 占 1 份,item_2 占两份。

flex-shrink

该标签是用来定义,如果在行内时,有元素超出容器的宽度,那么其它元素会相应的自适应缩小。默认情况下,所有的子元素的 shrink 都为 1:

  1. flex-shrink:1

如果你将 item_1 设置为 2,则超出的部分会被多分 1 份到 item_1 上进行缩小。

flex-basis

设置在没有空隙分配时的默认尺寸。如果有空隙出现,并且,你没有设置 flex-grow,那么默认是不会分配空隙到该元素的 content 中。如果你设置了 flex-grow,那么优先当其他元素已经达到使用 width 或者 height 设置的尺寸时,才会给其分配相应的空隙。 在弹性盒子中,widthheight 有效性是在有多余空间,并且处于默认 item 样式(即,没 grow/shrink)时。大部分情况,如果你想设置固定大小的盒子,需要将 grow 和 shrink 设置为 0.

  1. .fix-item{
  2. flex-basis:200px;
  3. flex-grow:0;
  4. flex-shrink:0;
  5. }

该标签有两个取值类型:

  1. .item {
  2. flex-basis: <length> | auto; /* default auto */ }

auto 表示按默认情况来,即,遵循缩放,多余的空间会分配到 content 中去。

flex

该标签也是一个综合标签,flex-shrink 和 flex-basis 是可选的。

  1. .item {
  2. flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
  3. }

默认值为:

  1. .item {
  2. flex: 0 1 auto;
  3. }

align-self

单独设置 item 在辅轴上分布的位置。取值和 align-items 一样。

  1. .item {
  2. align-self: auto | flex-start | flex-end | center | baseline | stretch;
  3. }

例如:

image\_1b9qt86ek1k6134v1eu4q6i14g62n.png-5.1kB

另外,float, clear 和 vertical-align 这几个标签,对 items 无效,这点需要牢记。

兼容

flex 现在的兼容性已经很棒了,所有的主流平台都会兼容,不过,如果你还有针对 Android 4.3 以前的版本,则需要加上相关的 prefix。大致的 prefix,如下:

  1. display: -webkit-box;
  2. display: -moz-box;
  3. display: -ms-flexbox;
  4. display: -webkit-flex;
  5. display: flex;

不过,最好还是采用编译的形式,有时候就不用自己手动加了。

rem vh vw 响应式

在响应式开发中,一般提倡使用的是灵活单位而非固定的 px 值。近年来比较好用的就是 rem 单位。另外,还有其他的单位,例如:emvhvw 等。这里,集中说明一下:

  • em:准确的说是相对于父节点的字号来计算的,如果自身定义了字号那么就相对自身字号来计算(针对其他属性使用 em 单位)。例如:

    .parent{

    1. font-size:20px;

    }
    .child{

    1. font-size:2em; // 40px
    2. padding:2em; // 80px

    }

  • vh/vw:这两个单位实际上是相当于 viewport 来定义的。vh 相当于 1% 的 viewport高度。vw 相当于 1% 的 viewport 宽度。这就可以让我们脱离父元素宽度的限制了。常常用于整块布局,而它的兼容性也挺好的,Android 4.4 都支持。

  • vmin/vmax:这两个单位和上面的区别在于,它们不代表某个具体的宽高,而是代表大小,如果宽 > 高则,vmax = 1% 宽,vmin = 1% 高,反之依然。他们的兼容性和 vh/vw 一样,也是在 Android 4.4 以上可用。这两个属性看起来挺鸡肋的,不过实际上用处很多。例如,实现背景图的 containercover 的效果。

    // 实现 container
    .bg{

    1. width:100vmin;
    2. height:100vmin;

    }

如图:

image\_1b9t3c1lp15ha132c16i61a7m16f89.png-21.7kB

  1. // 实现 cover 效果
  2. .bg{
  3. width: 100vmax;
  4. height: 100vmax;
  5. }

如图:

image\_1b9t3d8kj1doo1hphii111iv1bmet.png-23.1kB

  • rem:该单位是相对于根元素 html 的大小。该属性值用处比较大,常常用在 retina 兼容上。

    // 根据根元素的 font-size 设置
    html{

    1. font-size:14px;

    }
    .some-node{

    1. font-size:2rem; // 28px

    }

在 retina 兼容屏上,常常会根据 dpr 的大小来手动调整根元素的 font-size,来对相关的屏幕进行兼容。

  1. // iphone6 的基准值
  2. @media (min-width : 375px) and (max-width : 667px) and (resolution : 2dppx){
  3. html{font-size: 37.5px;}
  4. }
  5. //iphone5 的基准值
  6. @media (min-width : 320px) and (max-width : 568px) and (resolution : 2dppx){
  7. html{font-size: 32px;}
  8. }

大致的属性使用就是上面几类,大家有空的时候多多写一下,就能铭记于心了。

发表评论

表情:
评论列表 (有 0 条评论,424人围观)

还没有评论,来说两句吧...

相关阅读

    相关 响应网站的开发

    什么是响应式网站? 响应式网站设计是一种网络页面设计布局,其理念是:集中创建页面的图片排版大小,可以智能地根据用户行为以及使用的设备环境进行相对应的布局。 页面的设计与