HTML和CSS的一些实战经验、代码规范和使用建议

HTML与CSS大部分人都认为比较简单, 但真正学习透彻的人却很少。 简单的东西我们不能轻视它, 否则就会连简单的东西都学不好。 当然要是把浏览器对于HTML和CSS的渲染也算进去, 又不是那么简单了。
这部分内容尽量挑一些业务中会涉及, 文档中有但没有更直观的例子的内容来讲。 一些文档中有, 但是过于冗长的部分, 也挑一些重点作为笔记和大家快速参考。

HTML标签语义化 & HTML代码规范

文本和段落

<br />是强制换行, 而<p>用来表示自然段。 不能随意换用, 可以用一个例子来表达它们的区别:

<!-- 这是两段文字, 使用两个<p> -->
<p>第一段文本</p>
<p>第二段文本</p>

<!-- 这是一段文字, 因为排版需要, 需要在段落中强制换行, 所以使用<br /> -->
<p>W3C标准中提到:<br />在XHTML标准中自闭合标签必须要加"/", 在最新的HTML5标准中不需要加"/", 但兼容加"/"的写法。<p/>

另外, 我们可能会给段落设置首字缩进、段落之间的外边距等。 而强制换行前后的文本属于同一个段落, 自然也就不会有这些缩进和边距了, 从样式上来说这也是我们不期望看到的。

HTML实体(entity)

字符实体
&&amp;
<&lt;
>&gt;
"&quot;

错误写法:

<h2>HTML & CSS</h2>

正确写法:

<h2>HTML &amp; CSS</h2>

HTML元素的语义化

HTML中有一类标签只表示修饰含义,请不要使用。 语义化包含两方面:

  1. 根据XHTML标准, 使用原有的一部分元素替代另一部分元素。 如下表
  2. 使用HTML5语义化元素, 见扩展阅读。
    废弃HTML元素替代HTML元素<b>只表示加粗,没有语义<strong>、<em>表示重要内容<font>用来修饰文本<span>使用css选择器来赋予样式

参考

扩展阅读

下面这些内容在开发wap站点, 对于SEO有要求的时候才需要。

HTML代码规范

  • 自闭合元素需要增加"/", 这样可读性更高。 例如<link href=""/>。
  • 没有属性的自闭合元素需要增加一个额外的空格。 例如<br />, 但是<img src=""/>因为有属性而不需要增加额外的空格。
  • 块状元素可以嵌套行内元素和块状元素, 行内元素不能嵌套块状元素。
    行内(内联)元素和块状元素
  • 行内元素不会自动换行, 会被内容撑开, 指定宽高无效。
  • 块状元素会自动换行布局, 可以指定宽高。
  • 可以使用display来修改元素的显示类型, 比如常常使用display: block来将
  • 渲染为块状元素。
    扩展阅读
  • 探究行内元素和块级元素
  • 深入理解行内元素的布局

相关问题

当图片加载失败的时候, 非常老旧的浏览器(没错, 就是人人喊打的IE)会显示一张裂图。 如果直接使用alt属性,展示兜底问题, 在视觉上也不好看。 所以我们应该采用设置兜底背景图 + alt的方式来处理。对于alt, 没有SEO要求的纯端内h5可以使用空字符串, 有SEO要求的要根据图片含义来赋值。

CSS选择器

关于inline style

除非需要JS动态计算属性值, 否则也尽量不要使用内联样式属性style。 例如下面这种情况, 窗口的高度只有在运行时才能知道, 那么我们只能使用style属性了。(这是react的jsx语法, 没有学习到也可以大概理解这里就是引用了在属性里插入了一个变量/)

export default () => {
    return <div style={{backgroundImage:"url(`${src}`)"}}></div>
}

关于important

一般情况下, 不要使用!important。 这容易导致一些意外的情况。
下面只是一个例子, 实际我们不会这样写代码:

div{
    background-image: url('xxx') !important;
}
export default () => {
    return <div style={{backgroundImage:"url(`${src}`)"}}></div>
}

这种情况, 我们的style里的高度声明优先级低于声明的300px的固定高度, 就不会起作用了。

后代选择器和子代选择器

