原文连接
github.com/XboxYan/not…css
刚入前端那会,产品经理提出了这样一个需求html
这段文字能不能这样判断一下,当文字不足一行时,让它居中显示,当文字超过一行就让它居左,否则居中显示很奇怪,由于最后一行是吊着的前端
琢磨了一下,当时我还真按照产品经理的逻辑,经过js
判断一下文字的高度,若是超过一行,就添加一个类名,并且这样的文字不少地方都有,因此还作了遍历,还有最重要的一点是关于方法执行的时机,有可能刚加载的时候高度还获取不到(当时好像还用了定时器,还形成了先居中随后居左跳动的现象)...css3
//伪代码
$('.text').each(function(){
if($(this).height()>30){
$(this).addClass('mul');
}
})
复制代码
而后这些文本有可能仍是动态生成的,因此还得在生成文本的地方再调用一次这个方法,功能是作出来了,可别说有多啰嗦了,体验也不咋地(虽然外面的人看不到)git
当时也在想,若是是CSS
实现,那么就彻底不用考虑这些问题了!github
其实只要你逻辑清晰,js
都能实现出来,按照正常的思路一步一步走下来就好了。CSS
可不是这样,她须要你有更多的想象力。chrome
好比上面这种需求,表面上来看是须要判断文本行数,这彻底不是CSS
能干的事呀,不过咱们能够换个方向思考,文本默认是居左的(默认文本流),只有首行是居中的,首行能够联想到::first-line
伪元素,因此能够试着这样实现一下segmentfault
<p>这段文字能不能这样判断一下,当文字不足一行时,让它居中显示,当文字超过一行就让它居左</p>
复制代码
p::first-line{
text-align:center;
}
复制代码
很好理解是吧,只针对首行进行居中操做,当多行时,首行已经铺满了,居中或者居左效果已经不明显了,只是稍微有点瑕疵,首行的居中效果和后面的文字看着有些不太整齐的感受(由于当一行剩余空间不足一个字符的时候会掉下去)wordpress
解决这个问题也很简单,上面的问题是因为首行一直处于居中状态,那有没有什么办法能够只要一行的时候才居中呢?这里能够借助一下text-align-last
,意思就是规定多行文本的最后一行的居中方式,若是和::first-line
一块儿使用,既要知足首行又要知足是最后一行,是否是就判断出了当前只有一行呢?工具
p::first-line{/*匹配首行*/
text-align-last:center;/*最后一行居中*/
}
复制代码
这下就正常了,有点首尾夹击的味道~
遗憾的是,因为::first-line
支持样式很是有限(MDN),上述实现方法仅在chrome
下有效,不过这种逻辑仍是和js
差异很大的
虽然上述并无
text-align
相关属性,不过chrome
却已经支持了~
text-align:center
,子级inline-block
+text-align:left
首先来看看兼容性最好的实现方式
结构以下
<div class="content">
<span class="text">这段文字能不能这样判断一下,当文字不足一行时,让它居中显示,当文字超过一行就让它居左</span>
</div>
复制代码
样式以下
.content{
text-align: center;
}
.text{
display: inline-block;
text-align: left;
}
复制代码
这个方式最先是在《CSS世界》中学到的,
大概原理以下:
对于一个元素,若是其
display
属性值是inline-block
,那么其宽度由内部元素决定,但永远小于“包含块”容器的尺寸,也就是“包裹性(shrink-to-fit)”
可能这样描述的不够直观,来上述的案例简单来说
当文本比较少时,.text
的宽度跟随文本,而后咱们可使用父级text-align:center
来使一个inline-block
元素居中,因此能够知足单行文本居中的效果,
当文本比较多时,.text
的宽度跟随父级容器,因为text-align:center
会继承下去,因此在.text
上修复一下便可
兼容性一级棒~
width:fit-content
+margin:auto
上述方式是经过父级text-align:center
来实现inline-block
居中的,很巧妙,可是额外增长了标签,由于inline-block
元素没法自己居中的。
块级block
元素能够在设置宽度后直接经过margin:0 auto
来实现居中,可是必须指明宽度,否则就水平填充了,这二者的关系很微妙,有没有什么办法可以让块级block
元素的宽度像inline-block
元素跟随内部元素呢?
答案就是width:fit-content
,详细可参考这篇文章
width:fit-content
能够实现元素收缩效果的同时,保持本来的block
水平状态,因而,就能够直接使用margin:auto
实现元素向内自适应同时的居中效果了。
下面的实现方式均只须要单层标签
<p class="text">这段文字能不能这样判断一下,当文字不足一行时,让它居中显示,当文字超过一行就让它居左</p>
复制代码
.text{
width: fit-content;
width: -moz-fit-content;//火狐须要-moz-前缀
margin: 0 auto;
}
复制代码
固然,这种特性IE
确定是不支持的~
position:relative
+transform
仍需设置display:inline-block
来实现自适应,而后配合transform
来实现水平方向居中效果,实现也很简洁~
.text{
display: inline-block;
position: relative;
left: 50%;
transform: translateX(-50%);
}
复制代码
display:table
+margin:auto
前一种方式width:fit-content
颇有效,IE
不支持怎么办呢?其实默认display
已经有这种特性了,当display
属性值是table
,元素会表现出和width:fit-content
的效果,既支持宽度跟随内部元素,又支持水平方向上margin
居中
.text{
display: table;
margin: 0 auto;
}
复制代码
IE8
也完美支持~
flex
和grid
实现对于flex
和grid
来讲,实现这样一个效果仍是挺容易的。
在flex
容器中,全部子项成为弹性项,包括纯文本节点(匿名盒子),就好像包裹了一层,因此很容易经过justify-content: center
实现居中,同时(匿名盒子)也跟随文本自适应宽度,当超过一行时,就按照默认的文本对齐方式。
grid
同理,只不过对齐方式须要经过justify-items: center
。
flex
实现.text{
display: flex;
justify-content: center;
}
复制代码
grid
实现.text{
display: grid;
justify-items: center;
}
复制代码
相对于flex
,grid
的兼容性要差一些,因此尽可能选取flex
方式,至少移动端和IE10
(须要-ms-
)是没问题的
float
实现本觉得float
实现不了的,感谢林小志提供了float
居中的实现方法,大体原理以下:自己float
元素是具有包裹特性的,主要难点在于如何居中,毕竟没有float:center
这种写法,这里主要用到两层标签,利用position:relative;left:50%
正负抵消来实现
.content{
position: relative;
float: left;
left: 50%;/**父级设置50%**/
}
.text{
position: relative;
float: left;
left: -50%;/**子级设置-50%**/
}
复制代码
略微繁琐一点,不过也不失为一种方法,兼容性也极好
上述一共列举了8种实现方式,固然第一种属于实验性质的,兼容性少的可怜,但也不失为一种思路。怎么想到这些方法呢?
第一就是联想。好比上述提到了自适应(简单来说就是尺寸由内容决定),我就想哪些能够实现自适应呢?除了inline-block
,还有float
、position:absolute
、display:table
等...首先(通过试验,能够实现)。float
就排除了,元素设置了float
后,总体居中实际上是件麻烦的事,几乎不可能position:absolute
仍是挺有但愿的,借助left:50%;transform:translateX(-50%)
能够实现居中效果, 尝试了一番,发现宽度没法自适应父级宽度,一样失败(说不定能够,只是没有想到)~~最后选择了diaplay:table
,也算是按部就班。flex
和grid
就更不用说了,自然就是为弹性布局而生了,实现这类效果不奇怪。
第二仍是基础。CSS
属性可就那么多,那只是停留在表面,不少看起来不相关的属性在整个体系中又会有些微妙的关系,好比上面的width:fill-content
,单独看这个确定很鸡肋,彻底能够用inline-block
来代替,可是他却可让一个普通的div
元素具有inline-block
的特性,不得不佩服CSS
的设计~(确定有设计人员参与)
前一段时间在思考作一个可视化编辑工具,但愿能够经过一些属性,就像photoshop
那样,直接做出一个页面来,想一想看,发现只能做出最最基本的样式,也就颜色,大小什么的,若是要作成本文这样一个效果,八成是作不了的,除了自己是作开发,别人怎么可能知道这样设置呢?可视化编辑工具的道路还很长很长,因此作前端的也无需担忧被其余什么“一键生成工具”给取代了~
各位小伙伴若是还有其余实现方式可在下方留言评论,若是文章有错误请及时指出,谢谢~