/ css

css

https://haobing.wang/html/
https://haobing.wang/css/
https://haobing.wang/frontend/

工程问题

1.页面内容不足以铺满屏幕高度时,footer居底显示

在项目中常常会遇到这样的问题:页面主要内容不足以铺满一个屏幕的高度,footer下面就会有白块剩余。

2.scrollbar jumping 问题

页面高度超过 viewport 时,右侧新增的滚动条会使页面内容偏移。

  1. 水平导航条 bug

这个时候可以通过删除 div 节点来排查问题。通常是由于栅格类使用超过 12 列引起的。

css 基础

h1 {
  color: red;
}

h1 就是选择器,选中 h1 将字体颜色设置为红色.

每一条 css 样式的定义都有两部分组成: 选择器 { 样式 }

参考资料

选择器

正确使用选择器,是写出易于维护的CSS的关键!

精确度(优先级)

对于精确度的直观描述:

  • 所有都举手
  • 站在门口的人都举手
  • 站在门口的穿红衣服的人都举手
  • 站在门口的穿红色外套的的人都举手

MDN 优先级

MDN 的优先级文档写的不是很容易理解, 所以这里补充了一些更容易理解优先级的记录.

内联样式(style),权值为 1000
ID 选择器,权值为 100
class及属性选择器,权值为 10
元素及伪类,权值为 1

#menu h2 {}  /* 权值为 101 = 100 + 1 */
h2.title {}  /* 权值为 11 = 1 + 10 */
h2 + p {}    /* 权值为 2 = 1 + 1 */

通常,我们不会在 style 中写样式.也不会在 html 的 head 中写的样式.也就是说我们会使用引用外部css文件.

p span{color:green;} /*两个标签,权值为1+1=2*/
p>span{color:purple;}/*权值与上面的相同,覆盖上面的 color */

如果两个 css 选择器优先级相同,后者覆盖前者中相同的定义.

postion

position: static;   /* 初始值 */
position: relative; /* 相对定位元素,先放置在为添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在原来的位置留下空白) */
position: absolute; /* 绝对定位元素,不为元素预留空间,,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。 */
position: fixed;    /* 绝对定位元素,不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。 */

MDN position

css modules

我们推荐使用 CSS Modules 的解决方案。配合 webpack 的 css-loader 进行打包,会为所有的 class name 和 animation name 加 local scope,避免潜在冲突。

UserSearch组件:

// /components/Users/UserSearch.jsx
...
import styles from './UserSearch.less';
...

function UserSearch({
  form, field, keyword,
  onSearch,
  onAdd
  }) {
  ...
  return (
    <div className={styles.normal}>
      <div className={styles.search}>
        ...
      </div>
      <div className={styles.create}>
        <Button type="ghost" onClick={onAdd}>添加</Button>
      </div>
    </div>
  )
}

...

对应的UserSearch.less样式文件:

/* /components/Users/UserSearch.less */
.normal {
  display: flex;
  margin-bottom: 20px;
}

.search {
  flex: 1;
}

.create {
}

CSS Modules 会给组件的 className 加上 hash 字符串,来保证 className 仅对引用了样式的组件有效,如 styles.normal 可能会输出为 normal___39QwY

className 的输出格式可以通过 webpack.config 进行修改。

html 结构异常会引起 css 异常

当 css 代码格式一致,而 html 结构不一致,就可以考虑排查 html 语法

页面宽度异常

在调试手机端页面时,会发生 dom 超出设备尺寸的问题,原因是某 dom 宽度超出,需要添加 overflow-x: hidden;

媒体查询

在栅格系统中,我们在 Less 文件中使用以下媒体查询(media query)来创建关键的分界点阈值。

$screen-sm-min: 768px;
$screen-md-min: 992px;
$screen-lg-min: 1200px;

$screen-xs-max:              ($screen-sm-min - 1);
$screen-sm-max:              ($screen-md-min - 1);
$screen-md-max:              ($screen-lg-min - 1);

/* 超小屏幕(手机,小于 768px)没有任何媒体查询相关的代码,因为移动设备优先 */

/* 仅应用在手机端的样式 */
@media (max-width: $screen-xs-max) {}

/* 小屏幕(平板,大于等于 768px) */
@media (min-width: $screen-sm-min) { }

/* 仅应用在平板样式 */
@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { }

/* 中等屏幕(桌面显示器,大于等于 992px) */
@media (min-width: $screen-md-min) {}

/* 仅与应用在桌面显示器 */
@media (min-width: $screen-md-min) and (max-width: $screen-md-max) {}

