前端——正儿八经的CSS布局实战向(三)

写在开头:本篇文章为CSS布局实战向,首先不会考虑IE兼容问题,也不会考虑市场占有率小于0.5%的浏览器及其版本,毕竟就连微软都已经在15年放弃了这一品牌。其次本篇文章,不会过分追求一些原理性问题。例如:为何margin垂直方向防止重叠是BFC条件的子集。况且CSS规则及不同的浏览器的渲染引擎(浏览器内核)都可能会存在小小的BUG

基础知识点梳理

  • 文档流与脱离文档流:即简单粗暴的理解为两种完全不同的“元素”,脱离文档流的元素需要有特定“标识”,而属于文档流的元素是“看不见”脱离文档流的元素,所以两者可能会出现重叠的情况。但是在渲染方面,dom 树上既有文档流也有脱离文档流的元素。
  • display:这个CSS属性在布局当中的影响,可以说是举足轻重的。文档流中,元素基本分为行内元素(display:inline)和块级元素(display:block)两种。display:inline-block既是综合了块级元素与行内元素的特点,也会涉及到BFC布局。display:flex 涉及 flex 布局方式。至于display:none,这一标记可以使该元素暂时不出现在dom 树当中。(与visibility:hidden的差别,可以简单的理解为他会占据页面空间,是会出现在dom 树上面的)
  • margin(外边距)与padding(内边距):margin可以简单的理解为元素与元素之间的间距布局控制,padding则是可以被理解成元素内部内容的布局控制。
  • height(高度):为什么将height单独提出来?CSS规则中对于高度的解释,本人并没有花太多的时间去研究,但是height这个属性一直就挺有意思的。可以简单的理解成,一般情况下浏览器并不知道一个元素的高度内部分配情况。正因为元素的内部情况不清晰,所以margin:auto与margin:0 auto(0不设置单位可提高性能)。 padding-top , padding-bottom , margin-top , margin-bottom 等,当按百分比设定它们时,依据的也是父容器的宽度
  • IE传统盒模型与标准盒模型:盒模型简单的理解,即元素在页面上展示的大小。标准盒模型的宽度=content-box-width(盒内容的宽度);标准盒模型的宽度=content-box-height(盒内容的高度);IE传统盒模型的宽度=content-box-width(盒内容的宽度)+ border + padding;IE传统盒模型的宽度=content-box-heigh(盒内容的高度)+ border + padding;而目前的主流浏览器默认都是IE传统盒模型。

flex布局

2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。个人认为只要不是太过于苛责的兼容性考虑,这种方案是最为方便、“无脑”的布局方式。且距今十年的“检验”,也证明了这种布局方式的优越性。

而对于flex布局 阮一峰老师有着很是详细且清晰的解释,本人就不再重复这些东西了,只简单总结一下如何实际运用及必须要了解的重点。

  1. 简单情况下,我们对于flex布局,首先要做的即确定主轴方向(flex-direction),默认主轴方向为水平方向,从左到右。
  2. 如果你想要的布局即是水平布局,我们就可以进行下一步操作,而如果想要的是垂直布局,即将主轴方向重新设置即可,flex-direction:column。
  3. 在确定了主轴方向之后,我们就可以开始布局了,即主轴(justify-content)与交叉轴(align-items)的对齐方式设置。
  4. 子元素的float、clear和vertical-align属性将失效
  5. 其他的细节部分,如:主轴水平方向从右至左,及order属性等等都不再多做赘述。实在不清楚的部分可以去阮一峰老师的flex 布局那篇文章多熟悉几遍。下面是两个demo?。

例1:横向布局水平排布

html代码:

  <div class="demo">
    <div class="demo-1 demo-0">不建议在标签内写多余类,最好保证所有命名类都会被使用</div>
    <div class="demo-2 demo-0">如果该?是BFC布局</div>
    <div class="demo-3 demo-0">可能就会引起基线问题</div>
    <div class="demo-4 demo-0">这个问题下面的BFC布局会讲到</div>
    <div class="demo-5 demo-0">本篇flex布局不纠结细节原理</div>
  </div>
复制代码

CSS代码:

.demo {
  width: 320px;//其实边框重合问题,会有很多有意思的地方
  height: 300px;//并不是说单纯一个margin负边距就可以解决的
  border: 1px solid transparent;//但是本篇为实战向,且很多“bug”也没必要深究
  display: flex;//我们更应该把时间花到:不同的情况下用怎样的样式布局才合理的。
  margin: auto;//?中布局为视觉效果。
  flex-wrap: wrap;//实际上随着margin的变动,在flex布局中
  justify-content: space-between;//边框与父元素边框仍然会发生重合现象或小于等于1px的空隙
  align-items: center;
  background-color: #faebd7;
  .demo-0 {
    width: 100px;
    height: 100px;
    border: 1px solid;
    display: inline-block;
  }
}
复制代码