大部分情况下, 我们可以使用后代选择器来替代子代选择器。 在Sass等CSS预处理器的嵌套规则中, 默认使用的也是子代选择器。 除非在使用子代选择器的时候, 容易出现不符合预期的情况。 例如:
CSS

.tree li{
    font-size: 16px;
    border-left: 1px solid #000;
}
.tree li ul li{
    font-size: 12px;
}

HTML

<ul class="tree">
    <li>
        <span>蔬菜</span>
        <ul>
            <li>番茄</li>
            <li>土豆</li>
        </ul>
    </li>
    <li>水果</li>
</ul>

结果
在这里插入图片描述

这里我们只是期望一级的列表元素左边增加边框。应该修改一下CSS:

.tree > li{
    font-size: 16px;
    background-color: blue;
}
.tree li ul li{
    font-size: 12px;
}

在这里插入图片描述

浏览器默认样式

我们可以发现浏览器对于各种元素有一些默认样式:

  • <p>元素默认有一定的上下边距
  • <a>元素默认是蓝色的, 鼠标悬停时展示下划线,颜色变为红色等等。
  • 有的浏览器<body>元素默认有margin

伪类选择器

<a>元素常用伪类

我们这里选取几个常用的伪类选择器来说明。

  • :link,选取未访问过的超链接元素。
  • :visited,选取访问过的超链接元素。
  • :hover,选取鼠标悬停的元素。端内h5无需考虑。
  • :active,选取点中的元素。
a{
    text-decoration: none;
}
a:link, a:visited, a:hover, a:active{
    color: #000;
}

其他常用伪元素

  • :first-children: 表示一组兄弟元素的第一个。
  • :last-children: 表示一组兄弟元素的最后一个。
.content-box{
    width: 200px;
    height: 200px;
    border: 10px solid red;
    margin: 10px auto;
}
.content-box:first-children{
    margin-top: 0;
}
.content-box:last-children{
    margin-bottom: 0;
}
<div style="width:220px; padding: 0 5px; background-color: #6cf;">
            <div class="content-box"></div>
            <div class="content-box"></div>
            <div class="content-box"></div>
</div>

在这里插入图片描述

伪元素选择器

伪元素选择器实际上创建了一个子元素。 我们常见的用法是利用它来增加一些背景图、 多层的边框等。 目前最常用的主要是这两个:

  • ::before
  • ::after
    可以当做是普通文档流的一个行内子元素。
    对于伪元素要注意几个点:
  • 一般content不能少。 如果是使用伪元素来创建背景图片之类的节点, 一般content是""。
  • 伪元素默认是行内元素。

扩展阅读

参考

CSS布局

CSS定位主要有几下几种:

  • static: 默认的定位方式, 根据行内元素和块状元素定位方式不同。
  • relative: 相对于原本的位置进行一些偏移, 但是仍然会占据原来的位置。
  • fixed: 相对页面可视区进行定位。 常用与吸顶/吸底元素。
  • sticky: 当窗口滚动到一个阈值时, 元素类似于relative和fixed的组合。

绝对定位

绝对定位的元素会根据向上冒泡查找的第一个非static定位的先代元素的左上角作为坐标轴原定进行定位。 如果找不到找个先代元素, 则相对于浏览器窗口进行定位。
在这里插入图片描述

参考

扩展阅读

flex布局

flex布局有自动伸缩的能力, 包括flex-basic、 flex-shrink、 flex-grow这三个属性。

flex-shrink

flex布局需要特别注意flex-shirnk的问题, 例如下面这个例子:

.radio-pannel {
    width: 300px;
}
.radio-pannel .item {
    width: 300px;
    height: 40px;
    display: flex;
    align-items: center;
}
.radio-pannel .radio {
    width: 30px;
    height: 50%;
    margin: 0;
    background: url(./radio_normal.svg) no-repeat center center transparent;
    background-size: cover;
    flex-shrink: 0; // 如果没有这个声明, 当右边的文本溢出的时候就会自动shrink
}
.radio-pannel .text {
    font-size: 16px;
}
<div class="radio-pannel">
    <div class="item">
        <div class="radio"></div>
        <div class="text">Category1 Category1 Category1 Category1 Category1 Category1</div>
    </div>
    <div class="item">
        <div class="radio"></div>
        <div class="text">Category2</div>
    </div>