/* 大屏幕(大桌面显示器,大于等于 1200px) */
@media (min-width: $screen-lg-min) { }

/* 仅与应用在大桌面显示器 */
@media (min-width: $screen-lg-min) {}

我们偶尔也会在媒体查询代码中包含 max-width 从而将 CSS 的影响限制在更小的屏幕之内。

body {
  min-height: 2000px;
  padding-top: 70px;
}

sass 三大功能

  • 变量,$primary-color: blue;
  • 嵌套
  • 导入其他 sass 文件,@import "colors";,即导入 _colors.scss 文件

sass 文件使用缩进,没有 {}

scss 文件同 css 相同,使用 {}

body {
  padding-top: @navbar-height;
}

演进

css -> less -> sass -> postcss -> css in js

CSS 样式的优先级

针对同一个元素的同一个属性有两个或以上的不同属性值(多个 class),在复用代码的基础上来讨论 CSS 样式的优先级问题

  • 选择符的精确度决定了优先级,指定的越精确,样式的优先级就越高。
  • 精确度相同时,后加载的会覆盖先加载的。且容易出 bug
  • 利用加载顺序来覆盖原有样式是个糟糕的主意
  • !important 有妙用
.header {
  background-color: red;
}
.welcome .header {
  background-color: blue;
}
.header {
  background-color: green !important;
}

CSS 长度单位

px

em

1em 是多长呢?标准答案是“当前字体大小”( font-size )。当前字体大小可以是用 font-size 来手工设置的,如果没有设置,那就是从父元素继承,父元素是 16px 那我的当前字体大小也是 16px 。但是如果父元素没设置呢,那就在往上推,如果推到顶级标签 html 都没有设置 font-size 呢,那么就是流量器默认值 16px 。所以,一般在没有明文的 font-size 设置的情况下,1em 就是 16px ,可以放心大胆的用。

rem 是针对 em 的一个弱点而生的

em 不能说不强大,但也不能说没毛病。毛病就是当一个元素本身就是用 em 做单位的,那它的各级子元素字体设置如果还用 em 做单位,就会晕菜掉。

1rem 永远等于页面基础字体大小。

百分比

如果给一个 div 设置 width: 50% ,那意思就是,它的宽度是它父元素宽度的 50% 。这个很好理解吧?但是什么时候用百分比宽度?一般就是在做响应式页面设计的时候。

transform

transform 属性向元素应用 2D 或 3D 转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜。

css3 之 transition 过渡动画

.example {
  //过渡属性 持续时间 效果函数 过渡延时;
  transition: background-color 2s ease 1s;
}

触发方式,过渡是从一种状态变到另一种状态,那么什么时候变,或者说为什么要变呢?总要有个触发事件吧。触发方式中最常见的就是鼠标滑过:

div {
  transition: background-color 0.5s ease;
  background-color: red;
}
div:hover {
  background-color: green;
}

width

min-width > max-width > width

width: 300px        /* <length> values */
width: 25em
width: 75%          /* <percentage> values */

width: border-box   /* Keyword values */
width: content-box
width: max-content
width: min-content
width: available
width: fit-content
width: auto

width: inherit

height

min-height 与 max-height 覆盖 height.

height: auto     /* auto keyword */

height: 120px    /* <length> values */
height: 10em

height: 75%      /* <percentage> values */

height: inherit

问题:页面高度高于 viewport 高度时,出现在浏览器内的右侧滚动条,会让页面向左偏移。
解决办法:

html {
  overflow-y: scroll;
}

background

background-size

.frame {
    height: $carousel-height;
    background: url(/images/frame.jpg) center 0 no-repeat;
    background-size: cover;//缩放图片以完全装入背景,超出背景部分被裁剪。
    .cover {
      height: $carousel-height;
      margin: 0 auto;
      background: url(/images/cover.jpg) center 0 no-repeat;
      background-size: contain;//缩放图片以完全装入背景,不足部分用空白填充。
    }
}

class 命名规范

  • 使用 .js-* class 来标识行为(与样式相对),并且不要将这些 class 包含到 CSS 文件中

浮动

子元素float,会让父元素高度为 0

<div class="wrap">
    <div class="pull-right">...</div>
    <div class="pull-left">...</div>
</div>

清除浮动

通过为父元素添加 .clearfix 类可以很容易地清除浮动(float)

<div class="wrap clearfix">
    <div class="pull-right">...</div>
    <div class="pull-left">...</div>
</div>