元素位置和大小的计算是相对于一个特定的长方形,这个长方形叫做包含块。w3c对包含块的定义。元素的相对位置与元素的绝对位置。CSS2.1规范,一旦浏览器解析了一个文档并且创建了文档树,浏览器必须为文档树中的每一个元素指定其每一个CSS属性,属性值最终确定需要经过四个步骤。计算值应该是CSS特性定义的”计算后的值”一行所标明的值;在处理计算值的过程中,文档没有被格式化,因此,有些值是无法确定的。比如,百分比宽度的元素,最终宽度是与它包含块的宽度有关, 所以,值只有在包含块确定下来之后才能确定。可以说,使用值是将计算值和有依赖关系的值最终转化成的绝对的值。关于使用值,可以直接使用浏览器开发者工具查看,在Firebug中,使用值就是”计算出的样式”。Chrome里则是”Computed Style”。

1、整个大背景是这个网页的全部尺寸,中间的小框才是浏览器中的可见尺寸。 这幅图就是针对为文档(document)的各个height、width、top、left所做的说明。

2、该图主要是针对网页中一个div的各个属性值所做的说明。“DIV element client area”是这个div元素的可见区域,“scroll area”是这个div内容原始尺寸,但是由于div的css所设置的高度宽度容不下它的内容,所以出现滚动条。

3、关于height:100%:要想高度百分比起作用,一般来说,要满足两个条件:其一,父标签有高度可寻,就是向上遍历父标签要找到一个定值高度,如果中途有个height为auto或是没有设置height属性,则高度百分比不起作用;其二,标签本身的属性,如果inline属性的标签,如果没有浮动,zoom,或是绝对定位之类属性是不支持百分比高度的,block或inline-block属性可以说是高度百分比起作用的前提条件之一吧。
4、对html与body的理解:(chrome浏览器非最大化时的边框大小约8px)

5、给body或documentElement的scrollLeft、scrollTop赋值,浏览器在没有出滚动条的时候,赋值后该值不会发生变化,始终是0。document.documentElement.scrollTop存在bug,Chrome中会是0。window.pageYOffset是滚动条距离顶部的偏移量。
6、原本在html中,只有链接a和表单元素可以被键盘访问(即使是a也必须加上href属性才可以),但是aria允许tabindex指定给任何html元素。如果其他元素也要支持tab键盘访问,需要设置tabindex属性,当tabindex是正数的时候,可以通过鼠标、tab键、js进行foucs。当是负数的时候,不能通过tab键,只能通过鼠标或js进行focus。
7、所谓“键盘可访问性”,指的是用户只使用键盘访问网站的能力。例如,我们的iMac鼠标没电了,或者鼠标坏了,或者在智能电视中访问我们的网站,此时就只能依赖于键盘访问了。Tab键索引和Enter键点击是与交互相关的最重要的两个键盘行为。一般的操作行为是这样的,先Tab键按次序不断focus控件元素,包括链接,按钮,输入框等表单元素或者focus设置了tabindex的普通元素,处于focus状态元素,浏览器一般会通过虚框或者外发光的形式进行区分和提示,此时我们在按下Enter回车键,就相当于鼠标点击了这个元素,从而可以前往我们想去的目的地,或者执行我们想要的交互效果。
8、现在的网站越来越注重残障人士了,很多网站都开始有专为视力不好的人们制作一些便捷通道,方便他们进行浏览网页。document.activeElement属性始终会引用DOM中当前获得了焦点的元素。元素获得焦点的方式有用户输入(通常是按Tab键)、在代码中调用focus()方法和页面加载。HTML5除了新添加了document.activeelement属性,还添加了document.hasfocus()方法。这个方法用于确定文档是否获得了焦点。document.activeelement属性始终会引用DOM中当前获得了焦点的元素。元素获得焦点的方式有用户输入(通常是按Tab键)、在代码中调用focus()方法和页面加载。默认情况下,文档刚刚加载完成的时候,document.activeelement中保存的是document.body元素的引用。文档加载期间,document.activeelement的值为null。通过document.activeelement可以判断文档是否加载完成。
9、当一个元素设置tabindex属性值为-1的时候,元素会变得focusable,所谓focusable指的是元素可以被鼠标或者JS focus,在Chrome浏览器下表现为会有outline发光效果,IE浏览器下是虚框,同时能够响应focus事件。但是,却不能被键盘focus。这种鼠标可以focus,但是键盘却不能focus的状态,只要tabindex属性值为负值。
10、临时改变页面索引起始位置:当我们点击按钮并显示一个弹框的时候,Tab键的索引起始位置应该是从弹框元素开始的,但是如果我们不做任何处理,索引起始位置还是弹框背后的页面,此时想要通过Tab键一个一个索引到弹框元素,估计天都已经黑了,很显然,为了达到完美的键盘交互体验,我们就需要额外做点事情。1、给弹框容器元素设置tabindex=”-1”;2、弹框显示的时候容器元素DOM.focus()使其获取焦点;3、容器元素CSS设置outline:none。
11、直接使用display:none隐藏,或者visibility:hidden隐藏,会导致隐藏的控件元素压根没法通过键盘让其显示,因为这两种隐藏方式会让元素无法被focus,那该怎么办呢?可以试试使用透明度opacity控制内容的显隐,于是,我们就可以通过:focus伪类让按钮focus时候可见。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
tr .btn {
opacity: 0;
filter: alpha(opacity=0);
}
tr:hover .btn,
tr .btn:focus {
opacity: 1;
filter: none;
}