例二:竖直方向垂直排布

html代码:

  <div class="demo">
    <div class="demo-1 demo-0">如果非要考虑边框重合问题</div>
    <div class="demo-2 demo-0">不建议使用margin负边距实现</div>
    <div class="demo-3 demo-0">里面涉及到的问题有点多</div>
    <div class="demo-4 demo-0">如果是单行边框重合问题</div>
    <div class="demo-5 demo-0">比较建议的方法是从边框直接入手</div>
  </div>
复制代码

CSS代码:

.demo {
  width: 100px;//对于边框效果,比较建议的是父元素给一个整体边框
  height: 500px;//这样子比较有利于圆角之类的设置
  border: 1px solid;//当然?中子元素的边框还是有不到1像素的空隙
  border-radius: 4px;//眼尖的朋友应该已经发现了
  display: flex;//咳咳,这种像素级的问题,暂时先不去纠结,我们回归到主题,布局当中来。
  margin: auto;//通过这两个?,可以很清晰的感觉到
  flex-direction: column;//flex布局方式,写法相当简单,且“后遗症”较其他方式比少很多
  background-color: #faebd7;//他没有grid那般复杂,当然了grid布局本身就是为了二维布局而生的
  overflow: hidden;//更没有BFC、position、float那般多的破事烦恼,虽然本身仍有像素级“bug”
  .demo-0 {
    width: 100px;
    height: 100px;
  }
  .demo-0:not(:first-child){
    border-top: 1px solid;
  }
}
复制代码

BFC布局

对于BFC布局我们需要了解的就是,BFC到底是什么?这一点相信很多资料都有过说明,我们直接引用概念即可,对于实际运用当中遇到的问题,我们再单独细说。 BFC(Block formatting context)直译为"块级格式化上下文"。与flex布局相同,他的内部也是一个独立的渲染区域。

在目前的MDN当中,更是有人将flex也归到了BFC当中,由于本篇是实战向仍然不去纠结这些概念性问题,对于CSS我目前认为专注实战即可。那么对于BFC,他的实际作用有什么呢?

虽然对于BFC算是看过不少资料了,但是经过实践验证,个人认为,BFC作用即为清除浮动(解决元素浮动而造成父元素坍塌问题),而对于其他的类似解决margin的重叠问题、BFC的区域不会与float box重叠等等,本人并不是很认同。

首先谈一谈常用的且能形成BFC的契机:

  • 根元素或其它包含它的元素

  • 浮动 (元素的 float 不是 none)

  • 绝对定位的元素 (元素具有 position 为 absolute 或 fixed)

  • 非块级元素具有 display: inline-block,table-cell, table-caption, flex, inline-flex

  • 块级元素具有overflow ,且值不是 visible

通过这五个条件,我们再来回头去看BFC的通用作用,若是不把绝对定位这个“妖孽”给排除掉,仅有清除浮动这一作用是被所有BFC所满足的。

而绝对定位这妖孽的地位在我看来,是可以与js当中的函数比肩的。他基本上做到了可以“无视”任一其他元素的地步,无论该元素属于是文档流的,还是脱离文档流的,所以在剩下的情况讨论中,我会故意将他不列为讨论范围当中,仅在定位布局中再进行说明。

在排除绝对定位这一前提条件下,我们再回头看margin重叠问题以及float box重叠问题。

首先margin在水平方向上,本人认为是不存在重叠问题的,所以margin的重叠问题只会发生在margin的垂直方向。那么在什么情况下,margin垂直方向上会发生重叠问题呢?在常见情况当中,两个相邻块级元素之间即会产生margin重叠方向上的重叠问题。

那么解决margin垂直方向上的重叠问题,常见的又有那些?

  • 浮动
  • display: inline-block

嗯~ 其实常见的应该就是这两种,可以看做是BFC的子集,但是若说BFC作用为解决margin的重叠问题,就显得太不严谨了些。

说完水平和垂直方向的margin重叠问题,其实还有一种margin重叠情况的。那便是父元素与子元素的margin重叠问题,由于篇幅问题,且实战向不强本篇暂不做讨论。float box的重叠问题,也是同样的问题,并不是所有的BFC都满足防止float box重叠问题的、但是和margin重叠问题相比,绝大部分的BFC都已经算是可以满足条件的了。

