【CSS/HTML】圣杯布局和双飞翼布局实现两侧宽度固定,中间宽度自适应及其他扩展实现

news2024/9/28 17:36:06

前沿简介

圣杯布局和双飞翼布局是前端重要的布局方式。两者的功能相同,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局

圣杯布局来源于文章In Search of the Holy Grail,双飞翼布局来源于淘宝UED。

两者的实现方式有差异,但是都遵循以下几点:

  • 两侧宽度固定,中间宽度自适应
  • 中间部分在DOM结构上优先,以便先行渲染
  • 允许三列中的任意一列称为最高列
  • 只需要使用一个额外的<div>标签

圣杯布局

DOM结构

<div id="header"></div>
<div id="container">
  <div id="center" class="column"></div>
  <div id="left" class="column"></div>
  <div id="right" class="column"></div>
</div>
<div id="footer"></div>

主体由container包裹center、left、right三部分,其中的center在最前面,优先渲染。

CSS代码

假设左侧固定宽度200px,右侧固定宽度150px,在container上设置如下样式:

#container {
	padding-left: 200px;
	padding-right: 150px;
}

目的就是给左侧以及右侧预留出空间,得到如下示意图:
image

随后为左中右三列设置浮动与对应的宽度,同时为底部footer设置清除浮动。

#container .column {
  float: left;
}

#center {
  width: 100%;
}

#left {
  width: 200px; 
}

#right {
  width: 150px; 
}

#footer {
  clear: both;
}

得到如下示意图效果:
image

由于center设置了宽度100%,所有左侧left跟右侧right被挤到了第二行。

如果要把left放到预留的位置,那么需要使用负外边距,代码如下:

#left {
  width: 200px; 
  margin-left: -100%;
}

得到如下示意图效果:
image

由于margin-right: -100%占据叠到了center列左侧,那么需要用定位并且设置right的值为left列的宽度才能放到左侧预留的位置,代码如下:

#left {
	width: 200px;
	margin-left: -100%;
	position:relative;
	right: 200px;
}

这样后得到的示意图效果:
image

接下来对right列进行设置,代码如下:

#right {
	width: 150px;
	margin-right: -150px;
}

最终的示意图效果:
image

到这儿页面的基本样式完成。但是我们需要考虑页面的最小宽度,由于两侧有个固定宽度,感觉最小宽度就是200+150=350px,但是由于left列使用了定位position:relative,所以center列至少有个left设置的right值的宽度,即200px,所以最终的最小宽度是:200+150+200=550px。

body {
  min-width: 550px;
}

那么圣杯布局的整体CSS代码如下:

body {
  min-width: 550px;
}

#container {
  padding-left: 200px; 
  padding-right: 150px;
}

#container .column {
  float: left;
}

#center {
  width: 100%;
}

#left {
  width: 200px; 
  margin-left: -100%;
  position: relative;
  right: 200px;
}

#right {
  width: 150px; 
  margin-right: -150px; 
}

#footer {
  clear: both;
}

为了看到效果,贴一个完整示例代码,有模块的背景色:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>圣杯布局</title>
<style type="text/css">
html,body {
	margin: 0;
	padding: 0;
	height: 100%;
}
body {
  min-width: 550px;
}
#header,#footer {
	background: #4d4d50; 
	height: 40px;
}
#container {
	padding-left: 200px;
	padding-right: 150px;
	height: calc(100% - 80px); 
}
#container .column {
	float: left;
}
#center{
	width: 100%;
	height: 100%; 
	background: #c3c3cd; 
}
#left {
	width: 200px;
	position:relative;
	margin-left: -100%;
	right: 200px;
	background: #2e2eec; 
}
#right {
	width: 150px;
	margin-right: -150px;
	background: #0adf23; 
}
#footer{
	clear:both;
}
</style>
</head>
<body>
<div id="header"></div>
<div id="container">
  <div id="center" class="column">中间内容</div>
  <div id="left" class="column">左侧内容</div>
  <div id="right" class="column">右侧内容</div>
</div>
<div id="footer"></div>
</body>
</html>

