【呆萌の研究】圣杯布局引发对margin负值的研究

智码拓荒者
• 阅读 1588

问题の起源

以前一直就听说圣杯布局,但是没有怎么去用过,然后这次偶然接触到了,就学习了一下。
这是一个我从别人写的文章中复制过来的,关于圣杯布局的比较简单的说明

通过缩放页面就可以发现,随着页面的宽度的变化,这三栏布局是中间盒子优先渲染,两边的盒子框子固定不变,即使页面宽度变小,也不影响我们的浏览

而通常是采用浮动布局和margin负值。

一般の实现方法

HTML结构
首先定义一个主体div,再是left和right的div

<div class="container">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
</div>

CSS部分
1.给container左边和右边赋上padding值,宽度分别就是能容纳的下left和right的div。
2.main DIV的宽度为100%。
3.main,left和right三个div都设置为左浮动。

完成以上我们就会得到一个这样的结果:
【呆萌の研究】圣杯布局引发对margin负值的研究

再然后我们给left一个margin-left:100%,此时会发现left移动到了第一行中:
【呆萌の研究】圣杯布局引发对margin负值的研究

然后面对这个现象,我展开了一系列的思考和探究~

初次の发问

Q:为什么left会跑去了第一行?
A:这个其实我们大概心里是明白的。一开始,main的宽度是100%,所以第一行是无法再容纳后面同样是左浮动的div块。但是通过赋予了margin-left为-100%,这里的100%也就是父容器的宽度,浏览器计算出来是一个负值,就认为它能被容纳在第一行。

继续试验

我们可以尝试改变margin-left的值,去看看div位置的变化。为了方便我们计算,另外写了一个类似的布局,内容区的宽度是100px,三个div的宽度也都是100px。
HTML部分

<div class="container">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div> 
</div>

CSS部分

.container{
  width:100px;
  margin:0;
  padding:0 100px;
  background:rgba(0,0,0,.3);
}

div{
  float:left;
  width:100px;
  height:100px;
}
.main{
  background:rgba(0,0,255,.4);
}
.left{
  background:rgba(233,0,0,.4);
}
.right{
  background:rgba(0,233,0,.4);
}

效果是这样的
【呆萌の研究】圣杯布局引发对margin负值的研究

然后我们试着给left赋予不同的margin-left负值,会发现:
1.当margin-left在0px ~ -99px的时候,left会向左移动。
【呆萌の研究】圣杯布局引发对margin负值的研究

2.当margin-left为-100px的时候,left上移动,与main重叠:
【呆萌の研究】圣杯布局引发对margin负值的研究

所以margin-left是-100px的时候,显然是一个分界点

3.当margin-left的负值继续增加,left又会继续向左边移动:
【呆萌の研究】圣杯布局引发对margin负值的研究

根据上面的情况,加以本宝宝的百度(笑),我们确定了想法,就是在计算元素的"宽度"的时候是会把margin-left+width得到结果,当-100px+100px=0px的时候,就被认为第一行是还可以容纳的下,所以第二行的元素就到了第一行。
此时,我还找到了一篇文章,这篇文章比较合理的阐述了移动的原理:https://www.cnblogs.com/LiveW...

二次の提问

然而这里还有一个细节问题,就是left的移动其实是有一个范围的:
【呆萌の研究】圣杯布局引发对margin负值的研究

画了红框的范围是container的一个padding区域,在left移动切换的时候,
当left的margin-left并没有达到-100px的时候,为什么它会向左移动,单纯从放不下的原理来说,它在原处不动也可以是一个合理的现象,那篇文章似乎也没有提到合理的原因,然后我继续试验。

再次实验

我们从当left的margin-left为-100px开始,即main和left重叠的情况。
我们再给main一个margin-left负值为-50px,结果main和left一起向左边移动:
【呆萌の研究】圣杯布局引发对margin负值的研究

再试验一种情况,把left的宽设为150px,margin-left设为-150px,main的margin-left是0,此时left的右边对齐了main的右边。
【呆萌の研究】圣杯布局引发对margin负值的研究

所以应该隐隐约约可以发现了些什么...

我の小结论

合理的解释就是,在摆放元素位置的时候,它会计算出那个右边的值,并且会认为这就是元素的最后的标准线。

1.解释继续实验中为什么margin-left为left宽度负值,left会和main重叠:
因为它会被认为宽度是0,所以从main的结束位置开始计算是100px+0px,所以元素要以100px为结束线,也就是它在100px的左边。

2.解释再次实验中为什么更改main的margin-left,left会和它一直重叠:
根据1的推断,left的边界线计算结果一直都会是main的边界线。

