响应式布局下关于gird栅格布局的一些构思

1、传列数,根据列数计算元素容器宽度

好处是子元素可以写百分比宽度,不用固定某一种宽度,反正知道列数通过计算间距就能得到外层容器的宽度。
举个简单的例子:

(ps:以下用例皆在html中去模拟,就不另外起react或者vue应用了,主打一个轻便。)

在瀑布流下面的栅格布局

  • 先尝试固定列数3,并且固定宽高100px
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><style>.item {color: white;background-color: violet;width: 100px;height: 100px;margin: 2px;text-align: center;}.waterfall {display: flex;flex-wrap: wrap;}</style></head><body><div class="grid waterfall"></div></body><script>const column = 3;const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,];const UIList = list.map((item) => {return `<div class="item">${item}</div>`;});const renderList = new Array(column);const finalList = UIList.forEach((item, childIndex) => {const realIndex = childIndex % column;if (!renderList[realIndex]) {renderList[realIndex] = [];}renderList[realIndex].push(item);console.log("renderList", renderList);});const html = renderList.map((item) => {return `<div class="waterfall-item">${item.join("")}</div>`;});document.querySelector(".grid").innerHTML = html.join("");</script>
</html>

得到的结果:
在这里插入图片描述
好,写法ok,让我们试试列数固定(通过api传入),子元素宽度根据公式计算呢。
理论计算公式:元素宽度 = (屏幕宽度 - 左右间距宽度 - 列之间的间距)/ 列数
注意3列的话,计算列的宽度就是 2个列宽,自己体会。
在这里插入图片描述
好!理论成立,实践开始~!

我们修改下css,让item元素的宽高不在固定。

   .item {color: white;background-color: violet;height: auto;margin: 2px;text-align: center;}

在这里插入图片描述
于是我们得到了上面一坨,因为宽度和高度根据内容自适应了,所以只包裹了填充的数字。

嗯,在意料之中。
在这里插入图片描述

那么关键的计算来了,且看下面的js:

    const column = 3;   // 列数const screenWith = window.innerWidth; // 屏宽const paddingLeft = 12; // 页面左间距const paddingRight = 12; // 页面右间距const columnWith = 8; // 列之间的间距

我们先设定页面左右间距为12(px),列间距为8(px).
然后我们就可以计算单个元素容器宽度了:

  // 四舍五入并且精确到2位小数,防止列数过多而误差过大const itemWidth =Math.round(((screenWith - paddingLeft - paddingRight - columnWith * (column - 1)) /column) *100) / 100;

然后将元素的间距设置成和js里写的一致(当然你也可以把他们开放成动态的api):
完整demo:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><style>* {margin: 0;padding: 0;}.item {color: white;background-color: violet;height: 50px;margin-bottom: 8px;text-align: center;}.item:last-child {margin-bottom: 0;}.waterfall {display: flex;flex-wrap: wrap;padding: 0 12px;}.waterfall-item {margin-left: 8px;}.waterfall-item:first-child {margin-left: 0;}</style></head><body><div class="grid waterfall"></div></body><script>const column = 3;const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,];const screenWidth = window.innerWidth;const paddingLeft = 12;const paddingRight = 12;const columnWidth = 8;const itemWidth =Math.round(((screenWidth - paddingLeft - paddingRight - columnWidth * (column - 1)) /column) *100) / 100;console.log("itemWidth", itemWidth);const UIList = list.map((item) => {return `<div class="item" style="width: ${itemWidth}px;">${item}</div>`;});const renderList = new Array(column);const finalList = UIList.forEach((item, childIndex) => {const realIndex = childIndex % column;if (!renderList[realIndex]) {renderList[realIndex] = [];}renderList[realIndex].push(item);});const html = renderList.map((item) => {return `<div class="waterfall-item">${item.join("")}</div>`;});document.querySelector(".grid").innerHTML = html.join("");</script>
</html>

效果:
在这里插入图片描述

测试高度不一样的栅格效果

增加修改以下代码,意思是给5的倍数的子元素高度设置到100px

   .more-height {height: 100px;}const UIList = list.map((item, index) => {return `<div class="item ${index % 5 === 0 ? "more-height" : ""}" style="width: ${itemWidth}px;">${item}</div>`;});

效果:
在这里插入图片描述
不错,符合预期~

如果我们连列数colum都不想传了咋办?能不能自适应屏幕尺寸设置列数

答案当然是肯定的,前提你要和设计师商量好什么尺寸下出多少列。

比如我们规定:
320px以下,展示2列
320~600px, 展示3列
600~920px,展示4列
920px以上,还是4列,但是容器宽度增加,这时候就需要子元素也做了响应式,否则会造成容器空旷很多。
使用以下方法,动态确定colum列数:

 let column = 2;function handleResize() {const screenWidth = window.innerWidth;if (screenWidth < 320) {column = 2;} else if (screenWidth >= 320 && screenWidth < 600) {column = 3;} else {column = 4;}}// 监听窗口大小变化window.addEventListener("resize", handleResize);// 页面加载时执行一次屏幕尺寸判断handleResize();

