你没事吧?没事就来看看这篇响应式方案

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你没事吧?没事就来看看这篇响应式方案相关的知识,希望对你有一定的参考价值。


前言

hi大家好,我是小鱼,今天讨论的是前端响应式方案。这也是很多面试官喜欢问的一个问题,题型考察范围比较广,区分度比较大,一题就把你看得透透的,特别是移动端的更不可避免。所以,卷起来吧。

响应式

一提到响应式就会有很多概念,概念 == 术语,专业,高深,冷酷,无情。响应就是有响有应,这是一件双箭头的事情(我喜欢你,你也喜欢我)注意:前提是合适。那换做是屏幕也是同理,根据屏幕大小,显示合适的内容。我们先给它一个定义​​↓​

同一个页面在不同的屏幕尺寸的一个终端设备上有一个不同的布局表现,简单来说可以适配多端,同时让用户在多个设备上都有一个很好的页面源体验。

可能有些小伙伴会认为响应式布局是CSS3之后才有的一个概念,响应式就是flex或者媒体查询,其实不是这样,像早期的一些流排版,可能会结合一些​​min-width​​,​​min-height​​和百分比,一定程度上可以实现响应式布局。或者大家熟悉的​​REM​​、​​EM​​、​​VW/VH​​还有多栏布局,图片的话有图片集​​srcset​​......等等

在讨论方案之前我们先回顾一些常用的单位

单位

px

px(pixel),表示像素,所谓像素就是呈现在我们显示器上的一个个小点,每个像素点都是大小等同的,所以像素为计量单位被分在了绝对长度单位中。像素分为两种类型:css像素和物理像素。

  1. CSS像素(CSS pixels): 又称为逻辑像素,是为web开发者创造的,在CSS和javascript中使用的一个抽象的层
  2. 设备像素(device independent pixels): 设备屏幕的物理像素,任何设备的物理像素的数量都是固定的

每一个CSS声明和几乎所有的javascript属性都使用CSS像素,因此实际上从来用不上设备像素 ,唯一的例外是screen.width/height,这也是为什么给不同分辨率的屏幕上设置一样的字体大小呈现出来的却不一样

rem/em

​em​​的字体大小是相对于最近的被设定过字体大小的祖先元素

​rem​​是CSS3新增的一个相对单位(root em,根em),rem为元素设定字体大小时相对的只是根元素html,默认情况下,html元素的​​font-size​​为16px。这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。

vw/vh

​vw/vh​​也是一个相对单位(类似于​​rem​​,​​em​​)

vw:viewport width 视口宽度单位,1vw = 1/100视口宽度

vh:viewport height 视口高度单位,1vh = 1/100视口高度

注意:和百分比是有区别的,百分比是相对于父元素来说的,而vw和vh总是针对于视口来说的。实际开发中用vw最多,因为vh是相对视口高度计算尺寸的,一般我们都是相对的视口宽,而且使用vh需要考虑全面屏,视口高度尺寸会偏大。

实现方案


媒体查询

刚刚介绍px的时候说到,我们所用到的1px(css像素)所表示的物理像素在不同终端设备上的大小是不同的,那我们要解决这样的问题,​​BiuBiuBiu​​ ---- 媒体查询(Media Query)闪亮登场,是CSS3的新语法。

  • 使用@media查询,可以针对不同的媒体类型定义不同的样式
  • @media可以针对不同的屏幕尺寸设置不同的样式
  • 当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面
  • 目前针对很多苹果手机、android手机,平板等设备都用得到媒体查询

那我们就可以针对不同的屏幕大小定义不同的样式,来达到适配的效果。

​栗子↓​

// 设置max-width 是指定义输出设备中页面最大可见区域宽度,当宽度小于某个像素时,会执行里面的样式

@media screen and (max-width: 1334px)
.container
width: 600px;



@media screen and (max-width: 960px)
.container
width: 400px;



@media screen and (max-width: 750px)
.container
width: 200px;

外链式

