Layout

设备像素dp (device pixel) == 物理像素 :

设备像素设是物理概念,指的是设备中使用的物理像素。单位pt, 1pt=1/72inch, 1inch =2.54cm

每英寸像素ppi (pixel per inch):

每英寸所拥有的物理像素数目,数值越高,代表显示屏能够以越高的密度显示图像。

每英寸点数dpi (dots per inch):

每英寸多少点,用于点阵数位影像

CSS像素 (css pixel) == 设备独立像素dip (device independent pixel) :

逻辑像素,是相对单位,相对的是设备像素( css像素 = 设备像素 / dpr ),缩放会改变css像素的大小

设备像素比dpr (device pixel ratio):

dpr = 设备像素 / css像素

1
2
3
4
5
6
7
8
9
10
11
12
13
window.devicePixelRatio

<meta name="viewport" content="width=device-width,viewport-fit=cover,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />

#element { background-image: url('xxx.png'); }

@media only screen and (min-device-pixel-ratio: 2) {
#element { background-image: url('xxx@2x.png'); }
}

@media only screen and (min-device-pixel-ratio: 3) {
#element { background-image: url('xxx@3x.png'); }
}

面向逻辑像素开发的基本开发流程

  1. 在head 设置width=device-width的viewport

  2. 在css中使用px

  3. 在适当的场景使用flex布局,或者配合vw进行自适应

  4. 在跨设备类型的时候(pc 手机 平板)使用媒体查询

  5. 在跨设备类型如果交互差异太大的情况,考虑分开项目开发

静态布局(static layout)

  即传统Web设计,网页上的所有元素的尺寸一律使用px作为单位。

1、布局特点
  不管浏览器尺寸具体是多少,网页布局始终按照最初写代码时的布局来显示。常规的pc的网站都是静态(定宽度)布局的,也就是设置了min-width,这样的话,如果小于这个宽度就会出现滚动条,如果大于这个宽度则内容居中外加背景,这种设计常见于pc端。

2、设计方法
  PC:居中布局,所有样式使用绝对宽度/高度(px),设计一个Layout,在屏幕宽高有调整时,使用横向和竖向的滚动条来查阅被遮掩部分;
  移动设备:另外建立移动网站,单独设计一个布局,使用不同的域名如wap.或m.。

优点:这种布局方式对设计师和CSS编写者来说都是最简单的,亦没有兼容性问题。

缺点:显而易见,即不能根据用户的屏幕尺寸做出不同的表现。当前,大部分门户网站、大部分企业的PC宣传站点都采用了这种布局方式。固定像素尺寸的网页是匹配固定像素尺寸显示器的最简单办法。但这种方法不是一种完全兼容未来网页的制作方法,我们需要一些适应未知设备的方法。

流式布局(Liquid Layout)

  流式布局(Liquid)的特点(也叫”Fluid”) 是页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。代表作栅栏系统(网格系统)。

  网页中主要的划分区域的尺寸使用百分数(搭配min-*、max-*属性使用),例如,设置网页主体的宽度为80%,min-width为960px。图片也作类似处理(width:100%, max-width一般设定为图片本身的尺寸,防止被拉伸而失真)。

  1. 布局特点
      屏幕分辨率变化时,页面里元素的大小会变化而但布局不变。【这就导致如果屏幕太大或者太小都会导致元素无法正常显示。

  2. 设计方法
      使用%百分比定义宽度,高度大都是用px来固定住,可以根据可视区域 (viewport) 和父元素的实时尺寸进行调整,尽可能的适应各种分辨率。往往配合 max-width/min-width 等属性控制尺寸流动范围以免过大或者过小影响阅读。

这种布局方式在Web前端开发的早期历史上,用来应对不同尺寸的PC屏幕(那时屏幕尺寸的差异不会太大),在当今的移动端开发也是常用布局方式,但缺点明显:主要的问题是如果屏幕尺度跨度太大,那么在相对其原始设计而言过小或过大的屏幕上不能正常显示。因为宽度使用%百分比定义,但是高度和文字大小等大都是用px来固定,所以在大屏幕的手机下显示效果会变成有些页面元素宽度被拉的很长,但是高度、文字大小还是和原来一样(即,这些东西无法变得“流式”),显示非常不协调