:focus + label.btn {
outline: 1px dotted Highlight;
outline: 5px auto -webkit-focus-ring-color;
}

12、判断页面是否出现垂直滚动条

1
2
3
4
5
6
7
8
9
10
// document.body.clientWidth < fullWindowWidth 判断页面是否出现滚动条
Modal.prototype.checkScrollbar = function () {
var fullWindowWidth = window.innerWidth
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
var documentElementRect = document.documentElement.getBoundingClientRect()
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
}
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
this.scrollbarWidth = this.measureScrollbar()
}

13、获取滚动条的宽度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 // 1、top: -9999px; 页面并不会出现滚动条
// 2、overflow: scroll; 模拟滚动条并计算宽度
.modal-scrollbar-measure {
position: absolute;
top: -9999px;
width: 50px;
height: 50px;
overflow: scroll;
}
Modal.prototype.measureScrollbar = function () { // thx walsh
var scrollDiv = document.createElement('div')
scrollDiv.className = 'modal-scrollbar-measure'
this.$body.append(scrollDiv)
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
this.$body[0].removeChild(scrollDiv)
return scrollbarWidth
}

14、

1
2
3
4
5
6
7
8
9
// 调整窗口 更新弹框状态 modalIsOverflowing判断是否滚动
Modal.prototype.adjustDialog = function () {
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight

this.$element.css({
paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
})
}

15、对于普通元素而言,上下键是不会自动选中控件元素的,只会滚动页面,面对这种场景,我们需要一段额外的脚本对:focus出现的下拉内容进行索引控制和回车支持。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//键盘事件
doc.addEventListener('keydown', function (event) {
// 是否是上下左右键
var direction = keycode[event.keyCode];
if (!direction) {
return;
}
if (direction == 'tab') {
classList.removeAll();
return;
}
// 当前激活元素
var trigger = doc.activeElement;
if (!trigger) {
return;
}
// 对应的面板
var attrTarget = trigger.getAttribute('target') || trigger.getAttribute('data-target');
var target = attrTarget && doc.getElementById(attrTarget);
if (!target) {
return;
}
// 需要是显示状态
if (target.clientWidth == 0 && target.clientHeight == 0) {
return;
}
// 如果是回车事件
if (direction == 'enter') {
var eleFocus = target.querySelector('.' + className);
if (eleFocus) {
// 阻止默认的回车
event.preventDefault();
eleFocus.click();
return;
}
}
// 如果都符合,同时有目标子元素
var arrEleFocusable = target.storeFocusableEle, index = target.storeIndexFocus;
if (!arrEleFocusable) {
arrEleFocusable = [].slice.call(target.querySelectorAll('a[href], button:not(:disabled), input:not(:disabled)'));
target.storeFocusableEle = arrEleFocusable;
target.storeIndexFocus = -1;
index = -1;
}
if (arrEleFocusable.length == 0) {
return;
}
// 先全部清除focus态
arrEleFocusable.forEach(function (ele) {
classList.remove(ele);
});
// 阻止默认的上下键滚屏
event.preventDefault(); //**************************//
// 索引加加减减
if (direction == 'left' || direction == 'up') {
index--;
if (index < 0) {
index = -1;
}
} else if (direction == 'right' || direction == 'down') {
index++;
if (index >= arrEleFocusable.length) {

index = arrEleFocusable.length - 1;
}
}
// 如果有对应的索引元素
if (arrEleFocusable[index]) {
// 高亮对应的控件元素
classList.add(arrEleFocusable[index]);
}
// 记录索引
target.storeIndexFocus = index;
});