解决float box重叠问题的常见方法:

  • 浮动
  • 常见的非block、inline;display属性值,如display:table、display:inline-block、display:flex等等
  • overflow:hidden、overflow:auto

现在看一个?,主要关于display:inline-block,这个涉及了基线、BFC、IFC的奇特属性来实现排版问题。

图一:

图二:
html代码:

  <div class="demo">
    <div class="demo-1 demo-0">display:inline-block排版中最为重要的</div>
    <div class="demo-2 demo-0">应该就是基线的问题了</div>
    <div class="demo-3 demo-0">而对于基线这一概念,反正本人在总结了不少的资料后</div>
    <div class="demo-4 demo-0">还是有些迷茫的</div>
    <div class="demo-5 demo-0">但是对于实战向应该是可以应对的</div>
  </div>
复制代码

CSS代码:

.demo {
  width: 350px;//图一为“破版”的情况,细心的朋友应该发现了一个规律。
  height: 300px;//display:inline-block的默认对其为基线对其。
  background-color: #faebd7;//基线这个鬼东西,先不去说明,用通俗的话来说
  margin: 0 auto;//所有元素的文字内容的最后一行,默认对齐
  .demo-0 {
    width: 100px;//而与display:inline-block相对应的,便是vertical-align属性
    height: 100px;//其中baseline、sub、super可以简单的理解为基线相关;
    border: 1px solid;//而text-top、text-bottom、middle、top、bottom为元素本身相关
    display: inline-block;//再具象化的理解一下就是,若元素内部拥有行高(文字内容)
    margin-left: 10px;//此时便需要通过text-top、text-bottom、middle、top、bottom属性保证水平方向平行
    margin-bottom: 10px;//这个仅为简单理解应用,实际原理还是有所不同的
    // overflow: hidden;//overflow:hidden这个属性也是有保证元素水平方向平行的能力的
    vertical-align: middle;//其对其方式,建议自行体验印象更加深刻
  }
}
复制代码

定位布局

position(定位)在布局方面的地位,我认为与js中的函数是类似的,皆为“一等公民”。只是对此使用,本人不太建议如函数那般频繁。但是若一时半会遇到了暂时无法解决的布局问题,定位布局总是可以作为“银弹”来使用。

既然position近乎万能,那么我们更需要较为透彻的了解其属性,及常用的使用场景。这样才可以在实战中更加的得心应手。接下面我将从以下几个方面来进行解释。

  • position所包含的常用属性:static | relative | absolute | sticky | fixed
  • 其最为常见且合理的应用场景
  • 与其他任意元素的关系处理

先说第一点,position的常用属性,首先可以将五个属性分为三个派别,static、relative属于文档流;absolute、fixed属于脱离了文档流;sticky这一属性即为相对定位与固定定位的混合(粘性定位),需要指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同

position属性的默认属性即为static,会忽略 top, bottom, left, right 或者 z-index 的声明。而剩下的四种属性,虽然其中的三种都是会给默认left与top值,但是本人不建议使用默认值,因为该默认值可能会导致可读性问题。

原因也很简单,position在不考虑margin:auto的情况下,没有设置left、top时,left和top的默认值将使元素的位置和“原来的位置”一样。再简化一下便是,position当中left与top的默认值并不是0。而对于粘性定位(position:sticky)来说,更是需要明确的指定出阈值的。

再谈第二点,其常见且合理的应用场景。对于大部分时候来说,本人还是秉承着能不用定位就不要用定位的思想,毕竟可以完全脱离文档流的属性,或多或少总会对其他元素产生不小的影响的。但是在有些时候,定位布局绝对是不可或缺的(真香。。)

  • 固定在页面视角的布局情况(固定导航栏),这个时候毫无疑问的,我们的固定定位(position:fixed)老大哥就要出场了,在这里固定定位的作用便是最为合理且常规的。
  • 对于元素大小不定的布局情况(如流式布局),在这种情况下我们当然是可以通过长宽的百分比进行布局的,但是对于一些例如百分比与固定值混合的情况,虽然仍然calc属性可以使用,但是由于其有些令人不爽的兼容性问题和部分渲染引擎的计算方式偏差仍然是存在的,此时就需要我们的绝对定位(position:absolute)与相对定位(position:relative)出手了。一会会通过一个?进行讲解说明。
  • H5页面当中常见的,替换导航栏较炫酷的动画效果切换实现。嗯~,这是属于粘性定位(position:sticky)的领域范畴的,由于篇幅问题及该属性还在测试当中,也就不细说了。建议可以看一下张鑫旭老师对于粘性定位解读吧
  • 部分难以解决的问题,几乎都可以用定位布局来解决,例如:面试题中火过的的双飞翼布局、圣杯布局。

