不知道的HTML和CSS

445 阅读13分钟

HTML

*你是如何理解 HTML 语义化的?

超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。

从HTML编写历史说起

第一阶段:那时候还没有前端,网页的制作是由后端制作的,他们布局是table布局。但是这只能做一些简单的布局。更加复杂的布局难以实现。

第二阶段:使用div+css布局。这样会造成满篇的div盒子。既不利于程序员阅读代码,增加维护成本同时机器也很难做SEO优化。

第三阶段:HTML语义化的方式布局。这样在该写段落的地方用h1-h6。文字加粗就用strong标签。做列表就用<ul> <ol> <li> >。做表格就用<table>、<thead>、<tbody>、<td>、<th>、<caption>

简单来说语义化就是不仅让编写代码的人更加通俗移动的阅读代码还让机器理解每句代码的意思。

他的好处有以下几点:

  • html 语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;
  • 即使在没有样式 CSS 情况下也以一种文档格式显示,并且是容易阅读的;
  • 搜索引擎的爬虫也依赖于 HTML 标记来确定上下文和各个关键字的权重,利于 SEO;
  • 有利于构建清晰的结构,有利于团队的开发、维护

你用过哪些 HTML 5 标签?

HTML5使得页面更加的语义化。如果要制作以下的布局。

image-20210709095031102

以往的整个布局是:

<div class="header"></div>
<div class="nav"></div>
<div class="article"></div>
<div class="aside"></div>
<div class="footer"></div>

使用HTML5的编写更加的简介易懂

<header></header>
<nav></nav>
<article></article>
<aside></aside>
<footer></footer>

常见的HTML5标签有

<header>        标记定义一个页面或一个区域的头部
<nav>           标记定义导航链接
<section>	    标记定义一个区域
<main>         	定义文档中主要或重要的内容。
<aside>         标记定义页面内容部分的侧边栏
<article>       标记定义一篇文章
<footer>        标记定义一个页面或一个区域的底部

meta viewport 是做什么用的,怎么写?

meta 标签主要用于描述页面的一些信息。

viewport 是 meta 标签的 name 属性中可选值中的一个,指 web 页面上用户可见的区域,用于移动端页面设计。

为什么要做这个呢?

原因是在以往网页的展示主要在PC端,当时开发者没有考虑移动端的布局,现在移动端逐渐的兴起,更多人选择在移动端浏览网页,但是由于PC端的viewport 比移动端大,在移动端,浏览器会将网页等比缩小,导致看到的文字和图片异常的小,用户体验大打折扣。后开开发人注重移动的端的开发, Apple 最早在 Safari iOS 中引入了 viewport meta 标签,让Web开发人员控制视口的大小和比例。

image-20210709102910733.png

例如上面这个网址没有做移动端适配,就会出现很小的自,需要放大才能看。

常见的写法

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

meta viewport 的六个属性

  • initial-scale:初始缩放比例,即当页面第一次加载时的缩放比例,为一个数字(可以带小数);
  • maximum-scale:允许用户缩放到的最大比例,为一个数字(可以带小数);
  • minimum-scale:允许用户缩放到的最小比例,为一个数字(可以带小数);
  • user-scalable:是否允许用户手动缩放,值为 "no"(不允许) 或 "yes"(允许);
  • width:控制 viewport 的大小,可以给它指定一个值(正整数),或者是一个特殊的值(如:device-width 设备独立像素宽度,单位缩放为 1 时);
  • height:与 width 相对应(很少使用)。

H5 是什么?

注意H5不是HTML5的缩写。H5是一种技术的集合。

通常H5指代在微信中,点开后会在微信内部展开的精美的移动端的 Web 页面。例如易企秀制作的宣传页面。

里面会用到的技术有:

  • 页面素材预加载技术:可以选择 createJS 之中的 preloadJS 实现
  • 音乐加载播放技术:可以选择 createJSsoundJS 实现
  • 可以滑动的页面:可以选择 swiper.js 实现
  • 可以涂抹擦除:可以选择 HTML5 中的 canvas 实现
  • 有动态的文字和图片:可以选择使用 CSS3 实现,当然直接通过 JS 也可以
  • 可以支持分享自定义的文案和图片:这里用到的是微信的 jssdk

请描述<script><script async><script defer>的区别。

  • <script> - HTML 解析中断,脚本被提取并立即执行。执行结束后,HTML 解析继续。
  • <script async> - 脚本的提取、执行的过程与 HTML 解析过程并行,脚本执行完毕可能在 HTML 解析完毕之前。当脚本与页面上其他脚本独立时,可以使用async,比如用作页面统计分析。
  • <script defer> - 脚本仅提取过程与 HTML 解析过程并行,脚本的执行将在 HTML 解析完毕后进行。如果有多个含defer的脚本,脚本的执行顺序将按照在 document 中出现的位置,从上到下顺序执行。

为什么最好把 CSS 的<link>标签放在<head></head>之间?为什么最好把 JS 的<script>标签恰好放在</body>之前,有例外情况吗?

<link>放在<head>

<link>标签放在<head></head>之间是规范要求的内容。此外,这种做法可以让页面逐步呈现,提高了用户体验。将样式表放在文档底部附近,会使许多浏览器(包括 Internet Explorer)不能逐步呈现页面。一些浏览器会阻止渲染,以避免在页面样式发生变化时,重新绘制页面中的元素。这种做法可以防止呈现给用户空白的页面或没有样式的内容。

<script>标签恰好放在</body>之前

脚本在下载和执行期间会阻止 HTML 解析。把<script>标签放在底部,保证 HTML 首先完成解析,将页面尽早呈现给用户。

例外情况是当你的脚本里包含document.write()时。但是现在,document.write()不推荐使用。同时,将<script>标签放在底部,意味着浏览器不能开始下载脚本,直到整个文档(document)被解析。也许,对此比较好的做法是,<script>使用defer属性,放在<head>中。

CSS

*两种盒模型分别说一下。

盒模型是由 margin border padding content组成的

image-20210709111834154

分为:border-box(IE模型)和content-box(标准模型)

标准模型的宽度就是 内容content的宽度.

IE模型的宽度就是 内容的宽度+内边距的宽度+边框的宽度。

*如何垂直居中?

方法一

使用table标签垂直居中

  <table class="parent">
    <tr>
      <td class="child">
      一串文字一串文字
      </td>
    </tr>
  </table>
  
.parent{
  border: 1px solid red;
  height: 600px;
}

.child{
  border: 1px solid green;
}

方法二 :table-cell + vertical-align + inline-block/margin: auto

  <div class="parent">
    <div class="child">
      一串文字
    </div>
  </div>

.parent{
  border: 3px solid red;
  height: 600px;
  text-align: center;
  vertical-align: middle;
  display: table-cell;
}
.child{
  border: 3px solid black;
  display: inline-block;
  width: 300px;
  display: inline-block;
}

方法三 :绝对定位 + transform

  <div class="parent">
    <div class="child">
      一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
    </div>
  </div>
  
.parent{
  height: 600px;
  border: 1px solid red;
  position: relative;
}
.child{
  border: 1px solid green;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}

方法四:绝对定位和负magin值

  <div class="parent">
    <div class="child">
      一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
    </div>
  </div>
  
.parent{
  height: 600px;
  border: 1px solid red;
  position: relative;
}
.child{
  border: 1px solid green;
  width: 300px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -150px;
  height: 100px;
  margin-top: -50px;
}

方法五:flex布局

  <div class="parent">
    <div class="child">
      一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
    </div>
  </div>
  
.parent{
  height: 600px;
  border: 3px solid red;
  
  display: flex;
  justify-content: center;
  align-items: center;
}
.child{
  border: 3px solid green;
  width: 300px;
}

方法六:绝对定位 + left/right/bottom/top + margin

  <div class="parent">
    <div class="child">
      一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
    </div>
  </div>
  
.parent{
  height: 600px;
  border: 1px solid red;
  position: relative;
}
.child{
  border: 1px solid green;
  position: absolute;
  width: 300px;
  height: 200px;
  margin: auto;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

*flex 怎么用,常用属性有哪些?

具有强大的布局能力,传统布局使用display、float和postion来布局。但是这样布局比较麻烦,而flex只需要几段代码就能OK。

常见的属性

容器上面:

display:flex|inline-flex;

决定主轴的方向
flex-direction: row | row-reverse | column | column-reverse; 

换行
flex-wrap: nowrap | wrap | wrap-reverse;

是flex-direction属性和flex-wrap属性的简写形式,
flex-flow

定义了项目在主轴上的对齐方式。
justify-content: flex-start | flex-end | center | space-between | space-around;

定义项目在交叉轴上如何对齐。
align-items:flex-start | flex-end | center | baseline | stretch;

定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
align-content: flex-start | flex-end | center | space-between | space-around | stretch;

项目的上

定义项目的排列顺序。数值越小,排列越靠前,默认为0order:number

定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
flex-grow:number

定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
flex-shrink:number

定义了在分配多余空间之前,项目占据的主轴空间(main size)。
flex-basis:<length> | auto; 

是flex-grow, flex-shrinkflex-basis的简写,默认值为0 1 auto。
flex:none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。
align-self:auto | flex-start | flex-end | center | baseline | stretch;

*BFC 是什么?

BFC的全称 - 块级格式化上下文,W3C这样定义:

它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用 当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。

通俗的来说,BFC形成独立的空间,里面的子元素不会影响到外面的布局。

怎样才能形成BFC

  1. float的值不能为none
  2. overflow的值不能为visible
  3. display的值是table-celltable-captioninline-blockflex、或inline-flex
  4. position的值不为relativestatic

BFC的约束规则

  1. 内部的Box会在垂直方向上一个接一个的放置
  2. 垂直方向的距离由margin决定, 属于同一个BFC的两个相邻的标签外边距会发生重叠
  3. BFC的区域不会与float的元素区域重叠
  4. 计算BFC的高度时,浮动子元素也参与计算
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然

这样理解还不不够,我们可以举栗子

BFC解决的问题

解决float元素脱离文档流,导致父盒子高度塌陷的问题

<template>
  <div class="container">
    <div class="left"></div>
    <div class="right"></div>
  </div>
</template>

<style>
.container {
  width: 200px;
  border: 1px solid pink;
  background-color: pink;
}
.left,
.right {
  float: left;
  width: 50px;
  height: 100px;
  margin-left: 10px;
  background-color: red;
}
</style>

image-20210709165854245

可以看到上面的子元素浮动后,脱离文档流,导致父盒子高度塌陷,高度为0。

这是我们可以给它的父盒子加上BFC,例如加一个overflow: hidden; 父盒子的高度就是子元素的高度。

解决margin边距重叠

<template>
  <div class="container">
    <div class="box"></div>
    <div class="box"></div>
  </div>
</template>

<style>
.container {
  background-color: pink;
}

.box {
  width: 100px;
  height: 100px;
  margin: 20px;
  background-color: red;
}
</style>

image-20210709170724754

我们看到给每个盒子添加的一个margin:20px这样算下来,中间那个间隙该市40px,结果只有20px。,这就导致了margin塌陷问题,这时margin边距的结果为最大值,而不是合,为了解决此问题可以使用BFC,或者简单粗暴方法一个设置margin,一个设置padding

我们可以在div外面包裹一层容器,并触发该容器生成一个BFC。那么两个div便不属于同一个BFC,就不会发生margin重叠了。

.wrap {
  overflow: hidden;
}

<div class="container">
  <div class="box"></div>
  <div class="wrap">
    <div class="box"></div>
  </div>
</div>

CSS 选择器优先级

CSS选择器的优先级关系是:

内联 > id 选择器 > 类、属性、伪类选择器 > 标签元素、伪元素

情况一:

  • 内联样式表的权值最高 1000;
  • ID 选择器的权值为 100
  • Class 类选择器的权值为 10
  • HTML 标签选择器的权值为 1

情况二:

  • 越具体,优先级越高
  • 写在后面的覆盖写在前面的内容
  • !import级别最高,少用

清除浮动说一下(代码)

方法一:利用伪元素(clearfix)

 .clearfix:after{
     content: '';
     display: block; /*或者 table*/
     clear: both;
 }
 .clearfix{
     zoom: 1; /* IE 兼容*/
 }

方法二: 父元素加overflow清除浮动

    
<div class="container">
  <div class="left"></div>
  <div class="right"></div>
</div>
<div class="bottomDiv">...</div>
    
.container {
  width: 200px;
  height: 50px;
  background-color: pink;
  overflow: hidden; // auto 
}
.left,
.right {
  float: left;
  width: 50px;
  height: 100px;
  margin-left: 10px;
  background-color: red;
}
.bottomDiv{
  border: 2px dotted black;
}

这种方法如果子元素比父元素高,使用 hidden就会直接隐藏高出父元素的部分,使用auto就会出现滚动条。

方法三:创建一个空盒子 clear:both

<div class="container">
  <div class="left"></div>
  <div class="right"></div>
  <div class="clear"></div>
</div>
<div class="bottomDiv">...</div>

.clear{
  clear: both; // or left	
}

*relative、fixed、absolute和static四种定位有什么区别?

  • static:默认定位属性值。该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, left 和 z-index 属性无效。
  • relative:该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。
  • absolute:不为元素预留空间,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。
  • fixed:不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed 属性会创建新的层叠上下文。当元素祖先的 transform 属性非 none 时,容器由视口改为该祖先。
  • sticky:盒位置根据正常流计算(这称为正常流动中的位置),然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位。在所有情况下(即便被定位元素为 table 时),该元素定位均不对后续元素造成影响。当元素 B 被粘性定位时,后续元素的位置仍按照 B 未定位时的位置来确定。position: stickytable 元素的效果与 position: relative 相同。

display的属性值都有哪些?

  • none, block, inline, inline-block, table, table-row, table-cell, list-item.

重置(resetting)CSS 和 标准化(normalizing)CSS 的区别是什么?你会选择哪种方式,为什么?

  • 重置(Resetting): 重置意味着除去所有的浏览器默认样式。对于页面所有的元素,像marginpaddingfont-size这些样式全部置成一样。你将必须重新定义各种元素的样式。
  • 标准化(Normalizing): 标准化没有去掉所有的默认样式,而是保留了有用的一部分,同时还纠正了一些常见错误。

当需要实现非常个性化的网页设计时,我会选择重置的方式,因为我要写很多自定义的样式以满足设计需求,这时候就不再需要标准化的默认样式了。

参考文章


CSS 问题 | Front End Interview Handbook