双飞翼布局

DOM结构

<div id="header"></div>
<div id="container" class="column">
<div id="center"></div>
</div>
<div id="left" class="column"></div>
<div id="right" class="column"></div>
<div id="footer"></div>

双飞翼布局的DOM结构与圣杯布局的区别是用container仅包裹住center,另外将.column类从center移至container上。

CSS代码

跟前面思路一样,设置各列宽度与浮动,为左右两列预留出空间,以及底部footer清除浮动,代码如下:

#container {
  width: 100%;
}

.column {
  float: left;
}

#center {
  margin-left: 200px;
  margin-right: 150px;
}

#left {
  width: 200px; 
}

#right {
  width: 150px; 
}

#footer {
  clear: both;
}

left放到预留位置左侧:

#left {
  width: 200px; 
  margin-left: -100%;
}

right放到预留位置右侧:

#right {
  width: 150px; 
  margin-left: -150px;
}

最终计算页面的最小宽度:200+150=350px;虽然左侧没有用到定位,但是如果页面的宽度小于350px,那么会挤占中间center的宽度,故设置页面最小宽度为500px,代码如下:

body {
  min-width: 500px;
}

双飞翼布局的完整CSS代码:

body {
  min-width: 500px;
}

#container {
  width: 100%;
}

.column {
  float: left;
}
        
#center {
  margin-left: 200px;
  margin-right: 150px;
}
        
#left {
  width: 200px; 
  margin-left: -100%;
}
        
#right {
  width: 150px; 
  margin-left: -150px;
}
        
#footer {
  clear: both;
}

为了看到效果,也贴一个完整示例代码,有模块的背景色:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>双飞翼布局</title>
</head>
<style>
	html,body {
		margin: 0;
		padding: 0;
		height: 100%;
	}
	body {
	  min-width: 500px;
	}
	#header,#footer {
		background: #4d4d50;
		height: 40px;
	}
	#container {
		width: 100%;
	}
	#center {
		margin-left: 200px;
		margin-right: 150px;
		background: #c3c3cd;
	}
	.column {
		float: left;
	}
	#left{
		width: 200px;
		margin-left: -100%;
		background: #2e2eec;
	}
	#right {
		width: 150px;
		margin-left: -150px;
		background: #0adf23;
	}
	#footer {
		clear: both;
	}
</style>
<body>
<div id="header"></div>
<div id="container" class="column">
<div id="center">中间内容</div>
</div>
<div id="left" class="column">左侧内容</div>
<div id="right" class="column">右侧内容</div>
<div id="footer"></div>
</body>
</html>

扩展实现

如果去掉额外添加的<div>标签,也能实现相同的布局。

DOM结构变化为如下:

<div id="header"></div>
<div id="center" class="column"></div>
<div id="left" class="column"></div>
<div id="right" class="column"></div>
<div id="footer"></div>

基于双飞翼布局的实现思路,只需要在center上做出修改。

1.使用calc()

.column {
  float: left;
}
#center {
  margin-left: 200px;
  margin-right: 150px;
  width: calc(100% - 350px);
}
#left{
	width: 200px;
	margin-left: -100%;
}
#right {
	width: 150px;
	margin-left: -150px;
}
#footer {
	clear: both;
}

2.使用border-box

.column {
  float: left;
}

#center {
  padding-left: 200px;
  padding-right: 150px;
  box-sizing: border-box;
  width: 100%;
}

需要注意的是:由于padding是盒子的一部分,所以padding部分会具有中间栏的背景色,当中间栏高于侧栏时,会出现中间背景色出现在侧栏下面中。

3.使用flex

DOM结构如下:

<!-- DOM结构 -->
<div id="container">
  <div id="center"></div>
  <div id="left"></div>
  <div id="right"></div>
</div>

CSS代码:

#container {
	display: flex;
}
#center {
	flex: 1;
}
#left {
	flex: 0 0 200px;
	order: -1;
}
#right {
	flex: 0 0 150px;
}

参考地址:

  • 《圣杯布局和双飞翼布局的理解与思考》
  • 《CSS布局奇淫巧计之-强大的负边距》

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

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

