面试官:如何实现三栏布局,中间自适应

今天聊点简单的,最近在整理面试题的时候,看到css部分,感觉自己有段时间没有切页面了,正好趁着这个机会好好复习一下,加深一下印象。

如何实现三栏布局 中间自适应?这也是在前端面试官经常会问到的,当你被问到这个它的时候,你的脑子里应该想到什么?给你3秒钟的时间...那必然是最最经典的圣杯、双飞翼布局,这就是实现这个问题最优雅的方式。

既然是三栏布局,我们先创建3个容器:left + middle + right

image.png

接下来就是实现三栏布局的效果,我们先聊一个最简单最好想的方法,使用弹性

先给left和right都设置200px的宽度,再给它们的父容器container设置属性display: flex;这样这三个容器就会自动去到同一行,再给middle容器设置flex:1,这样中间这个容器的宽度就能一直得到全部宽度减去左右两边容器宽度,这个宽度会随着窗口的大小而变化,代码和效果图如下:

 

html

复制代码

<!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; } div{ height: 100px; } .container{ display: flex; } .left,.right{ width: 200px; background: #66a4bd; } .middle{ flex: 1; background: gray; } </style> </head> <body> <div class="container"> <div class="left">left</div> <div class="middle">middle</div> <div class="right">right</div> </div> </body> </html>

1.gif

这个方法看起来是不是很简单,没错它真的非常简单,都不需要动脑子,简简单单两行代码就能搞定。but!它存在一个问题,这个方法是先加载左边容器的,中间容器加载。不知道大家在上网的时候有没有发现过,有些页面左右两边的都是广告,重要内容都在中间,那么当我们如果使用这个方法来布局的时候,最先出来的是广告,那你愿意吗?我们肯定是想先看到中间的主要内容,两边广告什么时候出现谁在意呢?

所以为了优化这个问题,就出现了经典的 圣杯双飞翼 布局,它们的目的就是为了在HTML结构上,中间栏在最前面保证了最先渲染中间提升性能

圣杯布局

既然要保证中间栏最先加载,那就要把middle容器写在前面

 

html

复制代码

<body> <div class="container"> <div class="middle">middle</div> <div class="left">left</div> <div class="right">right</div> </div> </body>

css样式还是先给左右容器宽度200px,高度都一样,给个背景色便于区分:

image.png

第一步:给三个容器的父容器添加padding:0 200px;腾开位置;middle中间容器设置width:100%;此时的宽度继承了父容器的100%;并且给三个子容器都设置float: left;让它们都向左浮动,去到同一行,效果如下:

image.png

此时的页面效果就是第一行位置放不下,左右两个容器被挤到了第二行,其实按道理来说它们应该是在第一行两块红色区域位置的,浮动的效果嘛,大家都能理解吧

第二步:给左右容器相对定位,让它们相对自己原本文档流的位置进行定位

 

html

复制代码

.left{ width: 200px; background: #76d1ea; position: relative; margin-left: -100%; //向左挪动父容器宽度的100% left: -200px; //再向左挪动自身的200宽度 }

image.png

image.png

此时right接替了left原本的位置,同理,这时候只需要给right设置:margin-right: -200px; 那么就实现了我们想要的三栏布局

image.png

完整代码如下:

 

html

复制代码

<!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>圣杯</title> <style> *{ margin: 0; padding: 0; } .container{ height: 100px; padding: 0 200px; } .middle, .left, .right{ height: 100%; float: left; } .middle{ width: 100%; background: gray; } .left{ width: 200px; background: #76d1ea; position: relative; margin-left: -100%; left: -200px; } .right{ width: 200px; background: #76d1ea; position: relative; margin-right: -200px; } </style> </head> <body> <div class="container"> <div class="middle">middle</div> <div class="left">left</div> <div class="right">right</div> </div> </body> </html>

不过这样布局有一个问题就是:有一个最小宽度,当页面小于最小宽度时布局就会乱掉。 “由于设置了相对定位,所以当left原来的位置和right的位置产生重叠时,由于浮动的原因一行放不下就会换行” 。所以布局就被打乱了,使用双飞翼布局就可以避免这个问题。

双飞翼布局

我们先把HTML结构稍微改造一下,在middle容器里面多用了个inner容器

 

html

复制代码

<body> <div class="container"> <div class="middle"> <div class="inner">middle</div> </div> <div class="left">left</div> <div class="right">right</div> </div> </body>

因为已经设置了middle的width:100%,这时候我们只需要设置inner容器为padding:0 200px,我们要的效果同样是把左右两个容器摆放到对应的红框位置

image.png

image.png

接下来left、middle、right同样使用浮动,left设置margin-left:-100%;(父容器的整个宽度),right设置margin-left:-200px;这样便实现了三栏布局的效果,连定位都不使用,且当页面过小时,布局不会乱,效果如下:

2.gif

完整代码如下:

 

今天聊点简单的,最近在整理面试题的时候,看到css部分,感觉自己有段时间没有切页面了,正好趁着这个机会好好复习一下,加深一下印象。

如何实现三栏布局 中间自适应?这也是在前端面试官经常会问到的,当你被问到这个它的时候,你的脑子里应该想到什么?给你3秒钟的时间...那必然是最最经典的圣杯、双飞翼布局,这就是实现这个问题最优雅的方式。

既然是三栏布局,我们先创建3个容器:left + middle + right

image.png

接下来就是实现三栏布局的效果,我们先聊一个最简单最好想的方法,使用弹性

先给left和right都设置200px的宽度,再给它们的父容器container设置属性display: flex;这样这三个容器就会自动去到同一行,再给middle容器设置flex:1,这样中间这个容器的宽度就能一直得到全部宽度减去左右两边容器宽度,这个宽度会随着窗口的大小而变化,代码和效果图如下:

 

html

复制代码

<!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; } div{ height: 100px; } .container{ display: flex; } .left,.right{ width: 200px; background: #66a4bd; } .middle{ flex: 1; background: gray; } </style> </head> <body> <div class="container"> <div class="left">left</div> <div class="middle">middle</div> <div class="right">right</div> </div> </body> </html>

1.gif

这个方法看起来是不是很简单,没错它真的非常简单,都不需要动脑子,简简单单两行代码就能搞定。but!它存在一个问题,这个方法是先加载左边容器的,中间容器加载。不知道大家在上网的时候有没有发现过,有些页面左右两边的都是广告,重要内容都在中间,那么当我们如果使用这个方法来布局的时候,最先出来的是广告,那你愿意吗?我们肯定是想先看到中间的主要内容,两边广告什么时候出现谁在意呢?

所以为了优化这个问题,就出现了经典的 圣杯双飞翼 布局,它们的目的就是为了在HTML结构上,中间栏在最前面保证了最先渲染中间提升性能

圣杯布局

既然要保证中间栏最先加载,那就要把middle容器写在前面

 

html

复制代码

<body> <div class="container"> <div class="middle">middle</div> <div class="left">left</div> <div class="right">right</div> </div> </body>

css样式还是先给左右容器宽度200px,高度都一样,给个背景色便于区分:

image.png

第一步:给三个容器的父容器添加padding:0 200px;腾开位置;middle中间容器设置width:100%;此时的宽度继承了父容器的100%;并且给三个子容器都设置float: left;让它们都向左浮动,去到同一行,效果如下:

image.png

此时的页面效果就是第一行位置放不下,左右两个容器被挤到了第二行,其实按道理来说它们应该是在第一行两块红色区域位置的,浮动的效果嘛,大家都能理解吧

第二步:给左右容器相对定位,让它们相对自己原本文档流的位置进行定位

 

html

复制代码

.left{ width: 200px; background: #76d1ea; position: relative; margin-left: -100%; //向左挪动父容器宽度的100% left: -200px; //再向左挪动自身的200宽度 }

image.png

image.png

此时right接替了left原本的位置,同理,这时候只需要给right设置:margin-right: -200px; 那么就实现了我们想要的三栏布局

image.png

完整代码如下:

 

html

复制代码

<!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>圣杯</title> <style> *{ margin: 0; padding: 0; } .container{ height: 100px; padding: 0 200px; } .middle, .left, .right{ height: 100%; float: left; } .middle{ width: 100%; background: gray; } .left{ width: 200px; background: #76d1ea; position: relative; margin-left: -100%; left: -200px; } .right{ width: 200px; background: #76d1ea; position: relative; margin-right: -200px; } </style> </head> <body> <div class="container"> <div class="middle">middle</div> <div class="left">left</div> <div class="right">right</div> </div> </body> </html>

不过这样布局有一个问题就是:有一个最小宽度,当页面小于最小宽度时布局就会乱掉。 “由于设置了相对定位,所以当left原来的位置和right的位置产生重叠时,由于浮动的原因一行放不下就会换行” 。所以布局就被打乱了,使用双飞翼布局就可以避免这个问题。

双飞翼布局

我们先把HTML结构稍微改造一下,在middle容器里面多用了个inner容器

 

html

复制代码

<body> <div class="container"> <div class="middle"> <div class="inner">middle</div> </div> <div class="left">left</div> <div class="right">right</div> </div> </body>

因为已经设置了middle的width:100%,这时候我们只需要设置inner容器为padding:0 200px,我们要的效果同样是把左右两个容器摆放到对应的红框位置

image.png

image.png

接下来left、middle、right同样使用浮动,left设置margin-left:-100%;(父容器的整个宽度),right设置margin-left:-200px;这样便实现了三栏布局的效果,连定位都不使用,且当页面过小时,布局不会乱,效果如下:

2.gif

完整代码如下:

 
<!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>圣杯</title><style>*{margin: 0;padding: 0;}.container{height: 100px;padding: 0 200px;}.middle, .left, .right{height: 100%;float: left;}.middle{width: 100%;background: gray;}.left{width: 200px;background: #76d1ea;position: relative;margin-left: -100%; left: -200px; }.right{width: 200px;background: #76d1ea;position: relative;margin-right: -200px; }</style>
</head>
<body><div class="container"><div class="middle">middle</div><div class="left">left</div><div class="right">right</div></div>
</body>
</html>

给个图便于大家理解

image.png

总结

两种布局方式都是把主要栏放在文档流最前面,使主要栏优先加载

相同之处 :让三列浮动,然后通过负外边距形成三列布局

不同之处 在于如何处理中间主列的位置:

  • 圣杯布局是利用父容器的左、右内边距+两个列的相对定位;
  • 双飞翼布局是把主列嵌套在一个新的父级块中并利用主列的左、右外边距进行布局调整

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

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

相关文章

unity 利用Graphics.Blit来制作图片效果

c# 的代码 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class GraphicsBlitTest : MonoBehaviour {public Texture2D source;//原纹理public Material material;//效果材质public RawImage rawImage;// Sta…

前端实现轮训和长连接

简介 轮训和长连接相关内容可以参考之前的文章消息推送系统。消息推送系统-CSDN博客文章浏览阅读106次。在餐饮行业中&#xff0c;店内应用有pos、厨显屏等&#xff0c;云端应用为对应数据中心。为了实现云端数据和操作指令下发到店内应用&#xff0c;需要有一个系统实现这个功…

【手写数据库toadb】01 开发数据库内核准备阶段-开发环境准备

开发环境 ​专栏内容: 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学习…

配置DNS主从服务器,实现真反向解析

主服务器 [rootbogon ~]# systemctl stop firewalld.service #关闭防火墙 [rootbogon ~]# setenforce 0 #关闭selinux [rootbogon ~]# systemctl restart named #启动dns服务 [rootbogon ~]# vim /etc/named.conf #进入dns配置文件 options {#监听…

udp丢包处理方法

UDP丢包处理方法如下1&#xff1a; 使用前向纠错码&#xff08;FEC&#xff09;技术。通过在发送端添加冗余信息&#xff0c;使接收端能够在收到部分丢失的数据时进行纠错。 使用前向纠错码&#xff08;FEC&#xff09;技术是一种有效的处理UDP丢包的方法。FEC技术通过在发送…

【ARM 嵌入式 编译系列 2.4 -- GCC 编译参数学习 -Wl,--gc-sections 】

请阅读【嵌入式开发学习必备专栏 之 ARM GCC 编译专栏】 文章目录 概述-Wl 选项例子&#xff1a; --gc-sections --gc-sections例子&#xff1a; -Wshadow例子&#xff1a; -Wlogical-op例子&#xff1a; -Waggregate-return例子&#xff1a; -Wfloat-equal例子&#xff1a; -W…

2023年12月 电子学会 青少年软件编程等级考试Scratch三级真题

202312 青少年软件编程等级考试Scratch三级真题 一、单项题 第 1 题 运行左图程序&#xff0c;想得到右图中的效果&#xff0c;红色框应填写的数值是&#xff1f;&#xff08; &#xff09; A&#xff1a;12 B&#xff1a;11 C&#xff1a;10 D&#xff1a;9 第 2 题 下列…

每天都美好的一天

每天我们都会遇到不同的事情&#xff0c;开心的、愤怒的、悲伤的等等&#xff0c;今天过完明天我们还得继续&#xff0c;所以一切又显得不那么重要。一天中如果有不开心的事情发生会影响我们当天很长一段时间&#xff0c;甚至未来几天。 今天所做之事都是自己明天的基础&#…

修改live server的默认浏览器(vscode)

在插件打开设置 修改选定浏览器

VC++中使用OpenCV进行颜色检测

VC中使用OpenCV进行颜色检测 在VC中使用OpenCV进行颜色检测非常简单&#xff0c;首选读取一张彩色图像&#xff0c;并调用函数cvtColor(img, imgHSV, COLOR_BGR2HSV);函数将原图img转换成HSV图像imgHSV&#xff0c;再设置好HSV三个分量的上限和下限值&#xff0c;调用inRange函…

C++实现一个简单的学生管理系统

目录 1.一个简单的学生管理系统简介 2.定义一个 Student 类 2.1用于表示学生信息。 3.定义一个 StudentManager 类 3.1用于管理学生信息。 4.在 main 函数中 4.1使用上述两个类来实现一个简单的学生管理系统 5.C类模板 推荐阅读&#xff1a; calloc与realloc和malloc的…

多线程(看这一篇就够了,超详细,满满的干货)

多线程 一.认识线程&#xff08;Thread&#xff09;1. 1) 线程是什么1. 2) 为啥要有线程1.3) 进程和线程的区别标题1.4) Java的线程和操作系统线程的关系 二.创建线程方法1:继承Thread类方法2:实现Runnable接口方法3:匿名内部类创建Thread子类对象标题方法4:匿名内部类创建Runn…

MySQL TINYINT(1)和TINYINT(2)有什么区别?

文章目录 1.直接建表2.查询数据3.总结 身为程序员&#xff0c;拿事实说话拿代码说话最直观了&#xff0c;show the code 1.直接建表 CREATE TABLE tinyinttest (id int NOT NULL,a TINYINT(1) NOT NULL DEFAULT 0,b TINYINT(2) NOT NULL DEFAULT 0,c TINYINT(1) ZEROFILL NOT…

JSON 基本语法以及在Java 中的使用

文章目录 一、JSON 概述1.1 什么是 JSON1.2 JSON数据类型和语法1.3 JSON 优势 二、使用 JSON2.1 在 Java程序中使用 JSON2.2 Jackson的使用2.2.1 Jackson的简单介绍2.2.2 反序列化2.2.3 序列化 参考资料 一、JSON 概述 1.1 什么是 JSON JSON&#xff08;JavaScript Object No…

Unity下实现跨平台的RTMP推流|轻量级RTSP服务|RTMP播放|RTSP播放低延迟解决方案

2018年&#xff0c;我们开始在原生RTSP|RTMP直播播放器的基础上&#xff0c;对接了Unity环境下的低延迟播放&#xff0c;毫秒级延迟&#xff0c;发布后&#xff0c;就得到了业内一致的认可。然后我们覆盖了Windows、Android、iOS、Linux的RTMP推送、轻量级RTSP服务和RTSP|RTMP播…

VRRP协议负载分担

VRRP流量负载分担 VRRP负载分担与VRRP主备备份的基本原理和报文协商过程都是相同的。同样对于每一个VRRP备份组,都包含一个Master设备和若干Backup设备。与主备备份方式不同点在于:负载分担方式需要建立多个VRRP备份组,各备份组的Master设备可以不同;同一台VRRP设备可以加…

ctfshow信息收集(web1-web20)

目录 web1 web2 web3 web4 web5 web6 web7 web9 web10 web11 web14 web15 web16 web17 web18 web19 web20 web1 根据提示的孩子开发的时候注释没有被及时删除 web2 js原因无法查看源代码 第一种方法 在url前加入 view-source&#xff1a; 会显示页面源代…

【车载HMI开发工具--EB GUIDE 与 Unity 合作提供一体化的沉浸式 HMI 设计开发工具链】【转载】

随着车载高性能计算平台的日益普及以及显示器尺寸和数量的不断增加&#xff0c;沉浸式车载人机交互界面&#xff08;HMI&#xff09;的需求也在持续增长。为了将实时 3D 技术带入车载 HMI 领域&#xff0c;Unity 与 Elektrobit (EB)展开了合作&#xff0c;EB 是推进 HMI 功能安…

数据分析完整流程一般包括哪几个环节/步骤

问题定义&#xff1a; 确定需要解决的问题或目标&#xff0c;明确分析的方向和目的。 数据收集&#xff1a; 收集与问题相关的数据&#xff0c;可以包括从各种来源获取的结构化或非结构化数据。 数据清洗&#xff1a; 对收集到的数据进行清理&#xff0c;处理缺失值、异常值和…

JavaScript 中的事件

1、鼠标事件&#xff1a; 鼠标单击事件&#xff08;click&#xff09;&#xff1a; 方法一 &#xff08;onclick&#xff09; <button id"btn" onclick"alert(88888)">点击弹框</button> 方法二&#xff08;利用addEventListener&#xff09;…