04|盒尺寸三大家族

2019-11-28  本文已影响0人  井润

01|深入理解Content

01|content和替换元素

根据是否具有可替换的内容,我们也可以把元素分为替换元素和非替换元素,那么什么是替换元素?

其实所谓的替换元素就可以被替换的元素就称之为"替换元素" , 因此对应的标签 img object video iframe 和表单元素 textarea和input都是典型的替换元素!

当然替换元素还有以下特性:

02|替换元素的尺寸计算规则

替换元素的尺寸从内而外分为3类:

固有尺寸,其实就是替换内容原本的尺寸! 不加修饰的默认尺寸!

HTML尺寸 通过HTML原生属性改变

CSS尺寸通过width和height或者说max-height或者是min-width设置的尺寸!

对应盒子尺寸!

其中三者的关系 层层递进 CSS尺寸===> HTML尺寸===> 固有尺寸

固有尺寸有其固有的宽高比例

Wbe开发的时候,为了提高加载性能以及节约贷款费用,首屏以下的图片通过滚屏进行异步加载,但是为了布局稳健,体验良好一般都是使用的图名的图片占位:

<img src="transparent.png" >
<!-- 其实直接可以使用 img --> 
<img >
<style>
    img{visibility:hidden;}
    img[src]{visibility:visible;}
</style>

这里的img是直接没有src属性的,直接没有的话图片是没有任何请求的,是最高效的实现方式!

CSS世界中的替换元素的固有尺寸有一个很重要的特性,其实就是"我们无法改变这个替换元素内容的固有尺寸的!"

那么可能问题来了,及让说替换元素的固有尺寸无法改变,那么对应的我们设定的width和height会影响图片的尺寸呢?

03|替换元素和非替换元素的距离有多远?

观点1. 替换元素和非替换元素之间的间隔只隔了一个src属性!

其实我们都有一种思维定视,认为<img> 等同于图片,如果我们把src属性去掉的话,其实<img> 就是一个和span类似的普通内联元素,也就是一个非替换元素!

img{display:block;outline:1px solid;}

其中图片的宽度为多少?

最终的宽度其实就是100%适应父容器,其表现和span类似,已经完全不是替换元素了! 现在应该懂了FireFox浏览器下面img设置width和height不起作用了吧

其实该示例,也很好的说明了,"如果图片没有替换内容,图片就是一个普通的内联标签!"

当然对应的Chrome需要通过特定的条件进行触发才行

<img alt="任意值" />

这个很好理解,但是为什么IE没有对应的src属性的同时,还是完全的替换元素呢?

原因在于IE浏览器中有一个默认的 占位替换内容,当src属性缺失的时候,会使用默认的占位内容! 在IE8浏览器下面,这个占位内容全然暴露了,可以参照书籍里面得 4-8图片! (该图标并非打叉的小图标或者是破裂的小图标!)

其实还有一种方法证明 替换元素和非替换元素区别在于src属性,就是基于伪元素的图片生成技术! 可以对img元素使用 ::before和::after伪元素进行内容生成以及样式构建,但是该方法的支持是有限制的! 首先是兼容问题! Chrome和FireFox都能够兼容,但是IE浏览器却不支持! 如果要让Chrome和FireFox等浏览器生效的话,其实需要注意的技术点如下:

  1. 不能有src属性

  2. 不能够使用content属性生成图片 (针对Chrome)

  3. 需要有alt属性并优质!(针对Chrome)

  4. FireFox下面::before元素的content只会被无视,但是after并不会 与FireFox自己占用了::before的元素的content属性相关!

基于伪元素的图片内容生成技术,并不属于实用技术,但是实际网页开发的过程中,必须使用到该元素,此时这些隐藏的技术往往就会有神迹表现!

​ 使用缺省的src的img元素实现滚屏加载效果,如果说javascript加载比较慢的时候页面可能出现一块一块白色的图片区域,没有任何信息,用户体验差,虽然说alt能够提示具体的图片描述,但是由于视觉效果不好,就被隐藏掉了! 如果说图片还没加载的时候就能把alt信息呈现出来多好啊!