相关文章

Java文件上传同时传入JSON参数

前言 此篇文章用于解决一个接口内同时完成文件的上传及JSON参数的传入(生产环境已验证); 1.准备接口 import cn.cdjs.vo.UserVO; import cn.hutool.json.JSONUtil; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFi…

黑马头条day4 自媒体文章自动审核

阿里云内容安全调用 其实这个接口调用不是很难 但是需要花钱 就没买 我开了按量计费 但是还是不行 所以就没测试 于是尝试自己写返回成功值 效果不好 后来发现不如直接在函数里边取消调用文字和图片审核 这样更简单 远程调用与降级处理 这里有个bug调试了好久 第一个就是总…

C++面试题第一弹

TCP、UDP区别及使用场景 从TCP和UDP的特点来看&#xff0c;连接性&#xff0c;可靠性&#xff0c;以及面向字节流还是数据报来说。 区别&#xff1a; 连接性&#xff1a;TCP面向连接&#xff0c;而UDP无连接。对TCP来说&#xff0c;在数据传输之前&#xff0c;通信双发需要…

gradle镜像配置

当我们在Android Studio中新建项目或者打开已有项目时&#xff0c;会下载gradle文件&#xff0c;当使用官方的下载源时很慢&#xff0c;经常会下载失败&#xff0c;国内我们可以使用腾讯或者阿里的镜像&#xff0c;一般下载速度很快。 一、gradle下载地址 官网地址&#xff1…

02——springboot2——热部署

什么是热部署 简单说就是你程序代码修改了&#xff0c;现在要重新启动服务器才能加载刚刚新写的代码&#xff0c;如果每次修改代码都要重新启动服务器&#xff0c;这样就真的太麻烦了&#xff08;运行一些稍微较大的项目&#xff0c;运行时间是很长的&#xff0c;所以每次修改…

docker - 镜像操作(拉取、查看、删除)

文章目录 1、docker search --help&#xff08;用于显示 Docker 搜索命令的帮助信息&#xff09;2、docker pull&#xff08;拉取镜像&#xff09;3、docker images (查看镜像)3.1、docker images --help&#xff08;用于显示 Docker 镜像管理相关命令的帮助信息&#xff09;3.…

【C++】——vector深度剖析模拟实现

低头赶路&#xff0c;敬事如仪 目录 1、模拟vector 1.1底层结构 1.2构造析构 1.3尾插扩容 1.4迭代器 1.5增删查改 1.6模拟中的注意事项 2、vector模拟补充 2.1迭代器区间构造问题 2.2memcpy深浅拷贝问题 2.3动态二维数组的模拟及遍历 1、模拟vector 想要模拟实现自…

即梦PixelDance:从追赶到领跑,一跃成为全球AI竞赛的领航者!

今年2月份&#xff0c;OpenAI发布了全新的文生视频模型Sora&#xff0c;那一次的发布&#xff0c;成功开启了AI视频生成的ChatGPT时刻。 看到Sora的发布视频&#xff0c;我相信有很多小伙伴和我一样被深深得震撼了&#xff01; 只需一个指令就可以生成一段逼近真实的视频&…

NBOUND 2024:与AI 一起推动业务增长

在2024年&#xff0c;我们的企业有幸参加了INBOUND大会&#xff0c;这是HubSpot为期三天的动态会议&#xff0c;专注于探讨营销、销售和人工智能领域的最新趋势和策略。作为HubSpot的合作伙伴&#xff0c;我们在这里不仅学习和分享&#xff0c;更见证了如何通过AI推动增长的无限…

【DAY20240926】智能时隙选择器

文章目录 要点元模型和本地模型的关系lstm模型更新Q-learning选择策略&#xff1a;ϵ-greedy动作空间&#xff08;&#x1d44e;&#x1d461;&#x1d456;−1∈{add,stay,minus}&#xff09;: 要点 The intelligent time slot selector is composed of a meta model on the …

提升并行效率的Python多处理模块指南

