css一些细问题
当margin的值为百分比形式时,为什么浏览器会根据父容器宽度得出计算值?
假如有一个父容器宽度400px,高度600px,其子元素设置 margin:20% 20%后的计算值应该为“margin:120px 80px”还是“margin:80px 80px”呢?在横向排版时,宽度“有迹可循”,可以把浏览器宽度作为参考,所以第二个正确,但是高度是不固 定的,所以margin百分比值在计算时会参考父容器的宽度。当书写模式改为纵向,其计算参考便会变为父容器的高度了。
margin:auto为什么只能实现水平居中,不能垂直居中?
当一个常规流中块级元素的margin属性左右值设为关键字auto,且它拥有固定宽度时,它便会平分剩余的水平空间,居中显示。然而如果设置上下值为auto,浏览器得到的计算值为0,并不起任何的效果。那么问题来了,为什么垂直方向的auto不生效?
与上一问类似,这与布局相关。网页排版时,常规流的块级元素水平方向总是铺满浏览器窗口,垂直方向各块级元素按照先后顺序从上往下排列,当页面内容过多时网页会出现纵向滚动条,因此原理上纵向是可以无限扩展的,计算时找不到一个固定的参考值,所以纵向的auto无法生效。
同样,margin:auto会受书写模式的影响。当书写模式为纵向时,margin:auto垂直方向是可以居中的,水平方向仍然可以居中。不 信?请自己写个demo试试吧。其实受到书写模式影响的属性除了这些外,还有margin折叠、padding百分比值的计算等。
margin折叠指的是毗邻的两个或多个外边距 (margin) 在垂直方向会合并成一个外边距。
触发条件:毗邻,没有被非空内容、padding、border 或 **clear 分隔开的margin特性. **非空内容就是说这元素之间要么是兄弟关系或者父子关系
这些 margin 都处于普通流中,即非浮动元素,非定位元素。
垂直方向外边距合并的计算:
- 参加折叠的margin都是正值:取其中 margin 较大的值为最终 margin 值。
参加折叠的margin都是正值:取其中 margin 较大的值为最终 margin 值。
- 参与折叠的 margin 都是负值:取的是其中绝对值较大的,然后,从 0 位置,负向位移。
<div style="height:100px; margin-bottom:-75px; width:100px; background-color: red;">A</div>
<div style="height:100px; margin-top:-50px; margin-left:50px; width:100px; background-color: green;">B</div>
- 参与折叠的 margin 中有正值,有负值:先取出负 margin 中绝对值中最大的,然后,和正 margin 值中最大的 margin 相加。
- 相邻的 margin 要一起参与计算,不得分步计算
要注意,相邻的元素不一定非要是兄弟节点,父子节点也可以,即使不是兄弟父子节点也可以相邻。
而且,在计算时,相邻的 margin 要一起参与计算,不得分步计算。
<div style="margin:50px 0; background-color:green; width:50px;">
<div style="margin:-60px 0;">
<div style="margin:150px 0;">A</div>
</div>
</div>
<div style="margin:-100px 0; background-color:green; width:50px;">
<div style="margin:-120px 0;">
<div style="margin:200px 0;">B</div>
</div>
</div>
以上例子中,A 和 B 之间的 margin 折叠产生的 margin,是6个相邻 margin 折叠的结果。将其 margin 值分为两组:
正值:50px,150px,200px
负值:-60px,-100px,-120px
根据有正有负时的计算规则,正值的最大值为 200px,负值中绝对值最大的是 -120px,所以,最终折叠后的 margin 应该是 200 + (-120) = 80px。
- 浮动元素、inline-block 元素、绝对定位元素的 margin 不会和垂直方向上其他元素的 margin 折叠
- 创建了块级格式化上下文的元素,不和它的子元素发生 margin 折叠
以 “overflow : hidden” 的元素为例:
<div style="margin-top:50px; width:100px; height:100px; background-color:green; overflow:hidden;">
<div style="margin-top:50px; background-color:gold;">B</div>
</div>
- 元素自身的 margin-bottom 和 margin-top 相邻时也会折叠
自身 margin-bottom 和 margin-top 相邻,只能是自身内容为空,垂直方向上 border、padding 为 0。
自身 margin-bottom 和 margin-top 相邻,只能是自身内容为空,垂直方向上 border、padding 为 0。
以上代码运行后,我们讲得到的是红色边框的正方形,方框的宽高都应该是 100px,高度不应该是 150px。
行内级元素可以设置宽高吗
置换元素可以,非置换元素不可以,如span,strong不可以,但是img,input,select,textarea等可以设置。置换元素本身拥有固有尺寸(高度,宽度,宽高比)的元素,不设置宽高时,会按照本身的宽高进行显示。
CSS规则根据优先级生效,低优先级的规则会被浏览器忽略还是覆盖?
多个优先级的样式都会被渲染,只不过高优先级会覆盖住低优先级,元素呈现为高优先级 的样式。现在请考虑这样一个问题,在一个div应用了两条background-image规则,照之前的理论来看,两条规则都会渲染,那么请问浏览器会 请求被覆盖规则的背景图片吗?真实情况是浏览器会聪明到只请求当前应用的背景图片
使用margin可以做出圆角按钮的原理是什么?
当不能使用border-radius时,如何制造一个圆角按钮?现在有一个制造1px圆角的小技巧:button中嵌套span,设置span的margin为:“margin:1px -1px”。原理就是利用视觉误差。
.btn {
padding: 0;
margin: 0 5px;
border: none;
background: #a5a5a5;
display: inline-block;
font-size: 26px;
}
<a class="btn"><span>1px圆角</span></a>
清除浮动有N种方式,他们间有什么共同点吗?
清楚浮动的方法
1 结尾处加空div标签 clear:both;
<style type="text/css">
.div1{background:#000080;border:1px solid red}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} /*清除浮动代码*/ .clearfloat{clear:both} </style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> <div class="clearfloat"></div> </div> <div class="div2"> div2 </div>
2 父级div定义伪类:after和zoom:ie8以上和非IE浏览器才支持:after,zoom(IE专有属性)可解决ie6,ie7浮动问题。
<style type="text/css">
.div1{background:#000080;border:1px solid red;}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} /*清除浮动代码*/
.clearfloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}
.clearfloat{zoom:1}
</style>
<div class="div1 clearfloat">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="div2"> div2 </div>
3 父级div定义 overflow:hidden
<style type="text/css">
.div1{
background:#000080;border:1px solid red;width:98%;overflow:hidden;}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px;width:98%}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
</style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> </div> <div class="div2"> div2 </div>
原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
优点:简单、代码少、浏览器支持好
缺点:不能和position配合使用,因为超出的尺寸的会被隐藏。
4 父级div定义 overflow:auto
<style type="text/css">
.div1{background:#000080;border:1px solid red;/*解决代码*/width:98%;overflow:auto}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px;width:98%}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} </style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> </div> <div class="div2"> div2 </div>
原理:必须定义width或zoom:1,同时不能定义height,使用overflow:auto时,浏览器会自动检查浮动区域的高度
优点:简单、代码少、浏览器支持好
缺点:内部宽高超过父级div时,会出现滚动条。
建议:不推荐使用,如果你需要出现滚动条或者确保你的代码不会出现滚动条就使用吧。
5 父级div 也一起浮动
原理:所有代码一起浮动,就变成了一个整体
优点:没有优点
缺点:会产生新的浮动问题。
建议:不推荐使用,只作了解。
6 父级div定义 display:table
<style type="text/css">
.div1{background:#000080;border:1px solid red;/*解决代码*/width:98%;display:table;margin-bottom:10px;}
.div2{background:#800080;border:1px solid red;height:100px;width:98%;}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} </style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> </div> <div class="div2"> div2 </div>
原理:将div属性变成表格
优点:没有优点
缺点:会产生新的未知问题。
建议:不推荐使用,只作了解。
7 结尾处加 br标签 clear:both
<style type="text/css">
.div1{background:#000080;border:1px solid red;margin-bottom:10px;zoom:1}
.div2{background:#800080;border:1px solid red;height:100px}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} .clearfloat{clear:both} </style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> <br class="clearfloat" /> </div> <div class="div2"> div2 </div>
原理:父级div定义zoom:1来解决IE浮动问题,结尾处加 br标签 clear:both
建议:不推荐使用,只作了解。
8 父级div定义 height
原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。
优点:简单、代码少、容易掌握
缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题
什么是hasLayout?
在InternetExplorer中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容。为了调节这两个不同的概念,渲染引擎采用了 hasLayout 的属性,属性值可以为true或false。当一个元素的 hasLayout属性值为true时,我们说这个元素有一个布局(layout)
当一个元素有一个布局时,它负责对自己和可能的子孙元素进行尺寸计算和定位。简单来说,这意味着这个元素需要花更多的代价来维护自身和里面的内容,而不是依赖于祖先元素来完成这些工作。因此,一些元素默认会有一个布局。当我们说一个元素“拥有layout”或“得到layout”,或者说一个元素“has layout” 的时候,我们的意思是指它的微软专有属性 hasLayout 被设为了 true。一个“layout元素”可以是一个默认就拥有 layout 的元素或者是一个通过设置某些 CSS 属性得到 layout的元素。如果某个HTML元素拥有 haslayout 属性,那么这个元素的 haslayout 的值一定只有 true,haslayout为只读属性 一旦被触发,就不可逆转。通过 IE Developer Toolbar 可以查看 IE 下 HTML元素是否拥有haslayout,在 IE Developer Toolbar 下,拥有 haslayout的元素,通常显示为“haslayout = -1”。
负责组织自身内容的元素将默认有一个布局,主要包括以下元素: body 、html;tabel、tr、td、th;img;hr;input、button、file、select、textarea、fieldset;frameset、frame、iframe等。
对于没有默认布局的元素,如何激发haslayout?
设置如下css属性即可:display:inline-block,height/width:(除auto任何值),float:left|right,position:absolue,zoom:除 normal 外任意值,
仅限IE7:overflow非visible,设置min-width或min-height
具有“layout” 的元素如果同时 display: inline ,那么它的行为就和标准中所说的 inline-block很类似了:在段落中和普通文字一样在水平方向和连续排列,受 vertical-align影响,并且大小可以根据内容自适应调整。这也可以解释为什么单单在 IE/Win 中内联元素可以包含块级元素而少出问题,因为在别的浏览器中display: inline 就是内联,不像 IE/Win 一旦内联元素拥有 layout 还会变成 inline-block。
zoom:1的原理和作用
Zoom属性是IE浏览器的专有属性, 它可以设置或检索对象的缩放比例、触发hasLayout、清楚浮动。
当设置了zoom的值之后,所设置的元素就会就会扩大或者缩小,高度宽度就会重新计算了,这里一旦改变zoom值时其实也会发生重新渲染,运用这个原理,也就解决了ie下子元素浮动时候父元素不随着自动扩大的问题。
BFC:块级格式化上下文
BFC自成体系,对自己内部的元素负责,不会与浮动元素重叠,上下margin不会重叠,清楚浮动或者实现一个双栏布局。如何构造一个BFC:1.float设置为非none值;2.overflow设置为非visible;3.display设置为 table-cell,table-caption,inline-block;4.position设置为absolute或fixed。
ie6/7没有BFC概念,但是有一个与BFC性质相似的概念:layout。在IE6,7中遇到的很多bug都可以通过让元素has layout来解决,比如浮动margin双边距,躲猫猫,3像素间距等等。
9.图片和文字居中
<p>
<span style="vertical-align:middle;">hello</span>
<span style=''background(url(...)) vertical-align:middle;'"/>
</p>