这篇文章发布于 2017年02月15日,星期三,00:10,归类于 CSS相关。 阅读 61080 次, 今日 3 次 31 条评论
by zhangxinxu from http://www.zhangxinxu.com/wordpress/?p=5945
本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随意。
纵观所有书籍阅读网站移动端web app,第一个支持水平滑页阅读效果的网站就是起点中文网移动站,目前好像也是唯一一个。
效果如下截屏视频:
也可以随便找本书去感受下。
其实现最关键的核心就是利用CSS3 column分栏布局。
一、CSS3 column多栏布局
CSS3 column多栏布局是支持比较早的CSS3布局方式,目前IE10+以及其他所有现代浏览器都支持,IE浏览器不需要私有前缀,FireFox和Chrome虽然现在也不需要,但是,考虑到移动端以及可能一些用户浏览器升级不及时的现状,因此,-webkit-
以及-moz-
前缀目前还不能省略。
一般来讲,常用的属性又下面几个:
column-width
: 每栏的宽度;column-count
: 最理想的分栏数目,注意这里的措辞,是“理想的”,这个词很微妙的,大家可以多多体会下;column-gap
: 栏目之间的水平间隙;column-rule
: 分割线,形式规则什么的等同于border
,column-rule
实际上是一个缩写,还有column-rule-width
,column-rule-style
,column-rule-color
之类,就跟border
属性一个套路;column-fill
: 效果不明,不算常用。默认值是balance
,表示对每栏进行协调。还可以使用值auto
,表示每一栏按顺序填充。我是没搞清楚有什么区别。
其中,还有个缩写属性,名为columns
,实际上是column-width
和column-count
的缩写:
columns: 120px; /* column-width: 120px; column-count: auto */ columns: auto 120px; /* column-width: 120px; column-count: auto */ columns: 2; /* column-width: auto; column-count: 2 */ columns: 2 auto; /* column-width: auto; column-count: 2 */ columns: auto; /* column-width: auto; column-count: auto */ columns: auto auto; /* column-width: auto; column-count: auto */
如果翻看一些文章或者demo示意,基本上都是下面这种套路,容器指定一个大大的宽度,然后通过column-count
属性设定分为了几栏,比方说,如果是:
column-count:4
则会是按下图所示的样子(不同浏览器细节上会有差异):
如果是:
column-count:3
则:
如果是:
column-count:2
则:
看上去好像很厉害,而且离理解上难度并不高,然而,这么多年下来,我几乎就没有看到任何项目中有类似的使用。
column
多栏布局和flex
弹性布局基本上是同一时间段出现的,从兼容性来讲,column
多栏布局一直以来更稳定更兼容,而flex
弹性布局前前后后历经多个版本,直至现在有些移动设备支持依然不好,但是两者的命运却截然相反,column
多栏布局鲜有人问津,而flex
弹性布局则风生水起。面试的时候,就算面试者并未在实际项目中使用过flex
弹性布局,也会时不时扯到这东西上来,好像不提flex
布局就跟时代脱节一样,其实完全没有必要,每个CSS属性都有它的潜力和价值所在,挖掘其内在价值而不是单纯的被外在的那层表现困于庐山才是真正想要看到的。
回到这里,如果我们仅仅看到上面示意的这种常规表现,必然会觉得多栏布局似乎好像应用场景不是那么广泛,因为只有类似报刊杂志这种排版才会需要多栏布局,在web中,宽度往往是有限的,高度是无限的,所谓多栏布局,一般而言,就是指的分割宽度,但是想想看,宽度本来就不够,何来场景再让你去分呢?综合这些因素导致多栏布局闲有人问津。
但是如果我们挖掘多栏布局的潜力,会发现其实其能够实现的布局或者效果要比表面看上去的多。
我们这里书页的水平滑动浏览效果就是使用的CSS3 column
属性实现的。
二、CSS3 column有趣的空间使用特性及水平滑动浏览效果实现
- margin也在空间计算之列
这是什么意思呢?比方说上面4栏的例子,如果我们把文字内容变少,会发现,可能就会这样,Chrome和IE浏览器下都是如此,看上去就好像只有3列显示了:
实际上并不是只显示了三列,而是因为示意的HTML结构如下:
<div class="box col4"> <p>文字...</p> </div>
<p>
默认上下有1em
的margin间距的,于是乎,我们看上去好像是第四栏空缺,实际上被<p>
元素的margin-bottom
给占据了,如果我们使用下面的CSS重置掉<p>
标签的margin值,会发现,如预期的4列显示了:.box p { margin: 0; }
- column布局高度也是重要限制
上面几个
column-count
示意都是定了个宽度600px
,高度是默认的auto
,因此,分栏的表现都很乖巧,反正高度是无限的,无论你设置多少栏,我都可以通过调整高度来实现。但是,如果我们高度也设定了固定的值,例如高度
60px
,则此时很多有意思的事情就会发生了。如果说仅仅只是指定了
column-count
,至少在容器元素的可视尺寸范围内,还是设定的分栏数目,例如column-count:3
,虽然视觉上远不止3栏,但是容器可视尺寸范围就是3栏,如下截图示意: - column-width会让column-count打酱油
这是什么意思呢?比方说下面的CSS:
.col4 { width: 600px; column-count: 4; column-width: 200px; }
显然这里有矛盾之处,每栏宽度
200px
,总共要4
栏,就算不考虑每栏之间的间隙,也至少需要800px
的宽度,但是,我们容器设定的宽度只有600px
,怎么办呢?那即是
column-count
忽略无效打酱油,不要觉得不合理,也不要抱不平说为什么牺牲的是column-count
,而不是其他属性?那是因为column-count
天生注定就是要牺牲的命,因为其语义解释就是“最理想的分栏数目”,所谓最理想,就是你该牺牲的时候就要牺牲。实际上这里最终的每栏每列宽度表现并不是
200px
,如果我没算错的话,在没有样式重置的情况下,应该是292px
。 - 高宽同时限制可以实现完美分页
如下CSS代码:
.example { height: 120px; width: 100px; column-width: 100px; }
如果我们把
100px*120px
的这个名为.example
的小容器看成是一页内容的话,则此时,我们容器中的所有内容,就被完美的分成了一页一页水平呈现的内容,如下截图:这里就是我们书籍水平滑动浏览的关键所在,此时,如果我们给父元素有个如下的
overflow
限制:.father { width: 100px; overflow: hidden; }
此时就形成了一个永远只会显示一页宽度的视窗,然后下面的事情就简单了,我们通过JS一些一些touch相关的事件,控制我们的
.example
元素translateX
位移,就可以实现一开始展示的水平滑屏浏览小说内容的效果了。完美撒花!
上面第4点“高宽完美限制”即是起点中文网移动web app阅读页水平阅读布局实现原理,差别就是宽高尺寸不一样,不知赘述。这里顺便提一下开发时候的番外小故事:
原本滑页是通过改变容器原生的scrollLeft
值来实现的,而不是translateX
位移,好处在于不要担心边界判断的问题。但是后来发现有两点不足:
1. 个别Android设备下,滑动不是很流畅;
2. 这个不足是最为致命的不足,那就是在chrome55之后版本CSS3 column
布局出现了非常严重的bug, 容器overflow:hidden/auto
之后,后面第3栏开始往后的分栏会直接无法显示;
于是,最后选择了使用translateX
进行位移。
还别说,真有不少用户使用水平浏览模式,或许是跟原生APP交互形式相一致的原因吧。
补充于2017年3月13日
已经有多个小伙伴询问如何判断已经滑动到底部,很简单啊,设置overflow:hidden
容器的scrollWidth
值就是子元素的宽度。
三、结束语
情人节快乐!尼玛突然一看右下角,已经过期了!
好吧,明年再来祝福吧~
突然还想起一件事情,很不少人吐糟站点太丑,没错,就是“丑”这个词,但是,又不提供好的设计意见,所以,如果大家有觉得在排版或者样式上有哪些可以改进的地方,欢迎提出来。不过有几点需要明确:一是网站主题色不能变;二是内容不能变;三是调整尽量是微调,改动不能大。
最后,感谢阅读到最后,有什么真知灼见也欢迎交流!
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=5945
(本篇完)
- 快速了解CSS新出的列选择符双管道(||) (0.550)
- 写给自己看的CSS columns分栏布局教程 (0.267)
- 写给自己看的display: flex布局教程 (0.231)
- CSS/CSS3 box-decoration-break属性简介 (0.228)
- CSS columns轻松实现两端对齐布局效果 (0.220)
- CSS gap属性进化史 (0.220)
- CSS box-flex属性,然后弹性盒子模型简介 (0.191)
- 关于文字内容溢出用点点点(...)省略号表示 (0.183)
- 聊聊CSS世界中的margin-box (0.183)
- 深入CSS ::first-letter伪元素及其实例等 (0.183)
- RGBA颜色与兼容性的半透明背景色 (RANDOM - 0.008)
看《css新世界》221页推荐地址进来的,然后看现在起点中文移动站已经没有左右滑动效果了,是有什么原因导致有分栏布局解决不了的问题吗?
想多了,仅仅是改版了,换人实现了哈。
请问小程序scrollWith怎么获取啊
第一左滑切换上一页,在切上一章的时候,需要先将dom插入父节点才能正确获取scrollWidth,在计算translate值到上一章的最后一页。firefox明显会有跳动现象怎么处理的?
Safari中scrollWidth获取的并不能获取实际内容大小,而是该盒子的宽度,怎么处理的
大神,向前翻章的时候,必须先appendChild,然后才能获取scrollWidth计算translate的值,这样会造成向前滑动先出现第一页然后闪到最后一页,您是怎么处理的
我想问问如果要把文章真的分成几页,和上面说的效果一样,要怎么写逻辑呢?
关于column-fill这个属性是有区别的
我写了个DEMO : http://runjs.cn/code/jl4szipj
初始状态,column-count:2,P标签文字填充少于两栏变成平均布局,达不到期望效果
于是我想 P标签设置最小高度,强制让它填满自动换行如何?
就给P标签设置了min-height, CSS 102行 ( 因为column为2,此时高度值也要x2才能正确计算)
设置后发现 可以正常填充了,但是导致了新的问题:底部页码变成了1/2
明明只有一屏,但由于设置了高度,导致这个P标签的宽度渲染出现了问题,
读取父级scrollWidth 实际上得到的值是P标签的宽度+左半栏的宽度,计算出了两页
于是我去翻MDN发现了column-fill:auto这个属性
设置这个属性后(取消99行注释,102行min-height也不需要加了)
浏览器就可以正确的渲染P标签的宽高了,不设置之前,F12可以看到P标签的渲染大小是异常的
最终计算成功,翻页也没问题 DEMO:http://sandbox.runjs.cn/show/bcgeso2s
你好,第一列上面会空出来一行是什么原因呢?
大神,问个问题,加入标签要算字体偏移量,因为阅读器可以设置字体大小,行间距等,只能查字数,什么属性可以获取屏幕可视区域内的内容吗?
https://m.zhulang.com/382772/208083.html
挺早就支持左右滑动了。用的也是这个原理。
不过在滑动触发上做了点判断,>=25% 屏幕宽度的时候 才认定是需要换页。
当然也要考虑 触发的时间间隔。
也看过一些左右分页 只要有左右位移就换页的,感觉稍有太过灵敏嫌疑。
你好,能大概说一下,字体放大之后,怎么获得正确的当前页么,我也是用的这个方法做的分栏,看了一下你的代码,没有懂
你好,你的链接地址挂了,能否看下如计算页数吗
我在一个ul中通过column布局,分3列,里面的li排列很自然就是
1 3 5
2 4 6
嗯。。对,正常我们应该是
1 2 3
4 5 6
请问这个有什么方法吗
如果是分多个ul,每个里面包3个li确实可以实现,但是不利于数据渲染。。
除了这个方法以外?
非常感谢,正是想实现一个分栏翻页的功能,却被边界判断卡住了,原来还有scrollWidth这么个好东西,内牛满面
照片照片更新更新吧。哈哈
可能他是嫌弃你右上角的照片太丑吧!!!!!!!!!!!!!!!!(一本正经)
我感觉并不丑,这种学习的网站就是要让别人看的简单明了,而不是花花绿绿的没吊用的东西
HI,您好,我想请教怎么设置translateX的结束条件。谢谢!
容器的scrollWidth就是最终的长度。
我觉着是广告的部分有点丑,单独出一个广告板块?
get新技能,谢谢!
我有一个困惑困惑,通过column布局进行滚动与通过别的方式横向布局之后再滚动效果有什么不同呢? 这里为什么要强调column布局,难道会有性能上的提升?
优势在于 column布局实现 文字的无缝衔接吧
@yeatszhang 这里别的方式无法实现,只有column布局可以。
我一直用的仿真翻页,那个是咋搞的
大神有没有考虑过移动端限定一下图片的max-width,现在在移动端看的话,图片一大就需要横向滑动。
应该是嵌入的视频导致,我处理下~
其实我们网站也在用,不过图文混排的时候挺糟糕的,起点这样纯文字的排版倒是很合适
为什么丑也说不上来,大概是没有当前的流行元素吧。比如大色块啊,半扁平化啊,图像背景啊之类的。不过个人而言阅读起来很舒服,没有干扰。
沙发沙发 O(∩_∩)O撒花