概述
自适应网页设计是一种理念:旨在能够创建自动适应不同设备和屏幕尺寸的响应式网页。这种设计方法允许网页在各种设备(如台式机、笔记本、平板和手机)上都能呈现出良好的视觉效果和用户体验。
自适应网页设计通过一系列的CSS和JavaScript技术,采用流式布局、媒体查询和弹性盒子等设计模式,使得网页能够根据设备的屏幕尺寸自动调整布局、样式和内容。
为什么很少见到一套代码自适应移动端和PC端?
主要是因为移动设备和PC在屏幕尺寸、分辨率、交互方式,组件等方面存在较大的差异。另外移动设备的网络速度和计算能力相对较弱,使用一套代码同时适应多端,会导致页面加载速度变慢,影响用户体验。因此现在很多开发者选择分别开发移动端和PC端应用,以提高开发效率和用户体验。
此次讲解的重点不是一套代码自适应移动端和PC端,而是通过方案的概述,可以更灵活的选择移动端和PC端的自适应方案。
固定布局
顾名思义就是固定大小的设计,让内容在大屏中居中,小屏中出现滚动条。
这种布局方式在传统的网页设计中比较常见,对于需要突出品牌形象、提供清晰导航或展示特定内容的网站来说比较适合。
用代码来实现的话,给body一个固定的宽度,然后让整个body的内容在网页的中间。
body{
width:1200px;
margin:0px auto
}
知乎案例:
.Topstory-container {
...
margin: 10px auto;
width: 1000px
}
媒体查询
媒体查询是CSS3中引入的一个功能,它允许开发者针对不同的设备和屏幕特性(如宽度、高度、分辨率等)应用不同的样式。通过媒体查询,我们可以实现响应式设计,使得网页布局和样式能够根据设备屏幕的特性进行自适应调整。
媒体查询的基本语法如下:
@media mediatype and|not|only (media feature) {
CSS-Code;
}
@media screen and (max-width: 500px) {
...
}
也可以针对不同的媒体使用不同 stylesheets
<link rel="stylesheet" media="mediatype and|not|only (media feature)" href="mystylesheet.css">
流式布局
流式布局(Fluid Layout)是一种基于百分比的布局方式.
特点
是将元素的宽度设置为百分比,而不是具体的像素值。这种布局方式能够自适应不同的屏幕尺寸和分辨率,使页面在不同设备上呈现出良好的效果。
实现原理
是使用CSS的百分比宽度属性,将元素的宽度设置为相对于其容器的百分比。如果一个元素的宽度设置为50%,那么无论其容器的宽度是多少,该元素的宽度都将为其容器宽度的50%。
优缺点
优点是:自适应性和灵活性。由于元素的宽度是相对于其容器的百分比,因此当屏幕尺寸变化时,元素的宽度也会相应地调整,从而保持页面的布局和元素之间的相对位置不变。
缺点是:在大分辨率显示屏上,行可能会过长,导致用户阅读不便。而在窄窗口或在增加文本字号时,行可能会变得非常短,使得内容显得零碎。流式布局无法充分利用空间。当屏幕宽度足够大时,流式布局可能不会充分利用空间来显示更多内容。
css3中新增的视口单位
1vm:窗口宽度的1%。当窗口宽度减小的时候,1vm表示的大小也会对应的减小。
1vh:窗口高度的1%。当窗口高度减小的时候,1vh表示的大小也会对应的减小。
vmin:选择最小的vw和vh
vmax:选择最大的vw和vh
注意:好像跟百分比也没什么区别,但实际上是有区别的
1.vm不管父元素的大小,百分比是根据父元素的大小计算的。
2.百分比有继承关系,vm只和设备的宽度有关系。
这些单位在移动页面开发中特别有用,因为它们可以确保元素的大小始终与视窗的大小保持一定的比例,从而提供更好的用户体验。
flex布局
是CSS3规范中提出的一种新的布局方案。该布局方案提供了一种更加高效简单的方式来处理容器中的元素布局、对齐、空间分配等操作,即使容器中的元素尺寸未知(或者尺寸大小是动态的)也能工作得很好。
新旧语法
一种是W3C于2009年发布的旧语法,另一种是W3C最新发布的新语法。
旧语法中,所有的flex属性都以box打头,flex设置为display: box。
新语法中,所有的flex属性都以flex打头,flex设置为display: flex。
其中新旧语法中间还有存在一种非官方的过渡语法规范,flex设置为display: flexbox。
下面对弹性盒模型布局比较常用的几个属性,做一个简要的概述。
基于主轴对齐(justify-content)
可选值 | 含义 |
---|---|
flex-start | 条目集中于该行的起始位置。第一个条目与其所在行在主轴起始方向上的边界保持对齐,其余的条目按照顺序依次排列。 |
flex-end | 条目集中于该行的结束方向。最后一个条目与其所在行在主轴结束方向上的边界保持对齐,其余的条目按照顺序依次排列。 |
center | 条目集中于该行的中央。条目都往该行的中央排列,在主轴起始方向和结束方向上留有同样大小的空白空间。如果空白空间不足,则条目会在两个方向上超出同样的空间。 |
space-between | 第一个条目与其所在行在主轴起始方向上的边界保持对齐,最后一个条目与其所在行在主轴结束方向上的边界保持对齐。空白空间在条目之间平均分配,使得相邻条目之间的空白尺寸相同。 |
space-around | 类似于space-between,不同的是第一个条目和最后一个条目与该行的边界之间同样存在空白空间,该空白空间的尺寸是条目之间的空白空间的尺寸的一半。 |
基于交叉轴对齐(align-items)
可选值 | 含义 |
---|---|
flex-start | 条目与其所在行在交叉轴起始方向上的边界保持对齐。 |
flex-end | 条目与其所在行在交叉轴结束方向上的边界保持对齐。 |
center | 条目的空白边盒子(margin box)在交叉轴上居中。如果交叉轴尺寸小于条目的尺寸,则条目会在两个方向上超出相同大小的空间。 |
baseline | 条目在基准线上保持对齐。在所有条目中,基准线与交叉轴起始方向上的边界距离最大的条目,它与所在行在交叉轴方向上的边界保持对齐。 |
stretch | 如果条目的交叉轴尺寸的计算值是auto,则其实际使用的值会使得条目在交叉轴方向上尽可能地占满。 |
网格(Grid)布局
网格布局(Grid)则是一种二维布局系统,将容器划分为行和列,然后通过行和列来定位元素。
Grid布局可以创建复杂的网页布局,包括多行多列的版式,以及更复杂的布局结构,如分栏、画廊、卡片等。
通过一个简单的代码示例,讲一下grid是如何做整体布局。
小于500px | 500px 到800px 之间 | 大于800px |
---|---|---|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>grid</title>
<style>
* {
margin: 0px;
padding: 0px;
}
.container {
/* 启用网格容器 */
display: grid;
/* 定义网格单元的宽高 */
grid-template-rows: 50px auto 50px;
/* 特殊单元:fr fr单元允许你将网格容器中的自由空间设置为一个份数:*/
grid-template-columns: repeat(12, 1fr);
/* grid-gap是grid-column-gap和grid-row-gap的简称:如果只有一个值,grid-row-gap的值将和grid-column-gap一样。 */
/* grid-gap: <grid-column-gap> <grid-row-gap> */
grid-gap: 10px;
height: 100vh;
}
.header {
background: red;
grid-area: h;
}
.slider {
background: blue;
grid-area: s;
}
.content {
background: green;
grid-area: c;
}
.footer {
background: yellow;
grid-area: f;
}
@media screen and (max-width: 500px) {
.container {
/* grid-template-areas可以配合grid-area定义一个显式的网格区域。 */
grid-template-areas: 'h h h h h h h h h h h h '
'c c c c c c c c c c c c '
'f f f f f f f f f f f f';
}
.slider {
display: none;
}
}
@media screen and (min-width: 500px) {
.container {
grid-template-areas: 'h h h h h h s s s s s s '
'c c c c c c c c c c c c '
'f f f f f f f f f f f f';
}
.slider {
display: block;
grid-area: s;
}
}
@media screen and (min-width: 800px) {
.container {
grid-template-areas: 'h h h h h h h h h h h h '
's s s s s s c c c c c c '
'f f f f f f f f f f f f';
}
.slider {
display: block;
grid-area: s;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">Header</div>
<div class="slider">Slider</div>
<div class="content">Content</div>
<div class="footer">Footer</div>
</div>
</body>
</html>
rem方式
是基于HTML元素的font-size来计算的。当根元素(通常是HTML)的字体大小改变时,rem单位下的元素大小也会相应地改变,从而实现自适应布局。
例如:根元素的字体大小默认值为16px。如果我们设置一个元素的宽度为2rem,那么该元素的宽度就等于根元素字体大小的2倍,即32px。
为了实现自适应布局,我们可以根据屏幕宽度动态地改变根元素的字体大小,从而调整页面中元素的大小。这样,无论在何种设备和屏幕尺寸下,页面都能保持一致的布局和样式,提高了用户体验。
postcss-pxtorem
一般会结合postcss-pxtorem一起用,自动将px转化为rem。在vite项目中配置postcss-pxtorem插件是非常简单的。分以下几个步骤:
1.安装 postcss-pxtorem 和 amfe-flexible 插件
npm install postcss-pxtorem amfe-flexible --save-dev
2.配置 amfe-flexible:
在项目的根目录下 index.html 文件,并在其中添加以下 viewport meta 标签:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
3.在 main.js 中导入 amfe-flexible:
import 'amfe-flexible';
4.在 vite.config.js 中配置 css.postcss 选项:
import postCssPxToRem from 'postcss-pxtorem';
export default defineConfig({
plugins: [vue()],
css: {
postcss: {
plugins: [postCssPxToRem(
{
rootValue: 75,// rem 的根值,可以根据需要调整
propList: ['*', '!border-right', '!border-bottom'], // // 需要转换的属性
selectorBlackList: ['.ignore'] // 需要忽略的类选择器,这里表示所有 .ignore 类的样式都不进行转换
}
)]
}
}
});
5.在配置完成后,刷新页面,postcss-pxtorem 将会自动将 px 单位转换为 rem 单位。此时,在样式中可以直接使用 px单位,但最终渲染的页面将使用 rem 单位。
如果想在现有的项目中使用rem 且不能修改已存在样式表中的px,推荐flexible.js 结合vsCode插件。
px to rem & rpx & vw (cssrem)
修改@ext:cipchk.cssrem 中的Root Font Size和Vw Design 规定设计稿宽度(一般等同于浏览器视口宽度)
设计稿为:750px 建议分成15份 Root Font Size为:50
设计稿为:1920px 建议分成24份 Root Font Size为:80
在编辑器中书写px像素时 会自动给出rem值提示,按tab键选择
适用场景
在屏幕变化不大的情况还是比较有用的,不固定宽高比的Web应用,适用于绝大部分业务场景
不适用的场景:
移动端变成PC端的场景下是不推荐,主要是移动端的自适应解决方案,但是如果说想把移动端的rem布局内容,直接放在PC端展示,则只会显示更大的字或更大的图片,内容本身并不会变多。
综上所述,网页的自适应设计,应结合上面的几种方案,做全局考虑。通常情况下:grid做整体布局,flex做响应区块,然后根据块的内容使用相对单位进行适配。
原文链接:https://juejin.cn/post/7355096015584116736 作者:用户7308701179308