​min-width​​:最小值,大于或者等于该值加载css
​max-width​​:最大值,小于或者等于该值时加载css
或者一些多个端口:xx < 视口 < xx

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 通用的样式写在最前面 -->
<link rel="stylesheet" href="./css/common.css">
<!-- 针对不同的视口,选择不同的样式 -->
<link rel="stylesheet" href="./css/large.css" media="screen and (min-width:1200px)">
<!-- 为了避免更改了顺序,导致临界点发生改变,通常错开1px -->
<link rel="stylesheet" href="./css/small.css" media="screen and (max-width:1201px)">
<!-- 各个视口相似的样式要提取出来,防止书写多次 -->
<title>Document</title>
</head>
<body>
<!-- 在视口>1200的时候显示红色字体,绿色背景 -->
<!-- 在视口<1200的时候显示蓝色字体,粉色背景 -->
<div class="box">你好</div>
</body>
</html>

缺点:如果项目适配多端情况比较多,改变浏览器大小时需要改变的样式就很多,这么多的样式管理起来就很繁琐。

百分比

百分比大家都很熟悉了,​​width​​、​​height​​属性的百分比依照与父属性的宽高,设置百分比可以让浏览器中的元素随着浏览器的大小而变化,这样也可以实现响应式,简单写个栗子吧。

.box 
width: 100%;
height: 500px;
background-color: rgb(243, 151, 45);
display: flex;
justify-content: space-around;
align-items: center;

.item
width: 20%;
height: 150px;
background-color: rgb(211, 56, 56);

你没事吧?没事就来看看这篇响应式方案_css

百分比只能做一些简单的响应式,如果全部使用百分比单位来实现响应式布局,有很明显的缺陷:

  1. 计算量来说比较复杂,我们刚刚只写了几个简单的元素,如果页面比较丰富呢?全部按照设计图换算成百分比在成本上来说太高了。
  2. css中的子元素中的百分比(%)到底是谁的百分比?widthheight相对于父元素的widthheighttopbottom相对于直接非static定位(默认定位)的父元素的高度,leftright相对于直接非static定位(默认定位的)父元素的宽度,而marginpadding不管垂直还是水平方向都相对比父元素的宽度、border-radius则是相对于元素自身等等,这么多的条条框框,会造成我们使用百分比单位容易使布局问题变得复杂、混乱。我找到了我给大家列出来
  • ​padding​​百分比是相对于​​参照元素的宽度​​而言;
  • ​margin​​百分比是相对于​​参照元素的宽度​​而言;
  • ​width​​百分比是相对于​​参照元素的宽度​​而言;
  • ​left​​、​​right​​百分比是相对于​​参照元素的宽度​​而言;
  • ​height​​百分比是相对于​​参照元素的高度​​而言;
  • ​top​​、​​bottom​​百分比是相对于​​参照元素的高度​​而言;
  • ​line-height​​百分比是相当于​​元素自身文字大小​​而言;
  • ​background-size​​百分比是相当于​​元素自身的宽高​​而言;
  • ​border-radius​​百分比是相当于​​元素自身的宽高​​而言;
  • ​transform​​百分比是相当于​​元素自身的宽高​​而言;
  • ​background-position​​百分比和其它的百分比单位表现都不一样,具体可以用以下公式计算:
positionX = (容器的宽度-图片的宽度) * percentX; 
positionY = (容器的高度-图片的高度) * percentY;

rem

rem这个单位刚刚已经介绍过了,简单、灵活。它是相对于根元素html的​​font-size​​来决定大小的,根元素的​​font-size​​相当于提供了一个基准,当页面的size发生变化时,只需要改变​​font-size​​的值,那么以rem为固定单位的元素的大小也会发生响应的变化。

计算rem

不知道大家有没有写过移动端的项目,在做移动端各种尺寸屏幕的适配时,用的最多的就是rem方案。我们都写过这样的代码,来设置根字体大小。比如把我们的html的​​font-size​​设置成1px,这样1rem就等于1px,因为我们标注稿750px,是基于二倍屏的,1个css单位等于2个实际单位,所以我们的​​font-size​​设置为0.5px,这样我们设置尺寸时,rem和标注稿的px,就是1比1映射的。当然这里所有的大小都是相对于标注稿尺寸来说的,如果是其他屏幕的尺寸,html的​​font-size​​肯定要相应的变大或者变小。

// 基准大小
const baseSize = 16
// 设置 rem 函数
function setRem()
// 当前页面宽度相对于 750 宽的缩放比例,可根据自己需要修改。
const scale = document.documentElement.clientWidth / 750
// 设置页面根节点字体大小
document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + px

// 初始化
setRem()
// 改变窗口大小时重新设置 rem
window.onresize = function()
setRem()

转换rem

实际开发的时候,还是需要我们去计算对应的rem值去开发。

​postcss-pxtorem​

是一个用JavaScript工具和插件转换CSS代码的工具。

1. 安装 postcss-pxtorem

$ npm install postcss-pxtorem -D

2. 配置Postcss

项目下新建​​postcss.config.js​​文件

module.exports = 
plugins:
postcss-pxtorem:
//根元素字体大小
rootValue: 16,
//匹配CSS中的属性,* 代表启用所有属性
propList: [*],
//转换成rem后保留的小数点位数
unitPrecision: 5,
//小于12px的样式不被替换成rem
minPixelValue: 12,
//忽略一些文件,不进行转换,比如我想忽略 依赖的UI框架
exclude: [node_modules]


配置好了在开发就可以直接使用​​px​​,设计图给多少就写多少,是不是很nice!!!

这里肯定有很多小伙伴会提到字体的问题,用户群体有老年人,有大写字号或者超大,设计师不希望字体自适应。这种就需要你自己去对不同的字号做一些比值,涉及到一些缩放比例,这个比例定好之后,可以转换成大写的PX,通过mixin或者可以通过一些特殊的类对比需不需要​​scale​​。大家可以根据自己的场景去实现。

淘宝的​​flexible.js​

​flexible.js​用来处理移动端各种设备兼容和尺寸众多的问题
“了解一个框架的实现原理比用一个框架更有意思”,推荐文章​​---→​​ ​​手写flexible.js的原理实现​

vw/vh

上面已经介绍过了,忘了的再上去看一遍,加深印象哈哈哈哈哈。使用vw/vh布局,可以实现视口宽度不同,网页元素宽高等比缩放效果,比rem的优势在于,在代码中直接写vw/vh就能实现移动适配效果,不用引入js文件,比rem更简单,但有兼容问题,ie9-11不支持vmin和vmax,opera浏览器整体不支持vw单位。

vw/vh是相对单位,vw相对视口的宽度,vh相对视口的高度。
1vw = 1/100的视口宽度,1vh = 1/100的视口高度。
比如iphone6/7/8的视口宽是375,换算成vw就是3.75。.

除了vw和vh外,还有vmin和vmax两个相关的单位

  • vmin:vw和vh中的较小值
  • vmax:vw和vh中的较大值

但实际开发中用vw最多,因为vh是相对视口高度计算尺寸的,一般我们都是相对的视口宽,而且使用vh需要考虑全面屏,视口高度尺寸会偏大。

// 比如对于iphone6/7 375*667的分辨率 1px = (1/375)*100 vw
$vm_base: 375;
@function vw($px)
@return ($px / 375) * 100vw;


.box
width: vw(150);
height: vw(50);

end

响应式布局就是通过检测视口的宽度,通过一系列方式来让页面适配起来。这些方式各有利弊,大家根据自己的需要来选择。

你没事吧?没事就来看看这篇响应式方案_css_02

闲着没事?你可以这样学学算法

对于很多码农来说,算法总是显得有那么一点高深莫测,好像是一道难以跨越的坎。造成这种现象的原因,一是因为我们对算法的了解和对自己能力的了解不够,还没入门就被吓退了,另外一个原因是,大部分人实际工作中很少用到算法,很多算法都已经被封装到函数库或接口里面了,只需要调用就行,而为了能早点完成任务,我们一般都不会去想接口里面的算法如何实现,只管调用来完成任务,顺利交差就万事大吉了。

