改变CSS世界纵横规则的writing-mode属性

作者:张鑫旭(@张鑫旭)

链接:http://www.zhangxinxu.com/wordpress/2016/04/css-writing-mode/

一、冉冉升起的writing-mode

writing-mode这个CSS属性,我们是不是很少见到,很少用到!我们往往称不常见的东西为“生僻”,就像是不常见的文字我们叫“生僻字”,因此不常见的CSS属性,我们可以叫做“生僻属性”,writing-mode给我们的感觉就是一个“生僻属性”,很弱,可有可无。

但是,实际上,我们都错了,大错特错,writing-mode很弱?卧槽,别开玩笑了,writing-mode可以说是CSS世界里面最逆天的CSS属性了,直接颠覆CSS世界的众多规则。

而writing-mode之所以给人“生僻”的感觉,是有原因的。

实际上writing-mode这个CSS属性在上古时代就诞生了,IE5.5浏览器就已经支持了:

那就奇怪了!writing-mode既然这么鸟,同时时间早,资格老,为啥一直沉寂了差不多20年呢?

那是因为,在很长一段时间里,FireFox, Chrome这些现代浏览器都不支持writing-mode,writing-mode基本上就是IE浏览器的私有产物,大家对IE一直没啥好感,对吧,爱屋及乌由此及彼,自然对writing-mode也不待见。

然而,就在我们被流行前端技术一叶蔽目的时候,各大现代浏览器纷纷对writing-mode实现了更加标准的支持(主要得益于FireFox浏览器的积极跟进),也就是说,不知什么时候起,writing-mode的兼容性已经不成问题了,加上该属性本身特性逆天,我去,我仿佛看到了一个冉冉升起的新星,不对,是新月,而且是圆月。

二、writing-mode的原本作用

和float属性有些类似,writing-mode原本设计的是控制内联元素的显示的(即所谓的文本布局-Text Layout)。因为在亚洲,尤其像中国这样的东亚国家,存在文字的排版不是水平式的,而是垂直的,例如中国的古诗古文。

因此,writing-mode就是用来实现文字可以竖着呈现的。