16、//@ sourceMappingURL=jquery.min.map 这就是Source Map。整个文件就是一个JavaScript对象,可以被解释器读取。它主要有以下几个属性:names:转换前的所有变量名和属性名。mappings:记录位置信息的字符串。JavaScript脚本正变得越来越复杂。大部分源码(尤其是各种函数库和框架)都要经过转换,才能投入生产环境。常见的源码转换,主要是以下三种情况:
  (1)压缩,减小体积。比如jQuery 1.9的源码,压缩前是252KB,压缩后是32KB。
  (2)多个文件合并,减少HTTP请求数。
  (3)其他语言编译成JavaScript。最常见的例子就是CoffeeScript。

这三种情况,都使得实际运行的代码不同于开发代码,除错(debug)变得困难重重。这就是Source map想要解决的问题。简单说,Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码。这无疑给开发者带来了很大方便。目前,暂时只有Chrome浏览器支持这个功能。

source map只是一个映射到源文件的技术,这就是说以后还可以利用这个技术在浏览器中看SASS和LESS,说不定还可以通过html看erb,slim和haml?前景可谓一片光明。
17、inline-block元素在垂直位置上默认是与父系元素的基线(baseline)对齐的。而像图片或者输入框这样的元素,本身没有基线,则将其底端同父元素的基线对齐。不严谨地说,4线本中,第3条线就是基线——除了y、g等不老实的字母,大部分字母都在这条线的上面。vertical-align的middle在W3C的定义:Align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the parent.将元素的垂直中点,与父系元素的基线加上x-height的一半对齐。这个x-height是神马?我相信您到现在不止崩溃一次了,x-height简单地说就是当前样式下小写字母x的粗略高度。注意!注意!这个值已经明确到某个字母的粗略高度了,所以它不仅仅和字号相关了,还和字体相关!所以说,middle的定位,在不同的字体下都是不同的!不同类型的值,在对齐时使用的元素参照位置也不同(分别用元素的基线、顶部和底部做对齐参照)。
18、解析为可以用于继承的值-computed value。有没有一种方式可以获取通过任意方式定义的样式呢?w3c标准:window.getComputedStyle;IE方式:elem.currentStyle。 //我们可以注意到,实际项目中对计算值和使用值的区分并不重要,浏览器一般也未展现出计算值和使用值的区分。

19、line-height的计算值:长度和百分比值为绝对值;其他同指定值。注意:行框的高度只同本行内元素的行高有关,而和父元素的高度(height)无关。一个没有设置height属性的div的高度就是由一个一个line boxes的高度堆积而成的。事实上,深入理解inline模型后,会发现,根本不是文字撑开了div的高度,而是line-height!
20、垂直对齐主要属性值的表现形式如图:

设置垂直对齐会影响到行框高:

1
2
//p { line-height : 2em; }
//<p>垂直对齐<span style="vertical-align:2em;">正数向上</span>,而<span style="vertical-align:-2em;">负数向下</span>。&lt;p&gt;行高2em,而设置垂直对齐的文字撑开了行框。</p>


21、vertical-align的百分比值不是相对于字体大小或者其他什么属性计算的,而是相对于line-height计算的。对于内联元素,vertical-align与line-height虽然看不见,但实际上「到处都是」!vertical-align的不同类型的值,在对齐时使用的元素参照位置也不同(分别用元素的基线、顶部和底部做对齐参照)。line-height、vertical-align、inline-block关系链。对于内联元素各种想得通或者想不通的行为表现,基本上都可以用vertical-align和line-height来解释,以及进行行为矫正

1
2
3
4
5
6
7
8
9
{
line-height: 30px;
vertical-align: -10%;
}
//实际上,等同于
{
line-height: 30px;
vertical-align: -3px; /* = 30px * -10% */
}