“不管用什么方法,能够完成任务就可以”,其实我觉得这种想法也是可以的,毕竟我们搞技术的都比较崇尚实用主义。但是如果我们懂得背后的原理,可能心里会舒坦一些,而且在使用别人接口达不到理想的性能要求时,可以分析是否是接口的实现有问题,从而懂得去选择其他实现版本或者自己动手写,而自己动手写,就必须懂算法了。此外,很多大公司在面试中,往往也会考你算法,很多很多人都倒在算法这个环节上,尸骨遍野。这就是作为码农,即使你的工作不是算法研究,也需要了解一些基础算法的原因。

基础算法,我觉得对于大部分程序员来说,通过一定时间的练习,是可以学会的。了解了这一点,我们才不至于很容易被算法吓退。如果你是个算法小白,现在要开始学习算法了,可是又不知道从何学起,那么我这里给你一些建议。

首先,去找大学的数据结构和算法教程来看。我为什么不推荐很多人都知道的大部头《算法导论》呢?我是怕这大部头又把你吓退了,所以还是先从简单一点的开始吧。数据结构和算法是分不开的,一般来说,每种算法都是为某种数据结构服务的,不同的数据结构,往往需要使用不同的算法。数据结构,可以理解为,我们存放一堆数据时,要以某种结构形式存放,而算法,就是要从这堆数据中寻找到你想要的那一小坨数据的方法,而衡量算法优劣的,是空间和时间复杂度,也就是如果你能使用更少的时间和更少的空间(比如计算时需要使用的内存)就能得到答案,那么这个算法就是更好的。

假设你已经学过教材了,练习过教材上的一些算法题目,那么现在你可以尝试去刷刷LeetCode上的题目了。LeetCode上有很多算法题,按难度分为初级、中级等,练习时可以从简单的到难一点的,这样容易让你练习的过程中保持信心。很多公司在面试算法题时,也是直接使用LeetCode上的题目。我本人曾经在远程面试一家不错的外企时,被要求线上完成3道算法题,因为当时已经有比较长时间不接触算法题目了,所以没能很好完成,也错失了一次机会。然后第二天,我就去LeetCode上看题目,恰巧看到了这家外企出的算法题目,我再尝试去解决,没想到顺利把这些题目完成了。如果我在刷这几道题目之后接受那家外企的线上算法题笔试,也许Offer早就收入囊中了。现在,你应该知道,想要获得好的机会,为什么刷刷算法题可能也是必要的原因了。

除了LeetCode,还有一个我推荐你学习算法的网站,这个网站叫做:GeeksForGeeks,随便搜下就找到了。这网站上面有不少巨头公司的算法题目,包括微软、谷歌、亚马逊、Facebook等等,并且给出了解法,同时有不少面试者分享他们去这些公司面试后的面经,你可以参考参考。我曾经在这个网站上呆蛮长一段时间,现在很久没上去看了,写这篇文章时,我再打开这个网站,已经很难打开了,貌似需要你会轻功才能顺畅访问,哎,我就不说得太直白了。

以上提到的那些学习资料或网站资源,在你学习时,可能也会觉得学是学了,可惜缺乏使用场景,还是无法感受到这些算法的威力所在。现在也有一些付费的算法专栏,号称根据使用场景带你学习算法,让你真正明白算法是如何在实际项目中使用的。因为我没有订阅这个专栏,目前也不想免费给他们做广告,因此还是先不提了,如果需要这种学习方式,可以自己去搜索了解下这些专栏,或者私信我,我会告诉你去哪里订阅。

作为程序员,如果你还有蛮多闲暇时间,除了打游戏不知道干嘛的,建议这样去学学算法吧。不过提醒一下,我这些建议主要是给没有算法基础或者算法基础薄弱的技术人,高手路过时,还望理解,如能笑纳,本人将倍感荣幸!

原文地址:闲着没事?你可以这样学学算法

以上是关于你没事吧?没事就来看看这篇响应式方案的主要内容,如果未能解决你的问题,请参考以下文章

如果你不了解 python 的学习体系?来看看这篇博客吧 ,特邀嘴强擦哥做点评|Python技能树测评

iPhone天天用充电宝充电,几乎没用过充电器没事吧?

响应式网页设计需注意9点

响应式网页设计之技能技巧大盘点

值得一看,响应式网页设计的9条基本原则!

给你的15个响应式网页设计建议!