Twlig / issuesBlog

MIT License
3 stars 0 forks source link

响应式布局 #16

Open Twlig opened 2 years ago

Twlig commented 2 years ago

在介绍响应式布局之前,先讲讲响应式布局产生的原因。由于存在各种不同分辨率的设备,在开发人员采用css渲染页面的时候展示页面的布局也需要随之改变,比如:在PC端屏幕尺寸大,字体可以显示20px正好,但是移动端字体20px就很大。因此,对于不同的设备,我们需要不同的布局方案。但是这又存在一个很大的问题,市场上的设备非常多,难道每一个设备都要编写不同的css样式吗?那工作量也太大了。因此,还需要一套较通用的响应式布局方案

响应式设计

使得一个网站同时适配 多种设备多个屏幕,让网站的布局和功能随用户的使用环境(屏幕大小、输出方式、设备/浏览器能力而变化),使其视觉合理,交互方式符合习惯。如使得内容区块可伸缩与自由排布,边距适应页面尺寸,图片适应比例变化,能够自动隐藏/部分显示内容,能自动折叠导航和菜单。

在开始介绍响应式布局前,先介绍一下逻辑像素和物理像素。

物理像素和逻辑像素

  1. 物理像素

    物理像素也叫设备像素,是设备屏幕实际拥有的像素点,单位px(Pixel )。一个设备的像素点个数在生产时就固定了。比如iPhone 5的分辨率640 x 1136px,那么水平方向上有640个像素点,竖直方向上有1136个像素点。

  2. 逻辑像素

    逻辑像素也叫设备独立像素。可以理解为反映在css里的像素点,单位也是px,是浏览器使用的抽象单位,主要用来在网页上绘制内容。也可以说css px是专门为web开发者提出的一个抽象概念,也只跟我们平时写的css样式有关,与分辨率(比如720px*1280px)里的px没关系。

  3. DevicePixelRadio 也叫像素比,window.devicePixelRatio是设备上物理像素和逻辑像素的比例。公式表示就是window.devicePixelRatio = 物理像素/逻辑像素。

    注意:

    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    • 这条语句里的device-width指的并不是物理像素,而是逻辑像素。也就是我们平时在谷歌模拟调试手机设备时显示的像素。比如:iPhone 6 物理像素 750*1334,逻辑像素375*667,像素比2,也就是1个逻辑像素需要用2个物理像素来显示。
    • 一般PC端的浏览器都支持缩放,这其实就是调整像素比,比如放大,就是把像素比调大,1个css像素由更多个设备像素来显示。但是手机一般都不支持,不相信看看微信,都是设置了没有缩放,所以像素比就固定是2。但是其实这是由于app内部禁用了缩放,手机像素比是可以改变的,比如手机图片可以放大缩小过。那么在我们把手机图片放大的时候,其实图片的逻辑像素没有变,假设图片10 * 10px占满整个屏幕,像素比为1,设备像素就是10*10px。我们放大图片,使像素比为2,那么10*10px的设备只能显示5*5px的逻辑像素,也就是只能显示图片的一部分,这是不是就和咱们日常生活场景吻合了。
    • viewport 创建一个虚拟的窗口(viewport),这个虚拟的窗口就是layout viewport分辨率接近桌面显示器,apple将其定位为980px。在手机上,可以通过document.documentElement.clientWidth来获取。主要是为了解决手机和PC端分辨率相差太大,导致PC端网页在手机显示的问题。比如:一个长960px的页面,有一个元素是20%(实际解析出来就是192px),如果用宽为320px的屏幕打开,这个元素就成了64px,但是这个时候我设置的字体大小是12px,在320px的屏幕上就只能显示64/12个字了。

    ❗❓问题:

    常规的css大小单位是px,假设需要让图片占满整个分辨率为100*100px的屏幕,像素比是1,那么我们就需要设置图片的大小为100*100px。但是当另一个分辨率为200*200px,像素比为1的屏幕打开这个网页时,就会发现图片只占屏幕一半。这就是常规的css单位px存在的问题,下面将介绍解决方案。

响应式布局方案

  1. 媒体查询

    通过给不同分辨率的设备编写不同的样式实现响应式布局,用于解决不同设备不同分辨率之间兼容问题,一般是指PC、平板、手机设备之间较大的分辨率差异。

    @media only screen and (min-width: 375px) and (max-width: 750px){
       样式1
    }
  2. flex

    布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。Flex布局,可以简便、完整、响应式地实现各种页面布局。

    .box{
     display: flex;
    }

    教程见:[Flex教程](https://github.com/Twlig/issuesBlog/issues/!https://www.ruanyifeng.com/blog/2015/07/flex-grammar.html)

  3. em

    em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。

    • em的值并不是固定的
    • em会继承父级元素的字体大小

    注意:任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em=16px。那么12px=0.75em,10px=0.625em。为了简化font-size的换算,需要在css中的body选择器中声明Font-size=62.5%,这就使em值变为 16px*62.5%=10px, 这样12px=1.2em, 10px=1em, 也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了。

    所以我们在写CSS的时候,需要注意两点:

    • body选择器中声明Font-size=62.5%;
    • 将的原来的px数值除以10,然后换上em作为单位;
    • 重新计算那些被放大的字体的em数值。避免字体大小的重复声明。
  4. rem

    rem为元素设定字体大小时,相对的HTML根元素。集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。

    var getFontSize = () => {
       let deviceWidth = document.documentElement.clientWidth;  //获取逻辑像素
       let FontSize = (20*(deviceWidth/320) > 40 ? 40 + "px" : 20*(deviceWidth/320) + "px")
       document.documentElement.style.fontSize = FontSize; //设置html字体大小
    }
    window.addEventListener("load", getFontSize)
    window.addEventListener("resize", getFontSize)
  5. vh/vw方案

    视口是浏览器中用于呈现网页的区域,移动端的视口通常指的是 布局视口

    • vw : 1vw 等于 视口宽度1%
    • vh : 1vh 等于 视口高度1%
    • vmin : 选取 vwvh最小 的那个
    • vmax : 选取 vwvh最大 的那个

    使用 css 预处理器把设计稿尺寸转换为 vw 单位,包括 文本,布局高宽,间距 等,使得这些元素能够随视口大小自适应调整。

    #box { 
     width: 50vw; 
     height: 50vh; 
     margin: 25vh auto; 
    }
  6. %

    相对于父元素的大小占比。

    1、对于普通定位元素就是我们理解的父元素

    2、对于position: absolute;的元素是相对于已定位的父元素

    3、对于position: fixed;的元素是相对于ViewPort(可视窗口)

    .div {
       width: 100px;
    }
    .div div {
       width: 80%;   //80px
    }

参考文章: