百度前端技术学院task0001的笔记。


Q:背景图片 or img标签 ?

  • 考虑语义性原则,如果是图片是网页内容的一部分,则使用img标签,如果不是,就使用CSS的background-image。

  • 考虑SEO,用a标签+CSS的background-image,因为搜索引擎对文本信息的识别比alt中的文字友好。

  • 如果想让用户打印页面的时候默认打印图片,就用img标签。

  • 如果要实现背景图片的transition或animation,用background-image。如果用img标签,要实现动画就要用js或jQuery去改变img的src属性。

参考SO上的讨论


Q:img元素底部为何会有空白,如何去除?

会有空隙是因为图片的属性vertical-align默认值为baseline,和基线对齐。

解决办法:

  • 让vertical-align失效:img { display: block;},在布局允许的情况下也可以采用浮动或绝对定位。

  • 将vertical-align的属性值改成别的值:在考虑图文混排的情况下一般改成bottom或middle.

  • 将font-size或line-height设为0。

参考What is vertical-align?img元素底部为何有空白?


Q:如何实现父元素透明子元素不透明?

如果给父元素设置

div {
  background-color: #000;
  opacity: 0.5;
  filter: alpha(50); //IE5~7
  -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; IE8
}

则子元素也会跟着透明,即使给子元素重新设置透明度也无用。解决办法:

div {
  background-color: rgb(0,0,0); //fallback color for IE
  background-color: rgba(0,0,0,.5);
  -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr=#80000000,endC
               olorstr=#80000000)";  //filter for IE8
  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr=#80000000, endColors
          tr=#80000000);  //filter for IE5~7
}

Q:display: none;visibility: hidden;实现隐藏元素的区别?

  • 渲染时,display: none;的元素不占据空间; visibility: hidden;会保留元素本该显示的空间。
  • visibility是继承属性,display是非继承属性。
  • 修改常规文档流中元素的display属性会导致重排,而修改visibility属性会导致重绘

Q:js文件放在是放在<head></head>中还是放在页面底部?

以下摘自浏览器的JavaScript引擎

浏览器的核心是两部分: 渲染引擎JS引擎,渲染引擎就是常说的浏览器内核。

渲染网页的四个阶段:

  1. 解析HTML为DOM,解析CSS为CSSOM(CSS Object Model)

  2. 将DOM和CSSOM合成一棵渲染树。

  3. 完成渲染树的布局。

  4. 将渲染树绘制到屏幕。

(以上过程并非严格按顺序执行)

正常的网页加载流程:

  1. 浏览器一边下载HTML网页,一边开始解析。

  2. 解析过程中发现script标签。

  3. 暂停解析,网页渲染的控制权交给JS引擎。

  4. 如果script标签引用了外部脚本,就下载该脚本,否则直接执行。

  5. 执行完毕,控制权交还给渲染引擎,恢复往下解析HTML网页。

以上过程中如果外部脚本长时间无法完成加载,会导致页面长时间失去响应,呈现“假死”状态,也被称为“阻塞效应”。

避免“阻塞效应”的方法:

方法1. 将script标签放在网页底部,而不是头部,这样即使遇到脚本加载失去响应,网页主体的渲染也已经完成。用户至少可以看到内容,而不是面对一个空白的页面。 同时也可以保证在DOM结构生成之后再调用DOM。

方法2. 给script标签加上defer属性。

defer属性告诉浏览器,等到DOM加载完成后再执行指定脚本。

<script src="1.js" defer></script>
<script src="2.js" defer></script>

加载流程:

  1. 浏览器开始解析HTML网页。

  2. 解析过程中遇到带有defer属性的script标签。

  3. 浏览器继续往下解析HTML网页 ,同时并行下载script标签中的外部脚本。

  4. 浏览器完成解析HTML网页,此时再执行下载的脚本。(脚本的执行顺序就是他们在页面上出现的顺序)

注: 对于内置而不是链接外部脚本文件的script标签,defer属性不起作用。

方法3. 给script标签加上async属性。

<script src="1.js" async></script>
<script src="2.js" async></script>

加载流程:

  1. 浏览器开始解析HTML网页。

  2. 解析过程中遇到带有async属性的script标签。

  3. 浏览器继续往下解析HTML网页 ,同时并行下载script标签中的外部脚本。

  4. 脚本加载完毕,浏览器暂停解析HTML网页,开始执行下载的脚本。(哪个先下载完就先执行哪个)

  5. 脚本执行完毕,浏览器恢复解析HTML网页。

使用defer属性还是async属性?

如果脚本之间没有依赖关系就用async属性,如果有,就用defer属性。同时使用两者,defer属性将不起作用,浏览器行为由async属性决定。(注:async是html5新增属性,IE9+支持)


Q:如何实现多栏自适应等高?

子元素margin: -9999px; padding: 9999px;父元素overflow: hidden;

html

<div class="container">
  <div class="a">早上好啊,今天天气真是好啊,这么好的天气不如出去走走吧</div>
  <div class="b">中午好</div>
  <div class="c">晚上好啊,天上的星星可真多啊!</div>
</div>

css

.container {
  overflow: hidden;
}
.a, .b, .c {
  width: 200px;
  float: left;
  padding-bottom: 9999px;
  margin-bottom: -9999px;
}
.a { background-color: lightpink; }
.b { background-color: lightgreen; }
.c { background-color: lightblue; }

如果要给每一栏加底边框,可在每一列中再加一个子div来模拟边框,让这个子div相对外层父容器container绝对定位。

参考八种创建等高列布局


Q:如何实现列表元素两端自动对齐?

子元素 display: inline-block;父元素text-align: justify;

如果想让最后一行也两端对齐。在子元素的后面添加一个高度为0宽度为100%的inline-block元素作为占位元素。

如果想让最后一行居左对齐,在子元素的后面再添加几个高度为0宽度为子元素宽度的inline-block元素作为占位元素(个数为一行的个数足矣)。

如果列表元素只有一行,要两端对齐,方法和让多行中最后一行两端对齐的方法一样。

去除列表元素上下间距的方法:父元素line-height: 0;或子元素vertical-align: top;

去除占位元素带来的空白高度的方法:父元素line-height: 0;且占位元素vertical-align: top;

所以同时去除列表元素上下间隙和占位元素带来的空白高度的方法:父元素line-height: 0;且占位元素vertical-align: top;


Q:如何实现一栏固定一栏自适应的布局?

方法一:利用margin负值和浮动

main和side都浮动于容器container中。由于一行放不下,side浮动到了下一行。

如果将side的margin-left设为负的200px,即它自身宽度,它就刚好跑到上一行的尾部,覆盖在main上面。

将side的margin-left继续减小,减小到负的600px,即父容器宽度,它就跑到了上一行的头部,

我们可以在main里再放一个子元素来装真正的主体内容,再给这个子元素设置相应的margin或padding来留出侧栏的位置。就可以实现侧栏固定,主体自适应的布局。

方法二: 一栏浮动,一栏不浮动

浮动的元素要写在前面,不浮动的元素写在后面。

html

<div class="container">
  <div class="side"></div>
  <div class="main"></div>
</div>

css

.container {
  width: 600px;
  overflow: hidden;
  margin: 0 auto;
  background-color: #fafafa;
}
.side {
  float: left;
  width: 200px;
  height: 100px
  background-color: lightblue;
}
.main {
  margin-left: 200px;
  height: 100px'
  background-color: lightpink;
}

这种方法不利于SEO,因为主要的内容main放在了后面,html的解析是从上到下的,用户先看到的是side,然后才是main。