在Python中&#xff0c;multiprocessing 模块提供了强大的多进程支持&#xff0c;能够帮助我们充分利用多核CPU资源来实现并行计算。相比传统的多线程模式&#xff0c;Python的多进程模式更加高效&#xff0c;因为它可以避免Python的全局解释器锁&#xff08;GIL&#xff09;对…

一个超强大的Python数据探索工具

在数据分析的过程中&#xff0c;快速掌握数据集的基本特征是必不可少的一步。虽然 Pandas 提供了方便的 df.describe() 方法来生成数据摘要&#xff0c;但随着数据类型和分析需求的多样化&#xff0c;这一方法的局限性逐渐显现。Skimpy 作为一个新兴的 Python 包&#xff0c;旨…

基于mybatis-plus创建springboot,添加增删改查功能,使用postman来测试接口出现的常见错误

1 当你在使用postman检测 添加和更新功能时&#xff0c;报了一个500错误 查看idea发现是&#xff1a; Data truncation: Out of range value for column id at row 1 通过翻译&#xff1a;数据截断&#xff1a;表单第1行的“id”列出现范围外值。一般情况下&#xff0c;出现这个…

什么是Agent智能体?

你好&#xff0c;我是三桥君 近期&#xff0c;从各大厂商的年度大会到多个大型AI峰会&#xff0c;三桥君明显感受到行业风气的转变。这些会议不仅展示了众多AI Agent的实际应用案例&#xff0c;还有专家们对未来发展的预测。一时间&#xff0c;“Agent”这个词成为了热门词汇&…

Linux(含麒麟操作系统)如何实现多显示器屏幕采集录制

技术背景 在操作系统领域&#xff0c;很多核心技术掌握在国外企业手中。如果过度依赖国外技术&#xff0c;在国际形势变化、贸易摩擦等情况下&#xff0c;可能面临技术封锁和断供风险。开发国产操作系统可以降低这种风险&#xff0c;确保国家关键信息基础设施的稳定运行。在一…

多态的遗留问题以及C++中杂项,C++面试题

C面试题 1.什么是虚函数&#xff1f;什么是纯虚函数 虚函数&#xff1a;在类的继承中&#xff0c;基类中的函数前加virtual声明的函数就是虚函数。 虚函数实现了运行的多态&#xff0c;同一函数调用在不同对象中表现出不同的行为 纯虚函数&#xff1a;在基类中声明但没有实…

树莓派4B+UBUNTU20.04+静态ip+ssh配置

树莓派4B+UBUNTU20.04+静态ip+ssh配置 1.烧录Ubuntu镜像1.1选择pi 4b1.2选择ubuntu server (服务器版,无桌面)20.041.3选择sd卡1.4 点击右下角 NEXT ,编辑设置,输入密码,wifi选CN, 开启ssh1.5 烧录,依次点击“是”,等待完成2 烧录完成后装入树莓派,上电,等待系统完成配…

软件无线电3-微相E316和HackRF实现FM调制解调

前面介绍了基于Matlab、矢量信号器和HackRF One实现射频下的FM调制解调&#xff0c;今天分享的内容是用微相E316替代矢量信号器完成发射工作。注意本文仅用于科研和学习&#xff0c;私自搭建电台属于违法行为。 1.概述 微相E316和HackRF One实现FM调制解调测试框图如1所示&am…

离散化 ---( 求区间和)

什么是离散化&#xff1f; 离散化是将连续的数值范围映射到有限的、离散的数值集合的过程。在许多情况下&#xff0c;数据可能会存在多个重复值或范围较大的连续值。为了简化处理&#xff0c;尤其是处理区间查询和增量问题时&#xff0c;我们可以将这些值转换为一组有限的、唯一…

【重学 MySQL】四十、SQL 语句执行过程

【重学 MySQL】四十、SQL 语句执行过程 select 语句的完整结构select 语句执行顺序SQL 语句执行原理 select 语句的完整结构 SELECT 语句是 SQL&#xff08;Structured Query Language&#xff09;中用于从数据库表中检索数据的核心语句。一个完整的 SELECT 语句结构可以包括多…