自适应布局(Adaptive Layout)

  自适应布局的特点是分别为不同的屏幕分辨率定义布局,即创建多个静态布局,每个静态布局对应一个屏幕分辨率范围。改变屏幕分辨率可以切换不同的静态局部(页面元素位置发生改变),但在每个静态布局中,页面元素不随窗口大小的调整发生变化。可以把自适应布局看作是静态布局的一个系列。

​ 适合改造原有的系统,侵入性小

1、布局特点
  屏幕分辨率变化时,页面里面元素的位置会变化而大小不会变化。

2、设计方法
  使用 @media 媒体查询给不同尺寸和介质的设备切换不同的样式。在优秀的响应范围设计下可以给适配范围内的设备最好的体验,在同一个设备下实际还是固定的布局。

@media (min-width: 706px) and (max-width: 750px) {}

最佳实践:

  1. 将各功能写成组件
  2. 在公共的sass文件中定义断点
  3. 在每个组件中使用公共的断点
  4. 每个组件中先写基本的样式,在断点中写特殊样式

响应式布局(Responsive Layout)

  随着CSS3出现了媒体查询技术,又出现了响应式设计的概念。响应式设计的目标是确保一个页面在所有终端上(各种尺寸的PC、手机、手表、冰箱的Web浏览器等等)都能显示出令人满意的效果。分别为不同的屏幕分辨率定义布局,同时,在每个布局中,应用流式布局的理念,即页面元素宽度随着窗口调整而自动适配。即:创建多个流体式布局,分别对应一个屏幕分辨率范围。可以把响应式布局看作是流式布局和自适应布局设计理念的融合。

  1. 布局特点
      每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变。

  2. 设计方法
      媒体查询+流式布局。通常使用 @media 媒体查询 和网格系统 (Grid System) 配合相对布局单位进行布局,实际上就是综合响应式、流动等上述技术通过 CSS 给单一网页不同设备返回不同样式的技术统称。

优点:适应pc和移动端,如果足够耐心,效果完美。

缺点:
(1)媒体查询是有限的,也就是可以枚举出来的,只能适应主流的宽高。
(2)要匹配足够多的屏幕大小,工作量不小,设计也需要多个版本。

响应式页面在头部会加上这一段代码:

<meta name="applicable-device" content="pc,mobile">  
<meta http-equiv="Cache-Control" content="no-transform ">  

弹性布局(rem/em布局)

  1. rem/em区别:rem是相对于html元素的font-size大小而言的,而em是相对于其父元素。

  2. 使用 em 或 rem 单位进行相对布局,相对%百分比更加灵活,同时可以支持浏览器的字体大小调整和缩放等的正常显示,因为em是相对父级元素的原因没有得到推广。【中国站点制作网页的时候,习惯用CSS强制定义字体大小,保证每个人都看到一致的效果,包括网易、搜狐这些门户网站在内的大部分站点,用的都是绝对单位px(像素)。但是,如果从网站易用性方面考虑,字体大小应该是可变的,一些视力不是那么好的人需要放大字体才能看得清页面内容。然而,占据大部分浏览器市场的IE无法调整那些使用px作为单位的字体大小。国外人士非常重视网站的易用性,相当一部分外国站点已经使用em作为字体单位。

  3. 这类布局的特点是,包裹文字的各元素的尺寸采用em/rem做单位,而页面的主要划分区域的尺寸仍使用百分数或px做单位(同「流式布局」或「静态/固定布局」)。早期浏览器不支持整个页面按比例缩放,仅支持网页内文字尺寸的放大,这种情况下。使用em/rem做单位,可以使包裹文字的元素随着文字的缩放而缩放。

  4. 浏览器的默认字体高度一般为16px,即1em:16px,但是 1:16 的比例不方便计算,为了使单位em/rem更直观,CSS编写者常常将页面跟节点字体设为62.5%,比如选择用rem控制字体时,先需要设置根节点html的字体大小,因为浏览器默认字体大小16px*62.5%=10px。这样1rem便是10px,方便了计算。

  5. 用em/rem定义尺寸的另一个好处是更能适应缩进/以字体单位padding或margin/浏览器设置字体尺寸等情况(因为em/rem相对于字体大小,会同步改变)。例如:p{ text-indent: 2em; }。

  6. 使用rem单位的弹性布局在移动端也很受欢迎。

  7. 其实在移动端使用所谓的弹性布局,是比较勉强的。移动端弹性布局流行起来的原因归根结底是rem单位对于(根据屏幕尺寸)调整页面的各元素的尺寸、文字大小时比较好用。其实,使用vw、vh等后起之秀的单位,可以实现完美的流式布局(高度和文字大小都可以变得“流式”),弹性布局就不再必要了。