</div>

没有声明flex-shrink时, 默认值为1, 如果右边的文本溢出, 则左边的按钮会被缩小:
在这里插入图片描述

我们给radio增加属性flex-shrink: 0, 则只有右边元素会被shrink, 此时配合文本溢出省略, 显示不至于错乱:
在这里插入图片描述

Flex

  • flex: 1。 被当做flex-basic的值。
  • flex: auto。 相当于flex: 1 1 auto。 分别为flex-grow | flex-shrink | flex-basis,常用于占满父容器的其他空间。
    参考
  • Flex 布局教程:语法篇 - 阮一峰
  • CSS定位详解 - 阮一峰
  • flex - MDN

CSS 盒模型

content-box(默认, 标准模式)

在这里插入图片描述

  • 内容区域 content area ,由内容边界限制,容纳着元素内容。元素内容包括文本、图像、子元素等。 内容区域尺寸由width、 height、 max-width、 max-height来控制。
  • 内边距区域 padding area 由内边距边界限制,扩展自内容区域,负责延伸内容区域的背景,填充元素中内容与边框的间距。
  • 边框区域 border area 由边框边界限制,扩展自内边距区域,是容纳边框的区域。
  • 外边距区域 margin area 由外边距边界限制,用空白区域扩展边框区域,以分开相邻的元素。

border-box(怪异模式)

与标准模式不同的是, 定义width和height时包括元素的内边距padding和边框border。
有些组件库会使用通配符全局reset。

参考

CSS 块格式化上下文(Block Formatting Context,BFC)

BFC有这些要点:

  • 一个BFC内的布局与BFC外界无关。
  • 理解BFC的其中一个重要的作用是理解浮动元素不能撑开父元素以及解决方法。(现代业务中, 我们使用flex可以完全替代float的功能, 除非要兼容旧的IE浏览器)
  • 注意外边界塌陷问题。
  • 出现塌陷问题可以使用创建BFC的方法来解决, 例如使用overflow:auto(一般是想要高度自适应, 同时height: auto)来创建BFC。

参考

扩展阅读

CSS规范 & 实践

相关规范约束工具库有stylelint等,vscode可以安装插件vscode-stylelint。sass。

避免命名空间污染(强制)

要避免命名空间污染, 比如上面的flex-shrink的例子中, .text和.item这样的命名是非常容易重复的, 但是我们把它作为.radio-pannel的后代选择器, 只要保证我们的.radio-pannel是唯一的, 那么就是安全的。
好的做法(只需要保证.radio-pannel全局唯一, 则安全):

.radio-pannel {
   /* ... */
}
.radio-pannel .item {
   /* ... */
}
.radio-pannel .radio {
    /* 因为.radio-pannel的结构并不复杂, 没有必要写成.radio-pannel .item .radio */
}
.radio-pannel .text {
   /* ... */
}

糟糕的做法:

.radio-pannel {
   /* ... */
}
.item {
   /* ... */
}
.radio {
   /* ... */
}
.text {
   /* ... */
}

属性书写顺序(建议)

建议按照布局 -> 盒模型 -> 文本相关属性 -> 其他背景图动画等视觉属性。 eden的CSS规范也有类似内容, 参见CSS规范 - eden。
这样能避免意外的属性覆盖, 例如:

.panel {
  margin-bottom: 6px;
  width: 100%;
  height: auto;
  overflow: auto;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  padding: 16px;
  background-color: #fff;
  margin: 0
}

当我们声明一个CSS选择器的时候, 如果属性比较多, 我们又写的很散乱, 就容易出现这样的问题。

杂项

  • 当属性的值为0(也只有为0时), 属性的单位可以省略。 例如margin: 0px;可以写成margin: 0。
  • 慎用简写属性, 例如只是想定义背景颜色, 应该使用background-color: red;而不要使用background: red; 因为简写属性中没有定义的值, 会自动采用默认值, 这样容易导致不符合预期的展现。

扩展内容

记一次自闭合标签是否需要加"/"的battle记录过程

极少情况下你可能需要查询W3C标准, 主要是一些特别特别特别细节的地方, 所有的知乎回答、二手资料都无法证明其正确性的时候。
https://www.w3.org/standards/webdesign/

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值