3.解释为什么left能在第二行向左边移动:
因为它会被认为宽度在1px~99px之间,所以它的边界线是在内容区中宽度为1px~99px之间,所以它能移动。

其实也是我自己的猜想和推论,并不知道实际情况对不对QAQ,但是根据自己的测试情况来说,目前是都说得通的,望大神指点嘻嘻。

点赞
收藏
评论区
推荐文章
秃头王路飞 秃头王路飞
2年前
总结前端元素的各种高度(上)
HTMLElement.clientHeight只读属性Element.clientHeight对于没有定义CSS或者内联布局盒子的元素为0;否则,它是元素内部的高度(以像素为单位),包含内边距,但不包括边框、外边距和水平
浪人 浪人
4年前
Android 代码动态修改RelativeLayout布局
Android代码动态修改RelativeLayout布局前言有时我们会遇到在xml布局文件中设置好界面后,但是又需要从代码中进行动态布局修改。之前从网上寻找了好多资料,看到的都是新建一个布局文件但是我的需求又是从当前布局文件的基础上进行修改。下面用一个示例大家介绍一个比较简单的办
菜园前端 菜园前端
2年前
考考你HTML常用的标签有哪些?
原文链接:基础标签div块元素介绍:没有任何含义,主要用于div进行模块布局类型:块级元素block,盒子占用宽度为一整行属性:没有属性language我是模块span行内文本元素介绍:没有任何含义,主要用于展示文本内容类型:内联元素inline,盒子占用
菜园前端 菜园前端
2年前
想学会flex布局,我强烈推荐你来看看这篇文章!!
原文链接:为什么要使用flex布局?flex布局是目前比较流行的一种布局,因为它十分简单灵活,区区简单几行代码就可以实现各种页面的的布局,以前我在学习页面布局的时候我深受其float、display、position这些属性的困扰。使用flex属性就可以写
菜园前端 菜园前端
2年前
CSS布局方式-静态布局
原文链接:什么是静态布局?静态布局是平时开发中最常见的一种布局。就是给布局的元素设置固定的宽度和高度,无论你的屏幕分辨率是多大,它永远都是固定大小。通常使用px单位来实现静态布局。优点它的优点也比较明显,是一种最简单的布局方式,开发者只需要按照设计图1:1
Wesley13 Wesley13
3年前
CSS定位和滚动条
0805自我总结一.绝对定位position:absolute;/绝对定位:1、定位属性值:absolute2、在页面中不再占位(浮起来了),就无法继承父级的宽度(必须自己自定义宽度)3、一旦定位后,定位的布局方位top、bottom、left、right都能参与布局
Wesley13 Wesley13
3年前
Android ScaleDrawable
顾名思义,Android ScaleDrawable实现一个drawable的缩放。写一个例子。一个线性布局,垂直放几个ImageView,然后依次缩放若干个ScaleDrawable。布局文件:<?xmlversion"1.0"encoding"utf8"?<LinearLayoutxmlns:android"
Wesley13 Wesley13
3年前
HTML CSS布局定位
HTMLCSS布局定位我们在编写网页代码时,首先应该做的就是设计好页面的布局形式,然后再往里面填充内容。网页布局的好与坏,直接决定了网页最终的展示效果。PC端常见的网页布局形式有两列布局、三列布局等。在CSS中,我们通常使用浮动(float)、定位(position)、显示模式(display)相关属性结合使用,以达到预期效果
Wesley13 Wesley13
3年前
CSS定位规则之BFC
技术改变世界!学习改变人生!1. BFC(block formatting context,中文常译为块级格式化上下文)是W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。 在进行盒子元素布局的时候,BFC提供了一个环境,在这个环境中按照一定规则进行布局不会影响到其它环境中的布局。比如浮动元素
Wesley13 Wesley13
3年前
IOS开发
有没有这种需求,自定一个panel,里面放了好几个控件,在多个页面用到这个panel。解决这个问题有三条思路:1.自己继承UIView写一个类,在这里面以代码的形式添加需要的控件,完成布局。2.使用XIB布局文件完成布局3.使用storyboard完成布局在这三中方式中,1显得高端大气上档次,哗啦哗啦敲半天。虽然我是技术控,但是也很反感这
Stella981 Stella981
3年前
ConstraintLayout 约束布局
  约束布局ConstraintLayout  这种布局方式出现已经有一段时间了,刚出现的时候一直以为这种布局只是针对拖拽使用的布局,最近在新项目里看到了这种布局,又重新学习了这种布局,才发现以前真的是图样图森破啊,这种新的布局方式真的太好用了!1.引入使用之前需要添加这种布局的依赖implementation'com.an