最近看到一篇20 个CSS高级技巧汇总的汇总,感触很深,不过我想,与技巧相比,有些常见css布局难题,有时候更加让咱们的平常开发变得踌躇沮丧吧。
在写这一篇文章以前,本身还写过一篇:我所不注意的那些CSS冷知识,但却阻止了我作项目的速度,若是你看了,我相信你也会受益的。css
这是我在segmentfault上看到的一个问题,之前本身遇到过,因此就很热情洋溢的去回答了一下,难道遇到个本身会的,示例代码是这样的:
CSS:html
li{ display: inline-block; text-align: center; } .left,.center,.right{ width:300px; height:300px; } .left{ background-color: #999; } .center{ background-color: #ccc; } .right{ background-color: #eee; } HTML: <ul> <li class="left"> <p style="display: inline-block;">1</p> </li> <li class="center"></li> <li class="right"></li> </ul>
大概就是这样子,其实文和图有点不对应,代码中第一个模块他只写了一个“1”,我为了现象更加明显,且好说明为何,就打了一大段文字,如今咱们来讲说为何。先来一张图,看懂vertical-align的几个属性,顺便带上图片出处,文章讲得还能够,理解这张图片,后面就好理解了。canvas
inline-block的vertical-align 属性默认是baseline对齐(深刻理解的送福利),也就是英文文字小写字母a,b,c这类字母底部的那条线,由于这些是外国人发明的,因此以英文字母才有针对性。inline-block拥有vertical-align属性,其默认是基线对齐的,因此这三个inline-box须要基线对齐,而其基准线就是正常流中最后一个line box的基线,若是这个元素是空的,没有内容,那么这个基线就是最后这个元素的margin-bottom线;若是这个元素不为空,那么这个元素的基线就是元素里面内容最后一行文字的基线;因此咱们一个一个来套,发现这三个li元素在一行,第一个有文字,其基线为文字底部;最后一个没有文字,其基线为margin-bottom线,考试要考,划重点,能够本身为元素设置margin-bottom试试,这就会形成第一个和二,三个错行的感受,其实他两是为了基线对齐,因此多敲几十个文字就能明显看出其差异。因此最简单的解决方案就是为li添加vertical-align: 属性不为baseline,气不气,改变其纵向的对齐方式的默认属性;为啥非弄个折腾人勒。关于vertical-align,若是还想作这方面的深刻了解,能够看看张大侠的分析segmentfault
直接上图更直观(箭头所指):
相关css和html:浏览器
<style> body,div{margin: 0;padding: 0;} .test{ background-color: yellowgreen; } img{ width:260px; height:260px; } </style> <body> <div class="test"> <img width="130" height="130" src="https://user-gold-cdn.xitu.io/2017/12/10/160409cc0f090c6f"> </div>
</body>
其实这个问题,若是你单单这样看,和我同样涉世未深的话,是一眼看不出答案的,可是若是你在图片后面多敲两个文字,你就会发现,和上个问题,这又是一个有关于vertical-align属性相关的问题。wordpress
<div class="test"> <img width="130" height="130" src="https://user-gold-cdn.xitu.io/2017/12/10/160409cc0f090c6f"><span>abcd看文字</span> </div>
让人恍然大悟的效果图:
这下你应该就懂了,下面的空隙的距离实际上等与1个line-height的底边与baseline之间的间距。仔细观察,图片的底边是和a的下边缘是在一条水平线上的,而不是和‘看’字下边缘一条水平线上的。因此为何上面说这又是一个和vertical-align属性相关的问题。先说解决方案
针对于父元素div:布局
针对于图片div:测试
也许到这里,你和我同样,有疑惑,为何vertical-align是一个对块状元素无效的属性,设置img为块级元素,其和div就能够完美在一块儿,而一个内联元素放在块状元素里,就非得有隔阂。开始,我也是有这个疑问的,我的理解就是块状元素里面装了一个内联元素,若是块状没有显示的设置高度,其高度是由里面的最高的lineboxes组成的,这个div其实就是有两个lineboxes组成,图片linebox和<span>,其实还有一个linebox就是div自身的innerText(''),这不过这里内容为空,若是你把span去掉,你就更能理解这个隐身的linebox,因此就像是两个内联元素在一块儿,须要baseline对齐。因此网上有人说设置img{font-size:0;},是很是错误的,img元素很特殊,他不可是内联元素,他仍是一个置换元素(下面会讲),它的高度不是文字内容撑开的,是其置换的图片高度撑开的,因此设置font-size是无效的。字体
像上图那样的形式,盒子由导航栏和右侧一个搜索框或者登陆名什么的一块儿组成,这也是咱们经常使用浮动的方式来解决这样的布局。
说浮动前,先说三点概念:
1.浮动最初出现的意义是为了解决文字环绕图片这种在杂志报纸中常会出现的布局样式; (看下图)
2.浮动与绝对定位能实现相同的效果,但的区别是,浮动未脱离正常文档流,但绝对定位脱离了正常文档流;
3.浮动能带来灵活的布局,但同时也带来了父元素高度塌陷的缺点(看下图),因此清除浮动是使用浮动前的必修课,后面会说到;
如今看一下高度塌陷相关的代码:flex
<div class="test"> <img width="130" height="130" src="https://user-gold-cdn.xitu.io/2017/12/10/160409cc0f090c6f"> 1.浮动最初出现的意义是为了解决文字环绕图片这种在杂志报纸中常会出现的布局样式;<br> 2.浮动与绝对定位能实现相同的效果,但的区别是,浮动未脱离正常文档流,但绝对定位脱离了正常文档流;<br> 3.浮动能带来灵活的布局,但同时也带来了父元素高度塌陷的缺点,因此清除浮动是使用浮动前的必修课,后面会说到;<br> <br> </div> <div class="blank"></div> <div> <div class="box"> <span class="dot"></span> 我是下面一个div的文字。 </div> <div class="blank"></div> <div class="box"> <span class="dot"></span> 我是再下面一个div的文字。。 </div> <input width="260" value="输入一段文字"/> </div> .test { background-color: yellowgreen; font-size: 18px; vertical-align: top; } .test span { background-color: bisque; } .blank { line-height: 20px; height: 20px; } img { width: 260px; height: 260px; float: left; } input { border: 1px solid red; height: 24px; margin-left: 30px; } .box { background: black; color: white; padding-left: 20px; line-height: 10px; } .box .dot { display: inline-block; width: 4px; height: 4px; background: white; vertical-align: bottom; }
图片一中,实现了文字环绕图片那种想要的效果,而且后面的元素没有上移错位,其缘由是上面说过的,若是块状元素没有显示的设置高度,其高度由其元素内的最高的linebox决定,因此第一张图片div的高度是比img高度高的,由于我重要的事情说了三遍,文字够多。而第二张图片,div高度只有144px,由于img是浮动的,他的linebox被浮动属性破坏了,而文字又不够多,因此就形成了所谓的高度塌陷,导致最后两个div陷进了图片所在的div中,要知道,这种状况在正常块状元素布局中是根本不会出现的。至于解决浮动引发的高度塌陷,我总结了两条,分别是:
清除浮动,相信你们都懂,而触发bfc。
我说说我经常使用的几条,网上讲bfc的不少:
除了上面讲的这些,我还遇到过有人问,为何我用了浮动,但元素没有浮在这一行,却换了行,像下图这样
<div> <div class="gr">我是导航栏的一些文字</div> <div class="fr">我想浮在右边</div> </div> .gr{ background-color: yellowgreen; margin:5px; } .fr{ float:right; background-color: green; }
上面这种没按想要的方式浮,是由于块状元素会不敢其内容长度有没有一行的长度,其都会占据一行的长度,后面的元素会自动换行。解决这个其最简单的方式就是将fr元素放在gr元素前,为何这样就能够,由于float破坏了div元素的块状属性,但其未撑开父元素的高度,其浮动属性为right,默认从右侧开始布局,因此后面的div仍按正常的文档流从最左端开始布局。
若是你看上面一题代码的时足够细心,你会发现我给img设置了width和height两个属性值为130,但因为又在css属性里定义了宽高260,但最终表现出的宽高为260。若是css不定义宽高呢?答案是多少,要不你试试,你慢慢试,我仍是先公布答案:130.这里咱们将会说一个css中的一个不为人知的术语:置换元素,那什么又是置换元素呢?
置换元素是指:浏览器根据元素的标签和属性,来决定元素的具体显示内容。
例如:浏览器根据<img>标签的src属性显示图片。input元素根据标签的type属性决定显示输入框仍是按钮。还有,还有近来很火的canvas。
置换元素有以下共同点:
感受要写的还有不少,事件根本不够用,先睡了,未完待续 若是文中有任何不足和错误之处,还请及时指正。