极致CSS(7)-布局与定位

为了简单实用, 布局就直接从flex开始讲起. 要想让block或flex元素在一行展示, 可以在父元素设置属性display: flex, 或者子元素设置inline-flex.

先看第一种方式, 由于flex-direction的默认值是row, 而flex-wrap默认是nowrap, 也就是flex元素的子元素默认会在一行显示, 不会自动换行. 我感觉遇到这种个数不确定而且自动平分空间的场景比较少, 多数情况下列表是子元素固定宽度, 并且按宽度自动换行的, 所以我把flex元素都设置了flex-wrap: wrap. flex容器对于子元素的控制主要是通过 justify-content 和 align-items 两个属性, 这两个属性的默认值是normal,就相当于水平位置从起始位置开始排列(flex-start), 竖直方向拉伸至填满父元素高度(stretch). 由于多数场景下使用flex都是为了居中, 所以我把这两个属性都设置为center, 如果又需要对齐其他方向的再单独设置.

为方便描述, 以下把这两个属性简称为水平垂直属性.

首先看一种简单的情况, 一个display: flex的div, 里面有一段文字内容. 在水平垂直两个属性都设置为center时, 文字内容会在容器中水平垂直居中. 即使文字有多行依然表现良好. 所以flex极大的方便了页面布局, 在没有flex的年代, 需要通过line-height, vertical-align等属性复杂的计算和组合实现文字垂直居中, 而且不一定能很好的适应各种浏览器环境. 如果需要其他文字对齐方式, 正常调整水平垂直属性即可.

然后是内部包含子元素的情况, 其实也是类似的, 由父元素的水平垂直属性决定排列方式. 不同之处在于, 子元素可以设置尺寸, 此时元素的排列是根据父元素的水平垂直属性, 以及子元素的宽高和margin共同决定. 水平垂直属性也提供了几种常见的排列方式方便使用, 如space-around, space-between, space-evenly等, 不过实际场景中我们遇到的可能不是这些固定的排列方式, 所以就需要通过margin来调整. 简单的说, margin: auto会让子元素平分可用空间, 而单侧的margin-left: auto会让元素居右显示. 多数场景下使用这两个值都足够了, 可以代替float让元素右浮动的方法.

最后是一种更常见的场景, 使用flex排版列表, 其实关键是flex-wrap: wrap实现在容器边缘自动换行, 其他间距可以通过水平垂直margin调整. 也就是说, 通过在flex容器中使用margin, 即使不理解复杂的flex概念, 也可以实现布局. 个人认为是一种比较经济的方式.

当然, 如果能够深入学习和理解一下flex的概念, 对于日后学习grid布局也是有好处的, 很多概念是类似的. 其实难理解的主要是两个方面, 一是规范为了理论的严谨性, 使用了主轴和交叉轴的表达方式, 其实我们就简单理解成水平垂直属性就好了, 多数情况下使用flex都是为了水平排列元素, 如果确实遇到了少数场景要设置flex-direction为其他值, 可以先按水平排列的情况思考, 写好之后再把水平垂直属性互换一下. 另一方面是规范中大量的属性和篇幅在讲剩余空间的分配问题, 由于我们直接使用margin自己控制间距分配, 所以也避免了和复杂的分配规则打交道, 而且多数时候, 设计和业务想要的间距都不会按照规范制定者所想的方式, 基本都需要逐个手动设置.

然后说一下inline-flex, 其实就是让外部元素能和其他元素在同一行, 内部空间管理都是一样的. 之前还有inline-block属性, 也可以实现很多布局, 但是由于依赖inline模型的很多概念, 复杂难用, 所以现在基本都被flex取代了.

其实从历史和完整性的角度, 还是应该介绍一下float, 但是限于时间和篇幅, 以后如果有时间再补充吧.

定位

定位其实就是一个属性position, 值也不多, 默认值static, 然后是 relative | absolute | fixed, 以及一个不太稳定的sticky. 其中我们主要关注的是absolute.

如果一个元素设置了position: absolute, 就会有一些布局上的变化, 按照术语, 首先是绝对定位元素脱离标准文档流, 这个需要一些基础概念来辅助理解, 我们可以先理解成创建了一个单独的层, 和原先最下面的平面布局层相对独立. 如果试验一下就会发现, 自身的位置可能不会变化, 但是之后的元素会跑到他的下面. 这种状态也被称为'无依赖绝对定位', 因为设置位置的top/right/bottom/left四个方位值默认都是auto, 按照CSS规范, 元素的位置应该是在原先自己所处的位置. 但是层级会提高, 盖在其他元素之上. 此时元素会块状化, 但是和block形成的块不太一样, 不会自动填充宽度, 需要手动设置宽高或者根据内容决定尺寸. 要设置元素的位置可以通过两种方式, 一种是用四个方向上的定位属性, 但是定位的依据是包含块, 没有设置的话默认是根元素, 所以top: 0会把元素定位到页面顶部. 如果想改变包含块, 需要找一个上级元素设置上position属性, 因为绝对定位元素的包含块计算方式是: 最近的非 static 定位祖先元素. 另一种方式是通过margin控制, 由于margin支持负值, 也就可以在四个方向上移动, 这样不需要更改父元素的定位方式, 但是可能无法实现精确定位到距离右边或底边的指定位置.

实际场景中, 绝对定位一般用于将某个元素显示在固定位置. 所以通常会设置父元素为相对定位. 如果确实需要相对整个页面定位的, 可以用position: fixed, 概念和用法都是类似的, 只是强制指定了包含块为viewport也就是浏览器窗口, 注意这和默认的包含块为根元素也还是有一些区别, 因为页面滚动的时候, fixed元素是不会跟着动的, 而absolute元素会跟着自己的包含块移动. 所以说, fixed是一种特殊的绝对定位.

而relative多数情况下是为了给绝对定位元素设置包含块用的. 一个元素设置position: relative之后, 自身位置不会变化, 也不会脱离标准文档流, 不像absolute那样对其他元素有影响. relative的设计原意是让元素相对于自身原有位置偏移, 但是这一特性在实际场景中使用较少, 多数情况下都是使用margin进行偏移, 但是有一些区别在于, relative通过定位方式偏移之后, 自身原有的位置仍然保留, 不会影响其他元素, 可以理解为是在单独的一层上偏移的, 而margin偏移和文档流中元素是在同层的, 偏移之后其他元素的位置也会跟随变化. 所以这也是relative的一个应用场景, 提高元素的层级, 之后我们会看到, 设置了position属性的元素会创建新的层叠上下文.

所以在实际页面布局时, relative通常都是配合absolute使用, 此时relative元素作为absolute元素的包含块, 偏移位置都是相对包含块计算, 所以通过right和bottom偏移可以让元素定位在包含块的右边或底边指定位置. 另外元素的宽高百分比值也会相对于包含块计算. 另外一个特性是垂直方向上margin: auto会让元素在包含块中垂直居中. 不过在用flex布局之后这个特性的使用机会也不多了.

另外一个值sticky, 比较新, 兼容性也不好保证, 他的特点简单理解就是根据元素的位置是否在浏览器viewport显示范围内, 在relative和fixed之间切换. 有些场景下是有用的, 但是由于兼容性问题, 用之前需要查一下浏览器支持情况, 还要在真机上做测试, 我们就不多关注了.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容