您可以狠狠地点击这里:CSS writing-mode与文字垂直排版demo(http://www.zhangxinxu.com/study/201604/writing-mode-text-vertical-layout.html)

截自IE11浏览器IE8模式:

writing-mode语法

writing-mode的语法学习相比其他CSS属性要高一些,因为我们需要记住两套不同的语法。一个是IE私有属性,第二个是CSS3规范属性。

先看下未来所需的CSS3语法:

/* 关键字值 */

writingmode: horizontaltb;    /* 默认值 */

writingmode: verticalrl;

writingmode: verticallr;

 

/* 全局值-关键字inherit IE8+,initial和unset IE13才支持 */

writingmode: inherit;

writingmode: initial;

writingmode: unset;

各个关键字属性值的含义,我们透明名称就能知道其大概的意思,例如,默认值horizontal-tb表示,文本流是水平方向(horizontal)的,元素是从上往下(tb:top-bottom)堆叠的。

vertical-rl表示文本是垂直方向(vertical)展示,然后阅读的顺序是从右往左(rl:right-left),跟我们古诗的阅读顺序一致。

vertical-lr表示文本是垂直方向(vertical)展示,然后阅读的顺序还是默认的从左往右(lr:left-right),也就是仅仅是水平变垂直。

下面是各个值下的中英文表现对照(参考自MDN):

//zxx: 大家会发现英文字符横过来了,可以试试使用text-orientation:upright让其直立,IE不支持,FireFox, Chrome支持。

下面来看下老IE浏览器的语法,由于历史原因,显得相当的复杂,IE官方文档显示如下:

-ms-writing-mode: lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb

根据自己的测试(非原生IE8,IE9),-ms-私有前缀是可缺省的,直接writing-mode所以IE浏览器都是支持的。-ms-writing-mode这种写法IE7浏览器是不支持的,但是官方有如下说明:

Windows Internet Explorer 7. The rl-tb, and bt-rl values are available to the -ms-writing-mode

就是说IE7的-ms-writing-mode可以使用rl-tb和bt-rl这两个值,但这和自己的测试不符,我觉得可能是原生IE7浏览器,但我没有原生IE7,没有进行过测试,因此,此说法(原生IE7支持)只是自己的推测。

我扳指头数了数,IE浏览器下的关键字值多达11个,正好可以组个足球队,

lr-tb

IE7+浏览器支持。初始值。内容从左往右(left-right),从上往下(top-bottom)水平流动,以及下一行水平元素在上一行元素的下面,所有符号都是直立定位。大部分的书写系统都是使用这种布局。

rl-tb

IE7+浏览器支持。内容从右往左(right-left,从上往下(top-bottom)水平流动,以及下一行水平元素在上一行元素的下面,所有符号都是直立定位。这种布局适合从右往左书写的语言,例如阿拉伯语,希伯来语,塔安那文,和叙利亚语。

tb-rl

IE7+浏览器支持。内容从上往下(top-bottom),从右往左(right-left)垂直流动, 下一个垂直行定位于前一个垂直行的左边,全角符号直立定位,非全角符号(也可以被称作窄拉丁文或者窄假名符号)顺时针方向旋转90°。这种布局多见于东亚排版。

bt-rl

IE7+浏览器支持。内容从下往上(bottom-top),从右往左(right-left)垂直流动, 下一个垂直行定位于前一个垂直行的左边,全角符号直立定位,非全角符号(也可以被称作窄拉丁文或者窄假名符号)顺时针方向旋转90°。此布局多见于在东亚垂直排版从右往左的文本块上。

tb-lr

IE8+浏览器支持。 内容从上往下(top-bottom),从左往右(left-right)垂直流动。下一个垂直行在前一个的右边。

bt-lr

IE8+浏览器支持。 内容从下往上(bottom-top),从左往右(left-right)垂直流动。

lr-bt

IE8+浏览器支持。 内容从下往上(bottom-top),从左往右(left-right)水平流动。下一个水平行在前一行的上面。

rl-bt

IE8+浏览器支持。内容从下往上(bottom-top), 从右往左(right-left)水平流动。

lr

IE9+浏览器支持。在SVG和HTML元素上使用。等同于lr-tb.

rl

IE9+浏览器支持。在SVG和HTML元素上使用。等同于rl-tb.

tb

IE9+浏览器支持。在SVG和HTML元素上使用。等同于tb-rl.

各个属性值的表现如下(form微软官网)

一些说明:

  • 相同的writing-mode属性值并不会累加,例如父子均设置了writing-mode:tb-rl,只会渲染一次,子元素并不会2次“旋转”。
  • IE浏览器下,一个自身具有布局的元素(不是纯文本之类元素)如果writing-mode属性值和父元素不同,当子元素的布局流变化的时候,其父元素坐标系统的可用空间会被充分利用。左边文字太过术语,大家可能不懂,我解释下就是,IE浏览器下,当布局元素从水平变成垂直的时候(举个例子),你就想象为元素在垂直方向是100%自适应父元素高度的。所以,IE浏览器下(不包括IE13+),元素vertical流的时候会发现高度高的吓人,布局和其他现代浏览器不一样,就是这个原因。
  • Chrome浏览器下目前还需要-webkit-私有前缀,虽然Chrome和Opera认识tb-rl等老的IE属性值,但是,仅仅是认识而已,根本不鸟,没有任何效果,聋子的耳朵——摆设!

需要关注的writing-mode属性值

从着眼于直接开发的角度而言,虽然IE支持多达11个私有的属性值,但是,我们需要关注的,也就那么几个,那究竟是哪几个呢?

如果你的项目需要兼容IE7,则只有关注这两个值就可以了:初始值lr-tb和tb-rl,对应于CSS3规范中的horizontal-tb和vertical-rl!其他9个属性值就让它们去过家家好了。

如果你的项目只需要兼容IE8+,恭喜你,你可以和CSS3规范属性完全对应上了,而且IE8下的writing-mode要比IE7强大的多。我们需要关注:初始值lr-tb, tb-rl以及tb-lr,分别对应于CSS3中的horizontal-tb, vertical-rl以及vertical-lr。

看上去复杂的属性是不是变得很简单了,重新整一个实战版:

writingmode: lrtb | tbrl | tblr (IE8+);

writingmode: horizontaltb | verticalrl | verticallr;

对,大家只要记住上面几个就可以了,enough! 因为所谓的垂直排版,实际web开发是很少很少遇到的。

有同学可能要疑问了,既然writing-mode实现文本垂直排版场景下,那还有什么学习的意义呢?

前面也提到了,虽然writing-mode创造的本意是文本布局,但是,其带来的文档流向的改变,不仅改变了我们多年来正常的CSS认知,同时可以巧妙实现很多意想不到的需求和效果。

三、writing-mode不经意改变了哪些规则?

writing-mode将页面默认的水平流改成了垂直流,颠覆了很多我们以往的认知,基于原本水平方向才适用的规则全部都可以在垂直方向适用!

1. 水平方向也能margin重叠

W3C文档margin重叠之一:

The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.

清清楚楚写的bottom margin和top margin会重叠;然而,这是CSS2文档中的描述,在CSS3的世界中,由于writing-mode的存在,这种说法就不严谨了,应该是对立流方向的margin值会发生重叠。换句话说,如果元素是默认的水平流,则垂直margin会重叠;如果元素是垂直流,则水平margin会重叠。

您眼见为实,您可以狠狠地点击这里:CSS writing-mode与margin水平重叠demo

结果:

2. 可以使用margin:auto实现垂直居中

我们应该都是的,传统的web流中,margin设置auto值的时候,只有水平方向才会居中,因为默认width是100%自适应的,auto才有计算值可依,而垂直方向,height没有任何设置的时候高度绝不会自动和父级高度一致,因此,auto没有计算空间,于是无法实现垂直居中。但是,在writing-mode的世界里,纵横规则已经改变,元素的行为表现发生了翻天覆地的变化。

  • 图片元素

我们先来看下,图片元素margin:auto实现垂直居中,您可以狠狠地点击这里:CSS writing-mode与图片margin:auto垂直居中demo(http://www.zhangxinxu.com/study/201604/writing-mode-vertical-image-margin-auto.html)其中图片:

img { display: block; margintop: auto; marginbottom: auto; }

FireFox浏览器下(P白省流量):

但是,在IE浏览器下,却没有垂直居中~~

纳尼?!难道IE不支持垂直流下的垂直居中?非也,根据鄙人的测试,也就是图片这类替换元素貌似不行,普通的block元素都是可以的。

  • 普通块状元素

您可以狠狠地点击这里:CSS writing-mode与普通block元素margin:auto垂直居中demo(http://www.zhangxinxu.com/study/201604/writing-mode-vertical-margin-auto.html)此时,不仅IE11 edge,甚至IE8浏览器也都垂直居中了!IE8浏览器下block元素的margin:auto居中

3. 可以使用text-align:center实现图片垂直居中

前面提过,auto无法实现IE浏览器下的图片垂直居中,如果我们非要让图片垂直居中,可以使用text-align:center,您可以狠狠地点击这里:CSS writing-mode与图片text-align:center垂直居中demo(http://www.zhangxinxu.com/study/201604/writing-mode-vertical-image-text-align-center.html)

结果,之前病恹恹的IE浏览器活了:

由于我们直接使用内联特性进行控制的,因此,IE7浏览器也是可以实现text-align:center下的图片垂直居中,但是,根据我在IE11↘IE7下的测试,writing-mode需要写在最后重置下(原生估计不会这样),因此,完整的writing-mode代码为:

.verticlemode {

    writingmode: tbrl;

    –webkitwritingmode: verticalrl;      

    writingmode: verticalrl;

    *writingmode: tbrl;

}

4. 可以使用text-indent实现文字下沉效果

这是真实项目例子,要增加一个按钮按下文字下沉的效果。如果你来实现,你会这么实现呢?行高控制?但默认文本就不居中(对于高度自适应的按钮,line-height下沉为了避免按钮高度变化,默认是不能完全居中的)。padding+height精确控制,又略烦。然而,在writing-mode垂直流下,我们又有了新思路,例如,直接使用text-indent实现垂直方向的控制,没想到吧,无需关心height高度padding间距大小,任何按钮都可以通用,因为text-indent不会影响元素原本的盒布局。

您可以狠狠地点击这里:CSS writing-mode与text-indent文字下沉效果demo(http://www.zhangxinxu.com/study/201604/writing-mode-text-indent-vertical-down.html)

包括IE7在内的浏览器都是支持的(同上最后要*writing-mode覆盖下)都是支持下沉的。

为什么有如此的实现呢?这要归功于中文,在垂直流排版的时候,中文是不会旋转的,还是直立的,也就是说,虽然我们肉眼看上去文字没什么变化,但是,布局流已经发生了变化,以前类似text-indent/letter-spacing等水平控制属性都作用在垂直方向了。

当然,我们这个例子比较巧的是按钮文字只有一个,要是按钮文字有多个,怕是就没这么轻松和绝妙了。

5. 可以实现全兼容的icon fonts图标的旋转效果

在老的IE浏览器下,我们要实现小图标的旋转效果是不是很烦?要使用IE的旋转或翻转滤镜(filter)什么的,具体可参见我之前的“CSS垂直翻转/水平翻转提高web页面资源重用性”以及“IE矩阵滤镜Matrix旋转与缩放及结合transform的拓展”一文。

现在我们有了writing-mode,我们就不要这么烦心了。

前面可能也注意到了,当writing-mode把文档变成垂直流的时候,我们的英文和数字符号是会“躺着”显示,也就是天然90°旋转了。此时,我们不妨脑洞大开一下,假如我们使用icon fonts技术让这些字符直接映射某个小图标,那岂不是松松实现小图标旋转了,关键在于,就算是千年杀的IE6,IE7浏览器也是支持的啊,这要比滤镜什么的简单多了!

眼见为实,您可以狠狠地点击这里:writing-mode实现icon fonts图标旋转效果demo(http://www.zhangxinxu.com/study/201604/writing-mode-font-face-icon-rotate.html)

就算是IE7浏览器,也是很给力的!

6. 充分利用高度的高度自适应布局

卧槽,不行了,内容太多了

往下的7,8,9,10一起都略了吧~~

总之,放开自己的大脑,理论上讲,有了writing-mode,我们能够做的事情比以前多了50%,就怕你想不到,不怕做不到。

四、writing-mode和direction的关系

上个月刚刚介绍了CSS direction属性,也是个好东西,具体参见“CSS direction属性简介与实际应用”,其可以改变文字的走向,那他和writing-mode是个什么关系呢?

writing-mode, direction, unicode-bidi(MDN文档)是CSS世界中3大可以改变文本布局流向的属性。其中direction, unicode-bidi属于近亲,经常在一起使用,也是唯一两个不受CSS3 all属性影响的CSS属性,基本上就是和内联元素一起使用使用,且据说貌似为阿拉伯文字设计。

乍一看,writing-mode似乎包含了direction, unicode-bidi某些功能和行为,例如vertical-rl的rl和direction的rtl值有相似之处,都是从右往左。然而,实际上,两者是没有交集的。因为vertical-rl此时的文档流为垂直方向,rl表示水平方向,此时再设置direction:rtl,实际上值rtl改变的是垂直方向的内联元素的文本方向,一横一纵,没有交集。而且writing-mode可以对块状元素产生影响,直接改变了CSS世界的纵横规则,要比direction强大和鬼畜的多。且据说貌似为东亚文字设计。

然而,CSS的奇妙就在于,某些特性当初可能就是问了某些图文排版设计,但是,我们可以利用其带来的特性,发挥自己的创造力,实现其他很多意想不到的效果。所以,上面出现的三剑客都是非常好的资源。

五、writing-mode和*-start属性的流机制

CSS3中出现了诸多*-start/*-end属性(亦称为CSS逻辑属性),例如:margin-start/margin-end, border-start/border-end, padding-start/padding-end, 以及text-align:start/text-align:end声明。

下面问题来了,为什么会蹦出这么多*-start/*-end鬼?

那是因为现代浏览器加强了对流的支持,包括老江湖direction,以及最近年月跟进的writing-mode。

在很久以前,我们的认知里,网页布局就一种流向,就是从左往右,从上往下,因此,我们使用margin-left/margin-right没有任何问题。但是,如果我们流是可以变化的,例如,一张图片距离左边缘20像素,我们希望其文档流是从右往左,同时距离右侧是20像素,怎么办?

此时,margin-left:20px在图片direction变化后,就无效了;但是,margin-start就不会有此问题,所谓start, 指的是文档流开始的方向,换句话说,如果页面是默认的文档流,则margin-start等同于margin-left,如果是水平从右往左文档流,则margin-start等同于margin-right。margin-end也是类似的。

webkit内核的浏览器还支持*-before和*-end,默认流下的margin-before近似于margin-top,margin-after近似于margin-bottom,然而,规范貌似没提及,FireFox也没支持,*-before和*-after出场的机会并不多,为什么呢?因为实际上,配合writing-mode,*-start/*-end已经可以满足我们对逻辑位置的需求了,水平和垂直都可以控制,对立方向适用老的*-top/*-bottom.

例如,我们设置writing-mode值为vertical-rl,此时margin-start等同于margin-top,如果此时margin-start,margin-top同时存在,会遵循权重和后来居上原则进行相互的覆盖。

可以看到,场景不同,margin-start的作用也不能,能上能下,能左能右简直在世百变星君。

关于*-start/*-end以后有机会会具体展开论述,这里就先点到为止,大家估计目前也不会在实际项目中使用。

这可能是史上最全的CSS自适应布局总结

作者:茄果

链接:http://www.cnblogs.com/qieguo/p/5421252.html

标题严格遵守了新广告法,你再不爽,我也没犯法呀!屁话不多说,直入!

所谓布局,其实包含两个含义:尺寸与定位。也就是说,所有与尺寸和定位相关的属性,都可以用来布局。

大体上,布局中会用到的有:尺寸相关的盒子模型,普通流、浮动、绝对定位三种定位机制,CSS3中的transform、弹性盒子模块、试验中的grid模块。逛园子的时候经常可以看到浮动布局,inline-block布局,弹性盒布局这几个名词。现在对布局也算有一点了解,做个总结巩固一下。如果你也看了很多资料,但是实际动手时对布局还是无从下手的话,希望本文可以帮你理清思路。

唠叨一句:看到一个效果图的时候,千万不要急着手贱去敲代码!先思考清楚页面的构造,理清各元素之间的关系,特别需要注意的是在不同的设备下需要有怎样的展现,当你思路清晰找到最好的布局方案时,coding其实真的不需要多少时间。

尺寸相关

为什么要先说尺寸呢?因为尺寸在布局中的作用非常核心,布局方式定位这些只是改变了元素之间的关系,没有尺寸就什么也不是。比如我们通常会用margin来控制跟其他元素的距离,这就是布局。

很多人都会觉得,什么width、margin太简单了,早就掌握了。这种心态我一开始学习CSS的时候也有,觉得很好理解很简单,但是后面才发现自己原来很多东西都没真正掌握。看看张鑫旭大神给我们上的政治课:http://www.zhangxinxu.com/wordpress/2012/07/bottleneck-css-study/

先说说百分比,百分比是相对父对象的,这里特性非常好用,很多时候会用在自适应布局上面。浏览器尺寸的改变,就是根节点html的长宽改变,我们可以用%来将浏览器尺寸和元素尺寸联系起来,做到自适应。

另外一个比较有意思的是auto,auto是很多尺寸值的默认值,也就是由浏览器自动计算。首先是块级元素水平方向的auto,块级元素的margin、border、padding以及content宽度之和等于父元素width。使用auto属性在父元素宽度变化的时候,该元素的宽度也会随之变化。

但是当该元素被设为浮动时,该元素的width就变成了内容的宽度了,由内容撑开,也就是所谓的有了包裹性。overflow | position:absolute | float:left/right都可以产生包裹性,替换元素也同样具有包裹性。在具有包裹性的元素上想利用width : auto;来让元素宽度自适应浏览器宽是不行的。

高度方向:外边距重叠,外边距auto为0,这两点需要注意。书写方向什么的,接触比较少就不扯了。

那为什么margin:auto对不能计算垂直方向的值呢?很简单,垂直方向是被设计成可以无限扩展的,内容越多浏览器便产生滚动条来扩展,所以垂直方向都找不到一个计算基准,以此返回一个false,便成了0。

用处:通过width、height控制大小,各个方向的margin值控制与边界或者其他元素的距离来定位。

浮动

目前PC网站大多使用float布局,从成本上考虑大改的概率很小,所以不要说浮动无用,总是会有机会让你维护的!代表网站:淘宝、腾讯、百度,好吧BAT都到齐了。

浮动听得多了,博客园上关于用浮动布局的介绍也非常的多。浮动原本用于文本环绕,但却在布局被发扬光大,这就是命!我的理解:浮动布局的核心就是让元素脱离普通流,然后使用width/height,margin/padding将元素定位。脱离普通流的元素,就像脱离地心引力一样,与普通流不在一个高度上。这个跟图层的概念类似。高度不同所以可以叠在其他元素上面产生重叠或者使用负边距跑到父元素外,理解了这一点浮动布局就很好理解了。

下面用个圣杯布局的例子说明一下,理解了这个之后其他布局更加简单:

left,宽度固定,高度可固定也可由内容撑开

right,宽度固定,高度可固定也可由内容撑开

center,可以自适应浏览器宽度,高度可固定也可由内容撑开。

HTML & CSS:

原理非常简单,左右侧边栏定宽并浮动,中部内容区放最后不浮动、默认width:auto并设置相应外边距,让左右侧边栏浮动到上面。注意:子元素设置为浮动之后,父对象的高度就坍塌了,需要设置父对象后的元素清除浮动,这样父对象的高度才能被浮动子元素撑起来了。

当然,我们也要问一下,为啥父对象高度会坍塌呢?上面也说过了,浮动元素已经脱离了普通流,父对象所在的普通流比喻成地表,那浮动元素就已经上天了。但是父对象还在地表啊,从外太空看浮动元素在父对象里面,但是其实并不在,又怎么能撑开父对象呢?宽度如果我们不设置的话,其实也是为0的,因为父对象里面空空如也,所以宽高为0。

要撑开的办法就两个,1是让父对象也上天(。。。你咋不上天呢),2是把浮动元素的边框边界拉下来。

父对象也上天(即浮动)的话,那就不能实现宽度自适应了。因为float元素的width:auto是包裹内容的,参考前面说的!

办法2就是在后面的元素里加一个clear语句。说到这个问题就要扯到clear与BFC了,我就不献丑了。传送门:https://developer.mozilla.org/zh-CN/docs/Web/CSS/clear

这个三列布局还有个双飞(是双飞翼!想啥呢)的变种,就是在HTML中center部分也就是内容区提到最前面,也就是内容先行渲染。在网络不好的时候,左右双翼能不能出来不要紧,先让主体内容出来!这种想法,明显的优秀工程师思维,但,尼玛的双翼都是广告啊。广告不出来,哪能赚钱养你们这群工程师?所以提出双飞的玉伯才离开了淘宝???(纯属意淫,如真属实,当我扯淡,哈哈哈!)

先上码:

思路:

1)既然HTML里面要让center放前面,为了让left跑到center前面,那center也必须浮动了,否则因为都是块元素他们会分两行。

2)浮动之后还要让center宽度自适应,那明显width只能100%,然后在父元素中设width:auto,还有两侧margin,其实也就是父对象宽度自适应,center只是继承content的宽度。

3)对left使用负的margin让他们浮动到上方去。

代码里面我用到了一个calc(),这个CSS3带来的计算函数简直酷毙了!本例里如果不使用calc函数,那么就需要wrap左边距为0,left左边距-100%,然后center多加一层子块DIV设置margin-left:100px,可以达到同样的效果!calc函数与百分比配合就足以实现自适应的要求!目前所有的自适应布局都在利用浏览器来为我们计算尺寸,但是有了calc之后我们就可以自己制定规则!单是想想都高潮了吧?

总结:使用浮动来进行布局,一个比较大的问题是清除浮动。这个可以使用一个after伪类来清除。更大的问题是浮动性像水一样向上流动,难以把握。在元素较多而且元素高度尺寸不一的情况下,单纯使用浮动只能实现上端对齐,这对于适应多种设备的布局就显得力不从心了。目前的做法是牺牲一部分内容,将元素做成等高排列,从美观上看也当然也是极好的,比参差不齐的排列要美观。

普通流布局

普通流布局:display : inline-block!这是一个传说中取代float布局的存在。看了一些网站,PC端浮动为主,移动端的也用的不多啊,已经有些使用flex的了,说好的inline-block一统江湖呢?

使用inline-block之前先处理点小障碍:inline-block元素会有4px左右的空隙,这个是因为我们写代码时候的换行符所致。

解决办法很简单:在inline-block的父元素中设置样式font-size:0;letter-spacing: -4px; 然后设置inline-block的所有兄弟元素 font-size:值;letter-spacing: 值px;  恢复正常的显示。

另外还有一点需要注意的是inline-block默认是基线对齐的,而inline-block的基线又跟文本基线一致,所以在内容不同的时候并不能水平对齐。只需要用vertical-align显式声明一下top/bottom/middle对齐即可。这里补充一下基线的内容,没你想的那么简单哦。分有文字和无文字两种情况:

1)无文字:容器的margin-bottom下边缘。与容器内部的元素没一毛钱关系。

2)有文字:最后一行文字的下边缘,跟文字块(p,h等)的margin、padding没关系!注意是最后一行,无论文字在什么子对象容器内在什么位置都没关系,浏览器会找到最后一行文字对齐底部。

你们感受一下:

警示:inline-block的基线是最后一行文字的底部,flex里面的基线是第一行文字的底部(请看下文阮老师的文章)

满满的都是泪啊。。。既然都叫baseline,何必呢?

使用inline-block进行圣杯布局:

这里也没什么好说的,用到的也是width:auto和width:100%这两点,简单知识点的简单用法。

双飞的话,代码跟圣杯的基本相同,注意在html的顺序变为center>right>left,只改左栏移动的margin-left: calc(-100% – 100px)到预定位置即可。不能用calc的话可以在center里面再加一层,跟浮动一样的处理方式。更简单的方法是使用CSS3带给我们的box-sizing属性。请看代码:

总结:相比浮动inline-block更加容易理解,也更符合我们的认知,结合盒子模型的几个控制属性就可以进行布局了。对于元素高度不同的情况,目前浮动布局的做法都是将元素做成等高元素进行展现,这从美学上看也符合整齐的要求,不过牺牲了一部分内容。但inline-block有vertical-align属性,可以很好地解决元素高度不同而带来的布局问题。用过之后,你也会喜欢上inline-block的。。。至少我会!

绝对定位

前面的浮动和普通流中其实定位都是靠盒子模型控制的,与我们常说的定位还是有差别的。而绝对定位就是我们平常所说的定位,给定参考坐标系+坐标确定位置。关于绝对定位的资料太多,我就不说了。提一点就是absolute定位的基准是最近的非static定位父对象,而fixed是相对html根节点的定位。两种定位都会脱离普通流,跟之前说的浮动一样,上天了。

当然,他们跟浮动在空间中的位置还是有差别的,项目中有遇到这个问题的请参考张大婶的文章: http://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/  还是要结合项目来看,否则看过也只是看过而已,并不会存到你的脑子里,毕竟还是相当抽象相当理论性的东西。借用张大神的一个总结图:

使用绝对定位(特指absolute)做自适应布局跟前面两种方式没太大差别,宽度自适应还是在auto和100%上做文章,而位置则由top/bottom/left/right等控制。还是以圣杯布局来举例:

<!DOCTYPE html>

<html>

    <head>

        <meta charset=“utf-8” />

        <title>宽度自适应布局</title>

        <style>

            .wrap {

                position: relative;

                background-color: #FBD570;

                margin-left: 100px;

                margin-right: 150px;

                height: 250px;

            }

            .left {

                position: absolute;

                top: 0;

                left: -100px;

                width: 100px;

                background: #00f;

                height: 180px;

            }

            .right {

                position: absolute;

                top: 0;

                right: 0;

                   width: 150px;

                background: #0f0;

                height: 200px;

                margin-right: -150px;

            }

            .center {

                position: absolute;

                top: 0;

                left: 0;

                background: #B373DA;

                height: 150px;

                min-width: 150px;

                width: 100%;

            }

        </style>

    </head>

    <body>

        <div class=“wrap”>

            <div class=“center”>

                center,可以自适应浏览器宽度,高度固定。

            </div>

            <div class=“left”>left,宽度高度固定</div>

            <div class=“right”>right,宽度高度固定</div>

        </div>

    </body>

</html>

父元素为relative,子元素为absolute,这样的话,又会出现跟浮动一样的问题:父对象高度坍塌,子元素不能撑起父对象。原因也跟浮动一样,解决办法的话目前我知道的只有给父对象指定一个确定height值,大家如果有更好的办法,请联系我!

总结:单纯使用绝对定位进行自适应布局的情况很少,一般绝对定位都用在尺寸固定的元素定位上。而且fixed定位的渲染效率很低,因为它会频繁触发浏览器的重排。另外提一点:CSS3的transform会对绝对定位产生影响哦~比如说让fixed定位不再固定在浏览器视窗的黑魔法:http://www.zhangxinxu.com/wordpress/2015/05/css3-transform-affect/

弹性盒子

CSS3中对布局影响最大的莫过于弹性盒子模块了,这是一套区别于以往盒子模型布局的全新方案。上面几种方法你可以看到,为了实现自适应我们用的都是width:auto和100%的嵌套以及各种边距的移动定位,这套规则并不符合我们的认知。为什么不能开拓出一块区域,横竖排列都可以,内部所有元素的尺寸可以按照一个规则和这个区域的大小联系起来?终于CSS3做出了改变,引入了flex弹性布局方案,弹性盒布局有如下优势:

1.独立的高度控制与对齐。

2.独立的元素顺序。

3.指定元素之间的关系。

4.灵活的尺寸与对齐方式。

在MDN上有非常简单易懂的基础教程:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes

上面也已经给出了圣杯布局的自适应布局方案,所以代码就不贴了不过这个例子实现的是3栏成比例缩放,左右栏如果需要固定值的话可以写成  flex: 0 0 150px; 的样式。

但是上面的教程没有给出各个属性的详细解释,建议看看阮一峰的博文,详细易懂而且配图超漂亮的有木有:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

总结:弹性盒子在移动端的应用会越来越普遍,这套模型值得去好好研究。语法规则都是非常贴近人性,非常灵活,浏览器兼容性也非常好,当然国内百花齐放的移动浏览器会有哪些大坑呢?我们拭目以待~

其他

其他包括position:relative和CSS3中的transform都可以实现定位,但是由于他们在原来的普通流中还占着一个坑,所以很少用来布局啥的。transform是个很酷炫的东西,可以用平面的素材做出很多3D的效果,而且不需要js就可以做,非常好玩。此文已经很长,就不多说了,以后会写一篇文章来专门说说她的故事。