> 圣杯布局的核心
自适应位置不同,会不会导致最终实现方案不同,我们通过代码验证一下。
通过基础代码[html和css代码,宽度和背景色]。
拆解。三列。先实现 两列(定宽+自适应)。然后在实现两列(自适应+定宽)
效果:中间是自适应了。但是最后一列,折到第二行了。
原因就是因为中间一列,和最后一列的问题。兄弟元素中,中间没浮动,右边的浮动。
A.浮动的元素是不允许超过前面的元素的。所以依旧是垂直方向排列,而不能呈现水平方向
B.不动的元素是不允许超过前面的元素的。所以依旧是垂直方向排列,而不能呈现水平方向
吐字不清还是我耳朵没听清呢。不知道说的是A还是B。
前面浮动,后面不浮动,后面是可以向前占有位置的。根据这句来说,可以推理出来,应该说的是B。
推理:前面不浮动,后面浮动。前面不能覆盖后面,是没覆盖啊,所以折到第二行也是对的。所以还是不太明白。
剖析结果:浮动在前面没事,不会折行,后面就不行。那就想法儿把浮动放在前面。
解决的方法就是,改动下html的结构,将right改到center的前面去。
> 总结
尽管这种三列布局,和之前的三列布局不一样,但用的处理办法还是曾经用过的两列布局的招数,依旧沿用的是之前的解决方案。只不过进行了拆分,然后重新进行了整合和调整,最终依旧可以实现了这种情况。【感受:真的是将已经会的,然后重新组合拆分,好像真的能焕发新的生命力。推陈出新,也就是这个意思吧。所以不能单纯一味的相信喜新厌旧,因为旧的东西用好了,也是可以发挥很大能量,解决更多新问题,实现新功能的。】
缺点:
能实现不就好了吗,但不行,还要考虑另外一种情况。我们做网站,都需要被搜索引擎抓取
center自适应的放在了最后面。但搜索引擎是按照解析html的顺序来抓取的,也就是谁在前,优先抓取谁。
但页面的主要内容都在center,却在最后才被抓取。对搜索引擎并不友好,真正友好的应该是放在left和right的前面。
但如果真的是 center放在第一个的话【由于html的结构顺序改了,导致页面的布局也改变了】
布局就成了 center中间独占一行,然后left,right左右两列都被折到第二行了。
当前的center也只能放在最后了。
因此,当页面的结构不同的话,解决方案也是不同的。这块儿在实际开发中,一定要注意。
> 圣杯布局
- 概念:也叫三行三列。
需要注意的是这个”三列“,一般多出现在第2行中。
圣杯布局的示例,其实是一个完整页面的布局。
三行,可以用3个div,div本来就是垂直方向排列
三列,和之前讨论的三列布局有些不同。不同在自适应这一列出现的位置上。
之前讨论的三列布局是定宽+定宽+自适应,也就是自适应是在左边还是右边(可以试试看,示例中,自适应是在右边,自己可以试试自适应在左边该如何写),而现在这个布局,自适应是在中间的,也就是可以总结为,定宽+自适应+定宽的情况。
疑问:仅仅是位置变化了。影响应该问题不大吧?
还真不是,位置不同,实现方式方案整个就完全不一样了。
圣杯布局最核心的是指三行三列的第二行的三列【左右定宽+中间自适应】的具体实现。
圣杯的解决重点就是三列问题,只不过是对应自适应在中间的这种情况。
这个重点搞定了。圣杯布局也就算是学会了。
- 特点。
自适应处在中间,而非两边。
> 三列布局的实现方式
- 代码验证
先3列统一设置高度。左中设置定宽。右边只设置背景色,默认是width:100%自适应。
如果换成4列布局[也就是最后一列自适应,第三列还是定宽这类]的话,方案依旧可适用。
学习要摸索规律,举一反三。多多思考。
> 三列布局。
-概念:左边两列定宽,右边自适应。
差异点,相比两列布局,只是增加了一个定宽的列而已。复杂度没有增加多少。
-实现方法,仍然有3种方式。定宽+定宽+自适应。
除此之外,还有 定宽+自适应+定宽的这种情况,区别就在于
自适应是在两边,还是在中间排列。
如果是中间的话,就变得相对复杂了。
> 两列布局的第三种解决方案优缺点
- 优点
浏览器兼容性好
- 缺点
但会收到table的制约。宽度自动分配。会出现表格单元格双边框的问题。
解决方法就是通过parent元素上设置table-layout:fixed。
- 总结
第一种方法能用。但问题比较多。
第二种方法问题少很多了。
第三种更优一些。
讲解方式上可以认为是递进的,但实际开发中其实没太大关联,还是要分场景应用合适的方法。
> 两列布局的第三种解决方案
- 概述
html=>有一个变化,会在left和right外围增加一个parent父级元素。
css =>parent应用table效果,left/right左右应用表格的td单元格效果。left左侧定宽。
- 逻辑梳理
但是右边right没有width。解决是width为100%(为啥要显式声明呢?)。
table-layout:fixed(留个思考题,是干啥的。)
解决:table特性-表格的单元格的宽度会自动分配,也就是说没有设置width值的时候,单元格的width会等分。如果有一列定宽,则将其余宽度自动分配给另一列。
> 两列布局的第二种解决方案的优点和缺点
优点:
简单易用。没有第一种方案的3个bug问题。
缺点:
overflow开启BFC,同时还处理了内容溢出。会导致溢出内存想显示但却显示不了的问题。同时一个元素开启浮动,同级的另一个元素不开启浮动,老版本浏览器会出现之间有空白区域浏览器兼容性问题【留悬念,用IETest试试。结论是不存在此问题。但还是值得一试,印象会更深刻。】
> 两列布局的第二种解决方案
* 概述
- html结构:还是两层结构,1个父级,2个子集元素。
- css代码:float和overflow
* 验证
- 大概思路:左侧left定宽,右侧right自适应width:100%(默认值如此,可以不用设置),然后左侧left 设置浮动float,此时看似已经实现左右两列布局,但实际左侧left覆盖了右侧自适应right的部分布局(也就是右侧自适应被左侧挡住的那部分),解决方法是设置右侧自适应right的overflow为hidden。
- 主要核心点是overflow。表示一初始隐藏。但还有另外一个作用。就是 开启BFC模式。
- 开启BFC:也就是说当前元素的内部环境与外界完全隔离,即内部环境和外界完全没关系了。需要注意的是开启BFC模式的,不仅仅只通过overflow:hidden这一种方式。
* 总结
- 和第一种解决方案的相似之处是简单易用。只是将margin-left改为overflow而已。
> 两列布局的第一种解决方案的优化版
- 目的:fix第一种解决方案的缺点。
缺点1-left开启浮动,right不开启浮动,浏览器兼容性不好,老版本浏览器里,两个元素会产生空白区域。
缺点2-
缺点3-
- 做法:
为自适应元素定位父级元素(right这一层,外围再包一层right-fix),然后给right-fix设置float:right,同时宽度width默认100%,也就是自适应。这样就保证了兄弟节点元素都是浮动。——
执行1设置right-fix浮动后,会导致默认宽度值为0。也就是说,right-fix设置浮动后,默认宽度就不是父级的百分百了,而是(后代元素之和)实际内容填充起来的。比如后代元素设置了margin-left:400,所以right-fix的宽度就为400(这点真挺神奇,不设置width,只设置margin也可以给父级设置宽度)
处理2的问题,就是为right-fix显示声明宽度width为100%,也就是父级元素的百分百宽度。
但是会最终显示right的背景色,因为存在颜色覆盖的问题。right-fix的宽度自适应父级body的总宽度,然后right的宽度自适应父级right-fix的宽度,最终显示为right的颜色。right-fix相当于确定了位置,而right确定了最终显示的背景色。如果把right背景色注释掉,则会看到right-fix设置的背景色就显示出来了。证明了的确是颜色覆盖了。
但是两列布局还是不对,水平排列还是错显示为垂直排列。因为设置浮动后,div就不是默认的文档流排列规则(默认是水平排列)了。right的宽度复用了body的宽度,一行放不下了,被挤到下一行了。
解决5被挤到下一行的办法是设置margin-left。水平方向设置负值,表示向左移动,正值右移。不过同样左移的宽度值依赖于left的宽度。
执行6发现,左右两列布局,最后只剩下右列的父级元素了。原因在于被覆盖了?右列父级的层级高于左列?但是说不太过去啊,不是已经设置margin-left了吗?margin-left不会导致背景缩减吗?看来不会,背景色不是在右侧子集right设置的,而是在设置左移的右侧父级right-fix里面的,也就是margin-left和background-color同时设置的话,不会导致宽度发生变化。【这块儿不是太懂,需要自己实际再试试,不过好的地方是,引发自己的好奇心,一个小小的左右两列布局,就出这么多幺蛾子,一波未平一波又起的,挺有意思的。】
解决7右侧父级元素层级覆盖左侧导致左侧无法正常显示的问题的办法是设置z-index(我的想法应该也有效,老师的做法是设置左侧left元素的position值为relative,可以提升显示层级。为何能提升呢?原因不是很清楚。老师的解释是,定位position的显示层级 高于浮动float。怎么证明呢?就看是否7的左侧left无法显示被解决就可以了。)
目前来说,相比第一种解决方案,多了一层right-fix元素,以及基于当前场景下的css polyfill。但好处是,解决了一个浮动,一个不浮动的布局不一致问题。右侧左移的固定宽度还是要依赖左侧width,依旧没解决;如果右列right里面定义子集元素inner,并且子集元素inner设置clear:both(外加background-color:greeen,目的是更容易看效果,方便调试,还是看不到效果,因为inner没有设置高度height),是否会影响左右布局塌陷错位。目前来说,不受影响。
总结来看。3个问题,解决掉2个。只剩下width宽度高耦合的问题了。但是为了解决问题,付出的代价也是比较大的,多增加了不少代码。我自己的感受就是,CSS很强调的能力是就事论事,抓住问题,然后一个一个处理。想形成套路,不那么容易,只能碎片化一个个掌握小技巧,然后根据实际场景,逐个击破,打游击战,组合拳。
> 两列布局的第一种解决方案优缺点。
- 优点:简单
- 缺点:
1.自适应值要依赖于定宽的宽度,改动不灵活,高耦合;
2.定宽元素浮动与自适应元素不浮动处在两个不同层次,导致浏览器兼容性不好,两个元素之间会有空白区域;
3.不在同一层级的元素设置clear:both清除浮动时,会有影响。比如right下的inner设置清除浮动,会影响left的浮动。
- 启示:方法越简单,其影响产生的问题也是相对较多的。
> 两列布局的第一种解决方案
- 结构:parent + left和right
css: float+margin-left
- 代码验证
左侧浮动float脱离文档流,右边左侧保持距离margin-left:左列的宽度。
> 两列布局的第一种情况
- 概念:什么是两列布局(一类定宽,一类自适应)
- 实现方式:3种实现方式~4种
> 多列布局。
居中布局-水平,垂直,水平垂直居中。这3类布局方式。
块级元素,内联元素,行内块级元素。
- 分类(变化最复杂,CSS3多列布局属性)
两列布局(定宽[固定值]+自适应[剩余的列])
三列布局(定宽定宽自适应;定宽自适应自适应,圣杯之后是双飞翼)
等分布局。
等高布局。
> 垂直居中的第二种解决方案
- 概述
父子结构的元素+css样式(absolute+transform)
垂直移动translateY,向上移动是负值,向下移动是正值。
和水平居中的其中一个解决方案很类似。
> 垂直居中布局的第一种解决方案的优缺点
- 优点
没想过。反正是能实现就行。利用display转变成表格的单元格,然后设置verticle-align文本对齐方式为middle垂直居中,打的一套组合拳。
老师的回答:浏览器兼容性比较好,因为table-cell和verticle-align都是css2中就已经有的。对于老浏览器普遍都支持。
- 缺点
没想过,应该没啥缺点吧。
老师的回答:verticle-align属性具有继承性,导致父级元素的文本也是居中显示的。也就是说,将来在遇到 父级元素中包含除子集元素以外的文本内容的话,但是这些文本内容不需要居中的话,此时就不适合用这种方案了,或者说需要为当前方案增加polyfil,去调整文本内容的对齐方式。
>垂直居中布局的第一种解决方案
- 概要分析
dom设置:父子级嵌套
css设置:display(table-cell)和verticle-align(middle)
差异点(相比之前的水平垂直居中方案来说),设置样式在父级元素上,子集样式无需设置
-方法生效原因解析
自我分析:块级元素+居中文本对齐?不太明白
老师解释:
verticle-align-文本内容的垂直方向对齐方式,常用3个值,top顶部对齐,middle居中对齐,bottom,底部对齐。
table-cell:td[单元格](设置当前元素为<td>元素),table:table元素[表格]
整合一下去理解:相当于把父级元素设置为了表格中的单元格,单元格的内容只可以有2种方式[水平/垂直]对齐的[这点待验证];而verticle-align的middle则相当于设置了垂直居中。
>垂直居中布局
- 概念/定义:
自我理解-就是让自身上下居中的一种布局设置方式。
- 实现方式:提供2种解决方案
自我理解:能想到的就是height和line-height等值,以及verticle-align的等值(兄弟节点及父级元素设置)
> 水平居中的第三种解决方案的优点和缺点
- 优点:
没想过。如果现在想想的话,我的答案是相比第二种解决方案来说,可以抵抗float布局的影响,不至于设置float布局后,margin失效,就导致方案不可用。容错性更好些。——这个理解,跟老师的总结差不多。看样子是明白了。
反思补充:开启定位就相当于脱离文档流,这点我倒是没有融会贯通想到,脱离文档流的意思是啥?就是指高度塌陷吗?那是不是先用第二种方案实现一下水平居中,然后设置float布局,或者设置开启定位(绝对定位absolute,fixed固定定位),效果应该是一样的 ,都会令子集元素的水平居中效果失效。待制作demo验证。
老师的回答:父级元素是否脱离文档流,不影响子集元素的水平居中效果。
- 缺点:
没想过。如果现在想的话,我觉得没啥缺点。就是写平移的时候,用成百分比更好,这样即使后续子集元素width宽度改动后,平移不用跟着改。
老师的回答:transform属性是CSS3中新增的属性,浏览器支持情况不好。
反思补充:浏览器支撑情况,我觉得如果不考虑IE8的话,一般浏览器都支持。再者还是可以找找看,有没相关的polyfill,也不算太大问题。这其实涉及到一个决策识别。如果要支持老版本浏览器的话,就不能采用第三种解决方案了,而是要采用第一种或者第二种解决方案了。
- 遗留的思考题:
能否举一反三的,通过这3种,想到第4种,第n种呢。——这个等我把3个搞清楚了,再来好好整理想想。
> 水平居中布局的第三种解决方案:
- 方法拆分:
html:两层结构【父子级】
css:子集-absolute,left和transform;父级-开启定位 [除static外都是开启定位]
- 详细说明
1.开启absolute后,需要判断直接父级元素是否开启定位,如果开启,当前元素就是 相对于父级元素定位,也就是说,天花板是他的父级元素;如果直接父级元素没有开启定位,那当前元素就是 相对于页面定位的【其实这点我觉得仅适用于当前例子,如果body和直接父级节点还有包含节点的话,比如父级的父级节点,如果开启定位的话,那就不是相对页面定位了,而是父级的父级节点了。这点待补充例子证明】
2.translateX 表示平移, X表示水平方向的平移,左移动就是负值,右移动就是正值。想左边移动子集元素的一半,那就是子集元素width的一半即可。
3.子集元素的平移写法,可以写具体值,也可以写百分比。当宽度变的时候,平移如果写具体值的话,也需要跟着变,这时候用百分比-50%【如果平移一半的话】,那无论子集元素的width如何变,平移的设置都不用跟着改了,相对来说,代码更优。
> 水平居中布局的第二种解决方案
1.优点
没想过。
老师的回答:只需要对子集元素设置样式即可。更简单。相比第一种父级,子集,都需要设置来说,要简单很多。
2.缺点
没想过。
老师的回答:如果子集元素脱离文档流,导致margin属性的值无效。
补充:导致脱离文档流的3种场景。
1)浮动float
2)绝对absolute定位
3)固定fixed定位
3.总结
第一种和第二种都有优缺点,所以没有绝对的好,绝对的不好。还是要择机而动,根据场景不同,来选择合适的方案。
>水平居中布局的第二种解决方案:
- 和第一种的差异:只需要在子集元素中设置样式,而非父级,子集元素都设置。
- margin属性外边距的4个值。
技术实现分析:
1.margin: auto 表示根据浏览器自动分配
2.display: table/block,但是不能为inline。
但是对于第2点,我个人觉得inline-block应该也是可以的。因为inline-block也具有block的特性。但实际测试了下,是不行的。可能因为也属于inline,所以不行。可以得出结论是margin:auto这种方式,必须配合块级元素,不能是内联块级,或者是内联元素。
水平居中布局的第一种解决方案优缺点:
1.优点:
没想过这个问题。都是想的能实现就完了,而且实现的也不明不白的。
老师的回答:IE6-9,css2(text-align和display:inline-block),浏览器兼容性比较好
2.缺点:
没想过。
老师的回答:text-align有继承性。子集元素也会应用父级对齐方式。子集元素如果不想继承,需要重置覆盖父级元素的样式【多加一行代码,比如子集元素左对齐,text-align:left】
3.为啥要知道优缺点?
没想过。
老师的回答:搞清楚优缺点,是为了识别场景后,用上合理的解决方案,没有最好和最坏,而非生搬硬套过去,然后用的不明不白,糊里糊涂。
> 水平居中布局的第一个解决方案
技术点:text-align:center(父级元素) + display:inline-block(子集元素)
技术说明:
text-align针对的是文本内容
inline内联元素,也属于文本内容。
之所以设置为inline-block,是因为inline下的width和height是无效的。
简要概括:
组合拳,父容器设置text-align,子容器设置文本且支持宽高尺寸设置display:inline-block。
相当于是 text-align和inline的组合拳。inline-block相当于是一次polyfill补丁。
> 水平居中布局的概念:
当前元素相对于谁水平居中。可以是页面,也可以是父级元素。核心是左右方向放中间。
>水平居中布局:
-我知道的:
1.块级元素:margin:0 auto;
2.行内元素:text-align:center
-课程中讲的(常用的有3种,但不止这些):
inline-block+text-align配合(其实跟"我知道的2"差不多,只不过是用css定义元素类型为内联元素了。)
table+margin属性配合使用(其实跟"我知道的1"差不多,只不过是用css定义元素类型为块级元素了。)
absolute+transform配合使用(这个其实也知道,但是就是用的不太熟,百分比还是/2的数值应用在哪个样式,老是整不明白)
居中布局分类,3种:水平,垂直,水平+垂直
> 布局为何头疼:难
原因1:逻辑性及设计感强
原因2:不能debugger代码定位(语言开发,比如JS,可以跟代码)
原因3:没有套路规律可行
> 布局不是技术内容(html和css),而是一种设计思想(活学活用,而非只是语法堆砌)
需要不断练习,才能融会贯通
float + margin
两列布局的方式
absolute + transform 实现垂直居中
display:table-cell vertical-align 垂直居中