看看效果:
320以下展示2行:
在这里插入图片描述

320~600 展示3行:
在这里插入图片描述
600~920 展示4行:
在这里插入图片描述
920往上还是4行,但是单元格宽度增加:
在这里插入图片描述

上面的唯一缺点大概是因为是js控制,页面只要不刷新,即使尺寸变了也不会去动态的计算列数,在移动端影响不大~

2、根据子元素宽度,自动适应列数

如果是采用这种方案,那么子元素必须显示的定义了宽度,即只有子元素存在定义的宽度时才能正确计算。

这种方法则对子元素要求很高,需要子元素定宽并且适配了各种各样屏幕宽度下的尺寸。

我们的计算规则则变成了:
列数 = (屏幕宽度 - 页面左右间距- (列数-1) *列间距) / 子元素宽度(固定)
该公式解出来变成:
列数 = (屏宽 - 左右间距 + 列间距) / (子元素宽度+列间距)

假定我们各项数据值是:

    const screenWith = window.innerWidth;const paddingLeft = 12;  // 左间距const paddingRight = 12;  // 右间距const columnWidth = 8;  // 列宽const itemWidth = 120; // 子元素宽度

计算规则如下:

    // 列数必须向下取整,否则会放不下column = Math.floor((screenWith - paddingLeft - paddingRight + columnWidth) /(itemWidth + columnWidth));

在这里插入图片描述
像上面这种就是剩余宽度明显不够一列被向下取整给截断了。
那么有没有很好的解法呢,目前看来如果子元素定宽,不太好自适应的。

非要定宽可以考虑:
1、列间距自适应
2、整体布局居中

另外在设置子元素宽度时
计算失败的几种情况:
1、子元素定义了100%宽度,旨在根据容器宽度去定宽,但是容器也没有定宽。
2、子元素没有设置宽度导致计算失败,这时候会写一个兼容值,那么固定就会获取这个兼容值。

以上就是个人碎碎念~

希望有所收获!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/43154.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python7:装饰器

目录 1.调用外部程序os.system-阻塞式调用subprocess-python中的模块 2.装饰器前戏作用域&#xff08;1&#xff09;全局和局部-就近原则&#xff08;2&#xff09;嵌套作用域&#xff08;3&#xff09;内置作用域、变量 高阶函数&#xff1a;函数是最高级的对象&#xff08;1&…

海外媒体投稿:5个软文代发经典案例,教大家获得突破

随着互联网的飞速发展&#xff0c;软文代发成为一种高效的推广方法。下面我们就详细介绍五个成功软文代发推广实例&#xff0c;致力于帮助读者把握有关方法&#xff0c;完成突破。 第一实例&#xff1a;社交网络散播在如今社交媒体时代&#xff0c;软文代发能够通过社交平台迅速…

nodejs实现:支付宝订单查询

nodejs实现&#xff1a;支付宝订单查询&#xff1b; 原生http请求&#xff0c;不使用三方库&#xff1b; 代码如下&#xff1a; const https require(https); const crypto require(crypto); const querystring require(querystring);// 支付宝公共参数 const PRIVATE_KE…

[C++] 轻熟类和对象

类的定义 格式规范 class为定义类的关键字&#xff0c;后有类名&#xff0c;类的主体存于{}中&#xff1b;类定义结束时后面的分号不能省略&#xff1b;类体的内容成为类的成员&#xff0c;类中的变量成为成员变量&#xff0c;函数成为方法或成员函数&#xff1b;C兼容C语言的…

SpringBoot配置flyway

背景 目前我们的项目代码都会交由Git、SVN等版本管理工具进行管理&#xff0c;但是我们的sql脚本&#xff0c;尤其是各类ddl脚本并没有进行版本的管理&#xff08;python的web框架Django默认就提供了类似的工具&#xff0c;从一开始就鼓励开发者通过版本管理的方式进行数据库的…

C++中的多重继承和虚继承:横向继承、纵向继承和联合继承;虚继承

多重继承 A.横向多重继承&#xff1a; B.纵向多重继承&#xff1a; C.联合多重继承&#xff1a; 因为 single 和 waiter 都继承了一个 worker 组件&#xff0c;因此 SingingWaiter 将包含两个 worker 组件&#xff0c;那么将派生类对象的地址赋给基类指针将出现二义性 那么如何…

idea http client插件上传文件,并忽略https证书验证

上传文件 ### 传临时素材 图片 POST https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token{{access_token}}&typeimage Content-Type: multipart/form-data; boundary----WebKitFormBoundarywKUX3Xj6aL5Wssnb------WebKitFormBoundarywKUX3Xj6aL5Wssnb Conten…

从Helm到 Operator:Kubernetes应用管理的进化

&#x1f9f0;Helm 的作用 在开始前需要先对 kubernetes Operator 有个简单的认识。 以为我们在编写部署一些简单 Deployment 的时候只需要自己编写一个 yaml 文件然后 kubectl apply 即可。 apiVersion: apps/v1 kind: Deployment metadata: labels: app: k8s-combat …