22、在HTML5文档声明下,块状元素内部的内联元素的行为表现,就好像块状元素内部还有一个(更有可能两个-前后)看不见摸不着没有宽度没有实体的空白节点,这个假想又似乎存在的空白节点,我称之为“幽灵空白节点” 。div { line-height: 0; }
23、CSS2的可视化格式模型文档中有这么一段话:The baseline of an ‘inline-block’ is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its ‘overflow’ property has a computed value other than ‘visible’, in which case the baseline is the bottom margin edge.通俗的话描述就是:一个inline-block元素,如果里面没有inline内联元素,或者overflow不是visible,则该元素的基线就是其margin底边缘,否则,其基线就是元素里面最后一行内联元素的基线。
24、格式化上下文指的是初始化元素定义的环境。包含两个要点,一个是元素定义的环境,一个是初始化。在CSS中,元素定义的环境有两种,一种是块格式化上下文(Block formatting context),另一种是行内格式化上下文(Inline formatting context)。这两种上下文定义了在CSS中元素所处的环境,格式化则表明了在这个环境中,元素处于此环境中应当被初始化,即元素在此环境中应当如何布局等。以上解释专业点的说法是:在常规流中的框,都属于一个格式化的上下文中(触发方式、作用及现实意义)。块框参与块格式化上下文。行内框参与行内格式化上下文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//BFC  是这些元素创建了块格式化上下文,它们本身不是块格式化上下文。
<style>
.par {
border: 5px solid #fcc;
width: 300px;
overflow: hidden;
}

.child {
border: 5px solid #f66;
width: 100px;
height: 100px;
float: left;
}
</style>

<body>
<div class="par">
<div> //多层父容器 最外层触发BFC
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</body>

25、对于一个相对定位的元素,如果’left’和’right’的值都是”auto”(它们的初始值),计算后的值(computed value)为0(例如,框区留在其原来的位置)。
26、focus/blur不冒泡,focusin/focusout冒泡。mouseover/mouseout是冒泡事件;mouseenter/mouseleave不冒泡。
27、在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系,对祖先关系是否存在border的情况)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。折叠的结果:a、两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。b、两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。c、两个外边距一正一负时,折叠结果是两者的相加的和。
28、下面我们来谈谈’clearance’这个神奇的东西,当浮动元素之后的元素设置clear以闭合相关方向的浮动时,根据w3c规范规定,闭合浮动的元素会在其margin-top以上产生一定的空隙(clearance,如下图),该空隙会阻止元素margin-top的折叠,并作为间距存在于元素的margin-top的上方。关于这个间距的计算稍微有点复杂,但实际工作中你并不需要去计算它。
//1、通过w3c的官方规范可知,闭合浮动的块盒在margin-top上所产生的间距(clearance)的值与该块盒的margin-top之和应该足够让该块盒垂直的跨越浮动元素的margin-bottom,使闭合浮动的块盒的border-top恰好与浮动元素的块盒的margin-bottom相邻接。
//2、浮动的green盒子并未完全脱离文档流,还有margin-top或margin-bottom对常规流文档起作用。

29、幽灵空白节点:On a block container element whose content is composed of inline-level elements, ‘line-height’ specifies the minimal height of line boxes within the element. The minimum height consists of a minimum height above the baseline and a minimum depth below it,exactly as if each line box starts with a zero-width inline box with the element’s font and line height properties. We call that imaginary box a “strut.” (The name is inspired by TeX).翻译:在一个由行内元素组成的块级元素中,line-height指定了这个元素中的所有line box的最小高度。这个最小高度包括在baseline上面的最小高度和baseline下面的最小深度,就好像每个line box是由一个0宽度的,有着元素的font和line-height属性的行内框开始的,我们称这个虚拟的盒子为strut。
30、解决方案:1、font-size: 0或者line-height: 0;2、vertical-align !== baseline;方法1和方法2是两个不同的实现思路,方法1是让strut那个东西消失,对父元素设置。方法2就是inline-block垂直方向设置非baseline,从而让strut没有顶到底部。对子元素设置。
//如果line-height是相对单位,例如line-height:1.6或者line-height:160%之类,也可以使用font-size间接控制,比方说来个狠的,font-size设为大鸡蛋0, 本质上还是改变line-height值.

31、font-size:0, 因此此时content area高度是0,各种乱七八糟的线都在高度为0的这条线上,绝对中心线和中线重合。自然全垂直居中。字符实际占据的高度是由行高决定的,当行高变成0的时候,字符占据的高度也是0,此时,高度的起始位置就变成了字符content area的垂直中心位置。

1
2
div { line-height: 240px; font-size: 0; }
img { vertical-align: middle; }

32、middle中线位置(字符x的中心)并不是字符内容的绝对居中位置。两个位置的偏差就是图片近似居中的偏差。
33、有了href属性,天然鼠标手型,以及可以被键盘focus以及focus时候回车模拟点击行为。
34、设置a{outline:none;}虽然可以去除点击时留下的外框,但同时也扼杀了键盘操作focus时留下的虚框,会使键盘使用者迷茫与网页中。a:hover,a:active{outline:none;}。

Comments

去留言
2017-05-27

⬆︎TOP