此时的src没有因此对应的::before和::after可以生效,因此可以如下所示去写代码:

img::after{
    content:attr(alt);
    position:absolute bottom;
    width:100%;
    background-color:rgba(0,0,0,0.5);
    transition:transform 0.2s;
}
img:hover::after{
    transform:transkateX(0);
}

见图片4-10

观点二:替换元素和非替换元素之间只隔了一个CSS content属性!

替换元素之所以为替换元素,就是因为其内容可替换,其内容就是 content-box,因此可以明白content属性决定了是替换元素还是非替换元素!

在Chrome浏览器下面,所有的元素都支持content属性,而别的浏览器下面只有::before和::after才可以支持content属性!

img:not[src]{content:url(1.jpg);}  ====> /*<img src="1.jpg"/> */

其实上面视觉效果是一摸一样的!

因此在Chrome浏览器中我们可以很轻松的通过content属性对元素的内容进行修改操作! (详情请见:https://demo.cssworld.cn/4/1-4.php)

content属性改变的仅仅只是视觉呈现,当我们以右键或者其他形式保存这张图片的时候保存的还是原来src对应的图片!

不仅如此,使用content属性,我们可以将普通的元素变成替换元素,举个例子,官网的标志往往都会使用<h1></h1>标签 里面会有网站的名称和标志图作为背景图使用,如下面的代码:

<h1>css world</h1>

<style>
    h1{
        width:180px;
        height:36px;
        background:url(logo.jpg)
        text-indent:-999px;/*文字隐藏!*/    
    }
</style>

尺寸规则还是替换元素的规则,完美适应原始图片大小,虽然说视觉效果上的文字被替换了,但是屏幕阅读设备阅读的还是文字,搜索引擎SEO抓取的还是原始的文本信息,因此对页面的可访问性等没有任何影响!

但是,虽然说我们这样看着没什么问题,但是,其实还是存在一些局限性的,替换元素的尺寸是无法设置的,如今移动端的retina屏幕已经是标配了,为了更好的视觉体验,真实图片往往是显示图片尺寸的两倍,于是问题来了,使用content生成图片我们是无法设置图片的尺寸的,只能迫不得已使用一倍图,然后导致图片看上去有点儿模糊!

因此我们建议在移动端上面使用SVG矢量图片!

03|content与替换元素的关系剖析

CSS世界中content属性生成的对象称之为"匿名替换元素" 他们的属性不是微妙,而是赤裸裸的!

其实 content生成的内容都是替换元素,没错 就是替换元素!

正因为是替换元素,才与普通元素有诸多不同,我们使用Content生成的内容是无法被选中的,就像是user-select:none; 声明一般,但是普通元素的文本可以被轻松选中,同时content生成的文本无法被屏幕设备读取! 也无法被搜索引擎抓取!

这其实也引出了重要的内容:

有人可能会说无法被选中可能是伪元素的原因而并非替换元素的原因,我们可以使用::first-lette对比一下,可以选中,但是::before和::after内容却无法被选中,因而可以确定多半content的原因而并非伪元素的原因!

不能左右:empty伪类. :empty是一个CSS选择器,当元素里面无内容的时候进行匹配,

空格也算内容,伪元素不算内容!

content动态生成的值无法获取!

content是一个强大的属性,其中比较厉害的就是一个计数器!

.total::after{content:counter(icecream);}

我们无法获得此时content对应的具体数值为多少,一点儿办法也没有!

04|content的内容生成技术

其实content应用最多的地方还是在::before中和::after中,但是CSS世界中主要讲的是针对IE8及以上版本的浏览器!

而对应的IE浏览器仅支持单冒号的伪元素,一般使用的时候将对应的content数值值设置为空字符串!

其实这样做的好处是,会让HTML代码会显得更加干净和精简!

.clearfix{
    content:'';
    display:table;/*block*/
    clear:both;
}

预览请见:https://demo.cssworld.cn/4/1-7.php

常见的应用就是配合@font-face 规则实现图标字体效果

详情请见:https://demo.cssworld.cn/4/1-8.php

详情请见:https://demo.cssworld.cn/4/1-9.php content换行符与打点loading效果实例页面

02|温和的padding属性

在盒尺寸中,padding的性格是最温和的,并且padding指的是 内补间 这个词比较术语化,其实可以简单理解为蛋白! 鸡蛋中的蛋壳 蛋白 蛋黄!

因为在CSS中默认的box-sizing是content-box,所以我们使用padding的话会增加元素的尺寸!

.box{width:80px;padding:20px;}

如果说不考虑到别的元素的干扰的情况下那么对应的宽度就为120px; 但是这样的话是不符合现实世界的认知的,人们总是习惯把代码世界和现实世界做映射,导致人们总在使用padding的时候遇到坑,于是乐此不疲的直接将box-sizing设置为border-box!

其中作者也提到了不推荐这种做法:重置box-sizing,更何况是全局重置,尽量采用无宽度以及宽度分离准则的情况下实现才是好的解决方法!

但是很多人认为,重置了box-sizing:border-box; 这样设置了元素尺寸就不会发生变化,但是大部分人没有考虑到的事,如果说padding足够大的话,那么对应的width也就无能为力了!

.box{
    width:80px;
    padding:20px 60px;
    box-sizing:border-box;
}

那么此时的width就无效了,最终的宽度为120px(60px2) 里面的内容表现为"首选最小宽度*"

但是padding表现在内联元素上面的话则不一样!

同样的会在垂直方向上影响布局,影像视觉表现,只是内联元素没有对应的可视宽度和可视高度的说法,垂直方向上完全受行高和对应的垂直对齐影响的!

但是视觉上面并没有改变上下行的间距,我们的感觉就是垂直padding没有起到对应的作用!

但是如果说,给对应的内联元素添加背景色或者说边框的话,确实能够看到尺寸空间的变化(受到了padding的影响!)!

详情请见:https://demo.cssworld.cn/4/2-1.php

虽然说尺寸发生了变化,但是上下元素的原有布局却没有任何影响,仅仅是垂直方向上发生了层叠!

不影响其他元素布局而是出现层叠效果的现象

如何区别层叠效果到底是纯视觉层叠还是非纯视觉层叠呢?

父容器 overflow:hidden 如果说层叠区域超出父容器的时候没有滚动条出现 那么就是纯视觉的否则就是影响布局的那种!

如果说内联元素的padding有用的时候,那么对于我们实际应用CSS的时候有什么实质性的帮助吗?

01|padding的百分比值

但是padding的百分比值计算规则和height还是有些不同的,padding的百分比值的计算规则不管是水平还是垂直都是相对于宽度计算的!

那么为什么会相对于width计算而不是height计算呢?

因为如果说相对于height计算的话,大多数情况下都是0,那么跟摆设是没有什么区别的!

还不如相对计算的! 相反因为CSS默认的水平流,计算值一直都会有效,并且还能够利用这个特性实现一些有意思的布局效果!

当然一般的就是网页开发的时候经常会有横贯整个屏幕的头图效果,使用padding进行等比例控制,在小屏幕下面的时候高度天然等比例缩小,没有任何javascript的时候,却依然适配良好!

预览请见:https://demo.cssworld.cn/4/2-3.php

02|标签元素内置的padding

其中介绍了很多人可能不知道的关于padding的一些小秘密,ol/ul列表内置的padding-left,但是单位是px而不是em,例如Chrome浏览器下面是40px,因此对应的元素和左边缘距离受制于font-size的大小!

还有就是很多表单元素都内置了对应的padding!

其实最明显的就是button按钮了,在不同的浏览器中高度计算下的button的padding值都千差万别,但是为了更好地兼容的话可以这样去处理

<button id="btn"></button>
<label for="btn">按钮</label>
<style>
    button{position:absolute;clip:rect(0,0,0,0)}
    label{display:inline-block;line-height:20px;padding:10px;}
</style>

其实这样一来的话在所有的主流浏览器中的按钮高度都是为40px,就很好的解决了button的高度在不同高度计算的浏览器下面的表现不同的问题了!

label元素中的for对应的值和元素的id值想通就行了!

03|padding与图形绘制

预览请见:https://demo.cssworld.cn/4/2-4.php

03|激进的margin属性

虽然说padding比较温和,但是所谓的margin就比较激进了,负责外间距,虽然都是间距但是两者的差别还是很大的,有此事margin,比较奇怪的地方还是比较多的!

01|margin与元素尺寸以及相关布局

其实之后的内容会过多的涉及到尺寸,为了更好的甄别这个名词,把相关的概念梳理一下

其中margin最大的不同其实就是margin的值可以是负值,但是如果说我们将 外部尺寸理解为 元素占据的空间尺寸 可能就好理解得多了吧!

02|margin与元素的内部尺寸

如果说元素设定了对应的width或者保持 包裹性 的时候,margin对尺寸没有影响,只有元素是 充分利用可用空间,状态的时候,margin才可以改变元素的可视尺寸!

.father{width:300px;margin:0 30px;/*如果是这样的话 那么对应的元素尺寸不会发生任何变化!*/}

但是如果过说充分利用可用空间的话就能够使用margin进行设定!

<div class="father">
    <div class="son">
    </div>
</div>
<style>
    .father{width:300px;}
    .son{margin:0 -20px;}
</style>

这样一来对应的class为son的元素的宽度就是为340像素了!

只要元素的尺寸表现符合"充分利用可用空间",无论是垂直方向上还是水平方向上,都可以通过margin改变尺寸!

由于margin具有这种流体特性下的改变尺寸的特性,所以很多时候可以使用margin方便的实现很多流体布局的效果:

预览请见:https://demo.cssworld.cn/4/3-1.php

可以利用margin实现顺序完美一致的自适应效果 借助margin负值定位进行实现!

当然还能够利用margin的特性实现两端对齐我们设置三个元素在一行中,同一设定margin-right的话最后一个会有多余的控件!

因此维护起来比较麻烦,但并不是没有办法解决的:

ul{margin-right:20px;} /*ul 的width就为 100%+20px*/
li{float:left:margin-right:20px;width:100px;}

这样一来的话 最后的li元素的margin-right:20px;此时的位置 也就对应了 ul右边缘的宽度位置!

03|margin与元素的外部尺寸

对于普通块状元素,在默认的水平流下面,margin只能够改变元素的左右方向的内部尺寸!垂直方向上则无法改变!

如果说使用writing-mode改变流向为垂直的话,那么则水平方向内部尺寸无法改变,垂直方向可以改变,这是由margin:auto的计算规则决定的!

margin属性的影响更为宽泛,只要元素具有块状特性,无论有没有设置width/height无论是水平还是垂直方向,即使发生了margin合并,margin对外部尺寸都着着实实发生了影响! 实际上很多棘手的问题都是需要再借助Margin外部尺寸的特性来实现的!

其中子元素的高度超过content box的尺寸大小 触发滚动条显示,如果说留白效果的话 使用padding是不推荐的,推荐使用margin,滚动容器的底部留白也只是推荐margin-bottom实现!

还有一种应用就是,使用margin来实现等高布局:

预览请见: https://demo.cssworld.cn/4/3-2.php

其中最常见的问题就是: 为什么可以实现等高布局呢?

无法改变元素的内部尺寸,但是可以改变元素的外部尺寸,这样通过margin-bottom和padding-bottom一正一负相互抵消,虽然说在布局层面没有什么太大影响,但是带来了我们需要的东西 9999px高度的可使用的背景色,但是数值太大了,因此使用了overflow:hidden把多余的部分隐藏掉了! 因此视觉层面就是等高的效果了!

04|margin的百分比值

不管是padding还是margin百分比都是相对于width计算的,但是margin百分比的应用价值就比padding小了一节,元素设置margin在垂直方向尚无法改变元素自身的内部尺寸,往往需要父元素做为载体! 又因为margin合并的问题存在,垂直方向上面的往往需要双倍尺寸才能和padding表现一致!

05|正确看待margin中的合并

margin合并的条件如下:

margin合并的常见三种情景:

如何阻止margin-top合并的发生呢?

如何阻止margin-bottom合并的发生呢?

其中涉及到了块级格式化上下文的内容部分,具体详情:

其中比较重要的部分,也就是空块级元素的margin合并:

其实是合并了三次的,如果两个块级元素中加了一个空元素的块级标签!

第一个padding-bottom和第二个的padding-top 以及第三个的padding-top和中间的padding-bottom

之后呢 中间的margin你被合并之后了,第一个和第三个继续进行合并, 从第一个的padding-bottom和第三个的padding-top进行合并之后! 总共合并了三次!

如果说不希望空标签里面有对应的margin合并,那么可以进行如下操作:

其中涉及到了对应的margin合并规则的话,有以下三个

  1. 正正取大值
  2. 正负值相加
  3. 负负最负值!
06|margin合并的设计初衷

CSS世界的CSS属性一定是为了更好的图文展示 为了更好的布局体验!

其实自身margin合并的意义在于可以避免不小心遗落或者生成的空标签影响排版和布局!

07|深入理解CSS中的margin:auto

margin:auto的规则如下

明明容器定高元素定高那么margin:auto却无法垂直居中?

其实出发margin:auto计算有一个前提条件,就是width或者说height为auto的时候,元素是具有对应方向的自动填充属性的!

水平垂直居中的方法:

.son{
    position:absolute;top:0;right:0;bottom:0;left:0;
    width:200px;height:100px;
    margin:auto;
}

预览请见:https://demo.cssworld.cn/4/3-5.php

通过格式化宽高并且使用margin:auto自动分割垂直和水平方向的空间!

08|margin无效情形解析
  1. display计算值inline的非替换元素的垂直margin是无效的, 对于内联替换元素垂直margin有效,并且不存在margin合并问题,因此图片永远都不会margin合并!
  2. 表格中的tr或者说td元素 或者说设置display计算值是table-cell或者是table-row元素的margin都是无效的!
  3. margin合并的时候,更改margin值可能是没有效果的,
  4. 决定定位的非定位方位的margin "无效",是什么意思呢? 主要是因为绝对定位元素的渲染是独立的,而普通兄弟元素是心连心,但是绝对定位元素是无法印象兄弟元素定位的,因此对应的margin就无效了!
  5. 定稿容器子元素的margin-bottom或者宽度定死的子元素的margin-right的定位失效!
  6. 鞭长莫及的margin无效
  7. 内联特性导致的margin无效,

04|功勋卓越的border属性

为什么这么说呢,主要是边框在我们设计网页的时候确实起到了很多作用,并且与此同时,其良好的兼容性和稳定的特性表现菜的次荣耀的!

为什么不支持百分比值

其实border-width还支持一些默认值:

  1. thin 薄薄的 等同于1px
  2. medium(默认) 薄厚均匀 等同于3px
  3. thick 厚厚的 等同于4px

可能有些人会问 为什么不是thin为默认值呢?

因为border-style:double对应的数值最起码3px才有效果!

01|了解border-style

是的对应的border-style默认值为none 我们使用的时候 使用 border:1px solid red; 是通过重置边框样式的时候出现的!

这样一来的话如果需要一个圆我们可以使用对应的border的属性来实现了!

当然还有其他的border-style

分别为: inset 内凹 outset 外凸 groove 沟槽 ridge山脊

border-color和color

有一个很重要但是很实用的特性,border-color默认颜色其实就是color色值, 当然没有制定对应的色值的时候 会使用当前元素的color计算值作为边框色!

02|border与透明边框技巧
.box{
  border-right:50px solid transparent;
  background-position:100% 50%;     
}

优雅的增加点击区域的大小

其实可以利用透明的border进行处理:

.icon-clear{
    width:16px;height:16px;
    border:11px solid transparent;
}

后面有很多对border的应用!

上一篇下一篇

猜你喜欢

热点阅读