去水印小程序源码修复版-前端后端内置接口+第三方接口

去水印小程序源码&#xff0c;前端后端&#xff0c;内置接口第三方接口&#xff0c; 修复数据库账号密码错误问题&#xff0c;内置接口支持替换第三方接口&#xff0c; 文件挺全的&#xff0c;可以添加流量主代码&#xff0c;搭建需要准备一台服务器&#xff0c;备案域名和http…

农牧行业CRM洞察:打造营、销、服一体化数字营销平台

01、行业应用背景 保持企业活力&#xff0c;支撑业务单元协调发展&#xff0c;稳定核心产品竞争力&#xff0c;将成为农牧行业企业数字化、数智化建设的指导方向。 积极发挥数据在生产、流通、消费各个环节的决策支撑&#xff0c;为农牧企业特别是多业态集团型企业&#xff0…

JVM:类的生命周期

文章目录 一、介绍二、加载阶段三、连接阶段1、验证阶段2、准备阶段3、解析阶段 四、初始化阶段 一、介绍 类的生命周期描述了一个类加载、连接&#xff08;验证、准备和解析&#xff09;、初始化、使用、卸载的整个过程。 二、加载阶段 加载&#xff08;Loading&#xff09…

全栈业务开发入门——登录业务接口

业务已上传则资源 实现登录业务的前后端联调&#xff0c;前端点击登录按钮向后端发送一个请求&#xff0c;后端调用接口向前端响应结果 效果如下&#xff1a; 设计环境&#xff1a;springbootmybatisvue3axios 一.前端设计 1.基于vue3脚手架创建项目&#xff0c;搭建项目结构…

LAZYNVIM学习使用笔记

文章目录 1. 前言VIM的模式快捷键参考 1. 前言 习惯使用vscode进行代码编辑&#xff0c;无意中刷到lazynvim&#xff0c;感觉功能强大&#xff0c;于是下载、安装&#xff0c;学习使用一下&#xff0c;本篇主要记录学习使用lazynvim的一些要点&#xff0c;防止遗忘。 持续更新…

帝特(DTECH)USB转RS485/422串口线在Ubuntu系统中的安装

因为测试需要&#xff0c;买了一根帝特&#xff08;DTECH&#xff09;USB转RS485/422串口线&#xff0c;今天测试了一下在Ubuntu 22.04系统上的使用。帝特的网站上提供了驱动程序&#xff0c;下载以后发现接口芯片是CP2102&#xff0c;厂商只提供了Linux内核2.6和3.x版本的驱动…

游戏AI的创造思路-技术基础-情感计算(2)

上一篇我们介绍了情感计算的基本支持&#xff0c;本篇将呈现情感计算在游戏AI中的使用实例~~~ 目录 7. 情感计算在游戏AI中的运用实例 7.1. RPG游戏中的运用实例 7.1.1. 实例背景 7.1.2. AI情感计算系统 7.1.3. 引导用户执行任务 7.1.4. 推动游戏剧情发展 7.1.5. 实例效…

用Python玩转Excel的五大功能!

在日常的数据处理工作中&#xff0c;Excel无疑是一个强大的工具。然而&#xff0c;当数据量较大或需要自动化处理时&#xff0c;Python凭借其强大的库支持&#xff0c;如pandas和openpyxl&#xff0c;能够更高效地处理Excel文件。 本文将介绍Python中常用的五种Excel操作**&am…

Python办公自动化:增值税发票批量识别和核验

腾讯云免费体验地址: https://console.cloud.tencent.com/api/explorer?Product=ocr&Version=2018-11-19&Action=VatInvoiceVerifyNew 首先进行识别,这里以python为例子 # -*- coding: utf-8 -*- import jsonfrom tencentcloud.common.common_client import Commo…

【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——红黑树

目录 1 -> 红黑树 1.1 -> 红黑树的概念 1.2 -> 红黑树的性质 1.3 -> 红黑树节点的定义 1.4 -> 红黑树的结构 1.5 -> 红黑树的插入操作 1.6 -> 红黑树的验证 1.8 -> 红黑树与AVL树的比较 2 -> 红黑树模拟实现STL中的map与set 2.1 -> 红…

【堆 优先队列】1354. 多次求和构造目标数组

本文涉及知识点 堆 优先队列 LeetCode1354. 多次求和构造目标数组 给你一个整数数组 target 。一开始&#xff0c;你有一个数组 A &#xff0c;它的所有元素均为 1 &#xff0c;你可以执行以下操作&#xff1a; 令 x 为你数组里所有元素的和 选择满足 0 < i < target.…

linux信息收集与提权

目录 版本信息收集 kali得一些exp网站 kali自带的searchsploit工具 脏牛提权漏洞&#xff08;改写没有写权限的文件&#xff09; 测试靶场下载链接 sudo提权 上传恶意C脚本进行编译生成dirty的elf文件&#xff0c;也可以在攻击机编译好上传 启动&#xff0c;123456是设…