写一个小?,结合常用场景的第二点及第四点。 html代码:

<div class="demo-wrap">
  <div class="demo">
    <div class="demo-1 demo-0"></div>
    <div class="demo-2">
      无论是双飞翼布局还是圣杯布局,虽然名字听上去好像难以理解,
      但归根结底都是属于三栏布局的,
      而对于既不想要破版、而又实用且考虑细微“bug”的实战情况下,
      个人认为其比浮动加margin负边距更加的合理
      此?也算是结合了流式布局的概念,嗯~定位布局就是这般好用(真香)
    </div>
    <div class="demo-3 demo-0"></div>
  </div>
</div>
复制代码
.demo-wrap {
  overflow-x: auto;//给一个外层嵌套,只是为了保证一个滚动条效果
  .demo {
    height: 300px;
    position: relative;//一般来说相对定位都是和绝对定位嵌套使用的
    border: 1px solid;
    min-width: 600px;//与父元素的overflow-x: auto;结合保证滚动条出现
    .demo-0 {
      position: absolute;//虽然定位布局保证了不会破版这个问题
      width: 200px;//但是中间的文字内容部分,由于宽度是通过相对定位实现的,所以想要实现最小宽度
      height: 100%;//只能通过父元素的最小宽度且滚动条来取巧
      background-color: antiquewhite;//一个小小的冷知识点:!important并不是万能的
      top: 0;//至少他大不过min-width、min-height、max-height、max-width这四个属性
    }
    .demo-1 {
      left: 0;
    }
    .demo-3 {
      right: 0;
    }
    .demo-2 {
      position: absolute;//在设置两边定位值时,一定不要给相应的宽度或高度
      height: 100%;//例如设置了left、right就不要设置宽度
      left: 200px;//不然的话,其大小是由宽来决定的,
      right: 200px;
    }
  }
}
复制代码

最后一点:关于定位元素(这里的定位元素指的是完全脱离文档流的元素)与其他元素之间的关系,定位元素的地位,决定了他可以无视近乎所有的任一元素,包括其定位元素本身。而对于定位元素与定位元素之间,若是想要改变其覆盖的上下关系,最好的方法即使用z-index属性。该属性也就是为了定位元素而量身打造的。

浮动布局

其实说句实话,浮动布局已经渐渐有些退出历史舞台的趋势了,论地位,他虽然也算是脱离了文档流的,可还是有诸多限制或者可以说是“bug”,并不如定位布局那般随心所欲。论好用程度,同样是一维布局的flex布局,几乎是方方面面的优势碾压。

而若是论内涵,BFC的磅礴成员与其无处不在的身影,浮动更是无法比拟的。所以浮动布局实际上是处于了一个较为尴尬的地位的,且float box我们还需要考虑多方面的问题,如空间坍塌、不同浏览器渲染下可能产生的布局“bug”等等。

导致了,这个在早期风云一时的布局方法,已经有些跟不上时代的脚步了。不过在一种场景下,float布局却仍然是绝对的“主宰”。那便是围绕效果,这个应该也是当初推出float这一属性的本命任务了。

来一个简单的?吧

html代码:

<div class="demo">
  <img src="assets/images/cssView_pie.png" alt="">
  字围效果即通过float的独特效果,来实现的。而且我相信在float出现之初,
  提出者和设计者都是没有考虑到空间坍塌问题的,原因其实也很简单,若是为了实现字围效果
  本身高度就会被文字内容撑开,又怎么会出现空间坍塌呢?
  其实css这门语言确实会有着各种各样的有意思的问题,可我们要做的不仅是探究其本质,
  更重要的是如何通过权衡来更合理的利用不同的属性来达到我们想要的效果。所以很多不必要的东西,
  无需纠结,而是把时间放在其他更有意义的事情上面。
</div>
复制代码

CSS代码:

.demo{
  width: 300px;
  margin: 0 auto;
  background-color: antiquewhite;
  img{
    float: right;//没错不需要去管空间坍塌问题,即可实现字围效果
  }
}
复制代码

最后说两句:其实很多的CSS概念性的东西都是人为去定义的,并不是说这种方式有这么不好,概念本身就是为了让大家更好的去理解其含义才产生的。所以只要不是根本性的概念问题,我们在实战向当中,更应该把各种各样的概念及总结,转换为自身最能够理解的内容才是最正确的方向。等等~ 好像忘记了什么,grid布局?算了篇幅问题,以后有机会再来探讨吧,实际上对此,我用的也不多,还需继续总结才能不误人。

转载于:https://juejin.im/post/5c8110666fb9a049c8503dcf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值