一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
理解 viewport
布局视口(layout viewport)与视觉视口(visual viewport)
<meta name="viewport" content="width=device-width">
这里设置的 width,就是布局视口的宽度。那么什么是布局视口呢?大家现在可以打开一个新的 chrome 标签页,访问 www.baidu.com/(百度首页),点击右键,选择“检查”,选中 mobile 模式,然后刷新页面,你会得到一个类似这样的元素审查界面:
为什么一定要设置 width=device-width ?不设置会有什么后果?这里我随便把 width 改写成1000,发现页面变成了这样:
页面的可视区域变小了,这是为什么呢?这是由于视觉视口和布局视口不相等导致的。
所谓视觉视口,它指的是你的设备实际的可见区域,也就是浏览器的宽高。在PC端,浏览器的宽高我们可以任意缩放;但在移动端,浏览器的宽高一般是不支持改变的,其大小由设备屏幕的大小决定。
通过访问 window.innerWidth 和 window.innerHeight 两个属性,我们可以获取到视觉视口的宽高。通过 document.documentElement.clientWidth 来获取布局视口的宽度。
理想视口(ideal viewport)
实际上,很多时候,布局视口本身的宽度都是无法和视觉视口完全匹配的。为了解决这个问题,人们提出了"理想视口"的概念,它指的是布局视口最理想的尺寸。
"理想的尺寸"指的是整个页面刚好全部覆盖手机屏幕的尺寸。这个尺寸不需要我们手动计算,厂商根据手机屏幕尺寸大小,会提供一个最符合这个屏幕尺寸页面设计方案,我们通过这样一行代码就可以应用这个方案:
<meta name="viewport" content="width=device-width">
此处 width 属性对应的就是布局视口的值。设置 width = device-width 的目的,正是为了使布局视口的宽度刚好匹配上视觉视口的宽度。
rem em vw/vh
rem 指的是相对于HTML根元素的字体大小(font-size)来计算的长度单位。比如说我给 html 元素设置一个 font-size 是 100px,那么就有如下的换算关系:1rem = 100px
em 也是一个相对长度单位,它相对的是使用它们自身元素的字体大小。注意:很多人认为 em 单位取的是当前元素对应父元素的字体大小,这是不对的。的确,在一些情况下,em 确实会刚好取到父元素的字体大小,但这并非 em 的本色,而是由继承导致的。
vw 和 vh 是一种区别与 rem 和 px 的 css 尺寸单位。它们天生自带等比缩放能力:
- vw:1vw = 视觉视口宽度 / 100
- vh:1vh = 视觉视口高度 / 100
rem 和 vw/vh 之间不存在绝对的优劣,在选型上需要注意的是兼容性:vw/vh 的兼容性不如 rem。早年 rem 一直是响应式布局的主流解决方案,最关键的原因就是兼容性好,不挑食。而 vw/vh 则需要ios8、安卓4.4及以上操作系统的支持。话虽如此,2020年了,低于 ios8 和安卓 4.4 的机型在市场中的占比并不高(不过大家选型的时候还是要根据自己产品的投放情况实事求是地做判断哈),rem 和 vw/vh 的选择在如今更像是一个仁者见仁智者见智的问题。个人来说,是不推荐使用rem的,推荐使用vw/wh。
现在有一个场景,一个h5页面所有的距离都是用px写死的,而且这个距离都是按照375px的设计稿来画的,但是现在想要自适应不同宽度的手机,怎么做呢?可以把所有的px转化为vw单位,转换函数如下:
function px2vw(val) {
// 10px 9.5px
const reg = /^(\d+(\.\d+)?)px$/
// match的正则表达式里面一定要写括号,这样就可以拿到括号里面的值
const arr = val.match(reg) || []
const numStr = arr[1]
const num = parseFloat(numStr)
// 计算出vw, 重新赋值
// 375px
const vmNum = (num / 375) * 100
return `${vmNum.toFixed(2)}vw`
}
媒体查询
媒体查询是非常别致的"有条件的 CSS 规则"。它只适用于一些基于某些规定条件的 CSS。如果满足那些条件,则应用相应的样式。
媒体查询有两个部分,先是一个设备规范,然后是一个大小规则。
@media screen and (min-width: 480px)
bootstrap的栅格原理,就是利用media和grid动态的设置每一列的宽度:
.grid {
display: grid;
grid-template-rows: repeat(var(--bs-rows, 1), 1fr);
grid-template-columns: repeat(var(--bs-columns, 12), 1fr);
gap: var(--bs-gap, 1.5rem);
}
@media (min-width: 768px) {
.grid .g-col-md-4 {
grid-column: auto/span 4;
}
}
下面我们自己实现一个栅格系统
.row {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 50px;
grid-auto-rows: 50px;
}
.row div {
background: pink;
border: 1px black solid;
/* div的默认布局: 占一行 */
grid-column: auto/span 12;
}
@media (min-width: 576px) {
.row .col-sm-1 {
grid-column: auto/span 1;
}
.row .col-sm-2 {
grid-column: auto/span 2;
}
}
@media (min-width: 768px) {
.row .col-md-1 {
grid-column: auto/span 1;
}
.row .col-md-2 {
grid-column: auto/span 2;
}
}
@media (min-width: 1200px) {
.row .col-xl-1 {
grid-column: auto/span 1;
}
.row .col-xl-2 {
grid-column: auto/span 2;
}
}
<div class="row">
<div class="col-lg-4 col-sm-6">col</div>
<div class="col-lg-4 col-sm-6">col</div>
<div class="col-lg-4 col-sm-6">col</div>
</div>
响应式图片
根据屏幕匹配的不同尺寸显示不同图片,如果没有匹配到或浏览器不支持 picture 属性则使用 img 元素:
<picture>
<source media="(min-width: 650px)" srcset="demo1.jpg">
<source media="(min-width: 465px)" srcset="demo2.jpg">
<img src="img_girl.jpg">
</picture>
如何做一个响应式网站
设计师的沟通
- 首先要确定网站的交互式如何的
- 网站是否有一整套设计规范,比如字体、颜色、字号、间距等
- 哪些必须是100%的还原设计图,哪些是可以灵活处理的
网站开发注意事项
语义化标签
写网站为方便爬虫检索到,必须正确使用html5中的语义化标签
robots.txt
搜索爬虫访问网站时,第一个访问的文件,如果有这个文件,那么只会访问这个文件中规定的能访问的范围文件。如果不存在,则所有的都可以被访问。一般一些后台管理文件是不需要被爬虫抓取的。
User-agent: *
Disallow: /admin/
表示都可以被抓取,除了admin文件夹中的内容
humans.txt
humans.txt 是给人看的,介绍网站开发大致情况
favicon.ico
网站图标,可以使用www.bitbug.net在线ico制作工具, 一般是网站的logo
用户代理userAgent
user-agent是一个特殊字符串头,能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。在APP的下载中,可以根据用户的user-agent,来判断用户的设备是安卓还是IOS,来给出不同的安装包。
window.navigator.userAgent