响应式图片

  1. srcset attribute with Density Descriptor

    1
    2
    3
    4
    5
    <img src="cat-200px.jpg" alt="sugar free cat" width="200"
    srcset="cat-200px.jpg 1x,
    cat-400px.jpg 2x,
    cat-600px.jpg 3x,
    cat-800px.jpg 4x">
  2. srcset attribute with Width Descriptor and the size attribute
    This method is suited for images whose width changes according to the viewport size and our responsive breakpoints. This case is the most common in responsive websites.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // w是图片自身的pixel width 
    // sizes里当媒体条件为真,图像将填充的槽的宽度
    <img src="cat-200px.jpg" alt="sugar free cat" width="200"
    srcset="cat-200px.jpg 200w,
    cat-400px.jpg 400w,
    cat-600px.jpg 600w"
    sizes="(max-width: 399px) 50vw,
    (min-width: 400px) and (max-width: 900px) calc(30vw - 40px),
    100vw"
    >

A valid media condition can be either -

* A plain media condition, e.g. (min-width: 900px)  
* A “not” media condition, e.g. ( not (orientation: landscape) )  
* An “and” media condition, e.g. (orientation: landscape) and (min-width: 900px)  
* An “or” media condition, e.g. ( (orientation: portrait) or (max-width: 500px) )  

所以,有了这些属性,浏览器会:

1. 查看设备宽度  
2. 检查sizes列表中哪个媒体条件是第一个为真  
3. 查看给予该媒体查询的槽大小  
4. 加载srcset列表中引用的最接近所选的槽大小的图像  
  1. picture element

    1
    2
    3
    4
    5
    6
    7
    <picture>
    <source media="(min-width:600px) and (max-width:1200px)"
    srcset="images/sinai-medium-screen.jpg">
    <source media="(min-width:1201px)"
    srcset="images/sinai-large-screen.jpg">
    <img src="images/sinai-small-screen.jpg" alt="Unicorn Pool Float">
    </picture>
    1
    2
    3
    4
    5
    <picture>
    <source type="image/svg+xml" srcset="logo.svg">
    <source type="image/webp" srcset="logo.webp">
    <img src="logo.png" alt="investing.com">
    </picture>
Hairline Border 实现
  1. 0.5px方案

    1
    2
    3
    4
    5
    6
    7
    8
    div {
    border: 1px solid black;
    }
    @media (min-device-pixel-ratio: 2) {
    div {
    border-width: 0.5px;
    }
    }
  2. 用图片模拟边框

    使用 border-image 或者 background-image 将提前准备的一半透明一半有颜色的图片(不想准备图片也可以使用 CSS3 渐变填充)应用到边框上,可以模拟出 0.5px 边框的效果。不过确定也很明显,不好修改颜色,不好添加圆角,边框容易模糊。

  3. 伪类 + transform

    原理是利用 :before 或者 :after 重做 border ,并用 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    .scale-1px{
    position: relative;
    border:none;
    }
    .scale-1px:after{
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    transform-origin: left bottom;
    transform: scale(0.33333333);
    width: 300%;
    height: 300%;
    }