标签: CSS

  • 阻止浏览器根据 EXIF 信息自动修正图像旋转方向 image-orientation

    CSS 属性 image-orientation 用来修正某些图片的预设方向。

    当需要对图像原始状态进行操作时,这种自动修正会带来错误。尤其是在新版浏览器中该属性默认值从不生效(none)被改成了 from-image,此时导致在 Chrome v81 浏览器上处理一些带角度的图像时产出错误的信息。

    /* 正确的默认值应该是0 */
    image-orientation: 0deg /* 实际该值无效 */
    image-orientation: none /* 实际该值生效,可以阻止浏览器自动旋转图像(disable html img auto rotation) */

    /* 非 90 度的整数倍, 所以会被四舍五入到 0 度 */
    image-orientation: 6.4deg

    /* 相当于 270deg */
    image-orientation: -90deg

    /* 使用图片的 EXIF 数据 */
    image-orientation: from-image

    /* 旋转 90deg, 再水平翻转 */
    image-orientation: 90deg flip

    /* 不旋转, 只进行水平翻转 */
    image-orientation: flip

    /* 继承 */
    image-orientation: inherit

    该属性还未进入标准文档,在未来版本的浏览器中该功能的语法和行为可能随之改变。

  • 使用CSS变量提高代码复用率

    CSS 支持通过 ––variable-name: variable-value 声明变量,并通过 var(––variable-name) 使用变量。

    CSS 使用变量示例

    .parent {
        --color-red: red;
    }
    
    .child {
        color: var(--color-red);
    }
    

    Less 和 Sass 已分别使用 $ 和 @ 声明变量,CSS 则采用双划线声明变量。

    Less / Sass 变量示例

    /* Less 变量示例 */
    
    @blue: #f938ab;
    
    .blue {
        color: @blue;
    }
    
    /* Sass 变量示例 */
    
    $blue: #1875e7;
    
    .blue {
        color: $blue;
    }
    

    不同于 Less/Sass 在最外层声明, CSS Variable 需要在具体 selector 下声明变量,因此可以在子元素下覆盖父元素定义的变量。

    一般将 CSS Variable 定义在伪类 :root 下,让所有子元素都可以继承。

    定义在伪类 :root 下

    :root {
      --base-color: #333;
      --base-size: 14px;
    }
    
    .btn {
        color: var(--base-color);
        font-size: var(--base-size);
    }
    

    变量继承与重写

    div {
        padding: 2px;
    }
    
    .one {
        --border: 1px solid red;
        border: var(--border);
    }
    
    .two {
        border: var(--border);
        --border: 2px solid green;
    }
    
    .three {
        border: var(--border);
    }
    
    <div class="one">
        1
        <div class="two">
            2-1
            <div class="three">3</div>
        </div>
        <div class="two">2-2</div>
    </div>
    

    解析到 .two selector 会优先解析 .two 拥有的变量,再应用。因此 .two 应用的 --border 是 2px solid green。
    .three 也会应用 .two 定义的变量。

    动态修改 CSS Variable

    网页渲染完成之后,再修改变量值,会重新应用 CSS。

    因为 val(variable-name) 返回的是 variable-value,所以当 variable-value 不包含单位是,某些样式需要明确指定单位。

    :root {
        --line-height: 20;
    }
    
    p {
        line-height: var(--line-height)px;
    }
    

    这点不像 jQuery 自动检测浏览器设置的默认单位。需要显示设置单位。

  • 选择合适的字体区分 1Il、0Oo

    为了能够清晰区分 1Il 0Oo、准确识别相似字符,测试了 70+ 种 Windows 系统下使用的字体,得到 3 种能清晰区分 1Il 0Oo 的字体,效果如下:

    # 字体 1, i, l, 零和欧, 全角
    1 Consolas 1iIl 0Oo0Oo ø
    2 Tahoma 1iIl 0Oo0Oo ø
    3 Verdana 1iIl 0Oo0Oo ø

     

    在这 3 种字体中,Verdana 和 Tahoma 效果最好,Consolas 次之,在 Excel 中也常用到 Tahoma。

    最终采取的方案是:

    .input {
        font-family: Verdana, Tahoma, Consolas, monospace;
    }
    

    全部对比效果如下:

    # 字体 1, i, l, 零和欧, 全角
    1 Consolas 1iIl 0Oo0Oo ø
    2 Tahoma 1iIl 0Oo0Oo ø
    3 Verdana 1iIl 0Oo0Oo ø
    4 ‘Angsana New’ 1iIl 0Oo0Oo ø
    5 Arial 1iIl 0Oo0Oo ø
    6 ‘Arial Black’ 1iIl 0Oo0Oo ø
    7 Basemic 1iIl 0Oo0Oo ø
    8 Batang 1iIl 0Oo0Oo ø
    9 ‘Book Antiqua’ 1iIl 0Oo0Oo ø
    10 ‘Browallia New’ 1iIl 0Oo0Oo ø
    11 Calibri 1iIl 0Oo0Oo ø
    12 Cambria 1iIl 0Oo0Oo ø
    13 Candara 1iIl 0Oo0Oo ø
    14 Century 1iIl 0Oo0Oo ø
    15 ‘Comic Sans MS’ 1iIl 0Oo0Oo ø
    16 Constantia 1iIl 0Oo0Oo ø
    17 Corbel 1iIl 0Oo0Oo ø
    18 ‘Cordia New’ 1iIl 0Oo0Oo ø
    19 Courier 1iIl 0Oo0Oo ø
    20 ‘Courier New’ 1iIl 0Oo0Oo ø
    21 DilleniaUPC 1iIl 0Oo0Oo ø
    22 Dotum 1iIl 0Oo0Oo ø
    23 Garamond 1iIl 0Oo0Oo ø
    24 Geneva 1iIl 0Oo0Oo ø
    25 Georgia 1iIl 0Oo0Oo ø
    26 Gulim 1iIl 0Oo0Oo ø
    27 GungSuh 1iIl 0Oo0Oo ø
    28 Impact 1iIl 0Oo0Oo ø
    29 JasmineUPC 1iIl 0Oo0Oo ø
    30 ‘Lucida Console’ 1iIl 0Oo0Oo ø
    31 ‘Lucida Sans Unicode’ 1iIl 0Oo0Oo ø
    32 ‘Malgun Gothic’ 1iIl 0Oo0Oo ø
    33 Mangal 1iIl 0Oo0Oo ø
    34 Marlett 1iIl 0Oo0Oo ø
    35 Meiryo 1iIl 0Oo0Oo ø
    36 ‘Microsoft JhengHei’ 1iIl 0Oo0Oo ø
    37 MingLiu 1iIl 0Oo0Oo ø
    38 MingLiU_HKSCS 1iIl 0Oo0Oo ø
    39 monospace 1iIl 0Oo0Oo ø
    40 Modern 1iIl 0Oo0Oo ø
    41 ‘MS Gothic’ 1iIl 0Oo0Oo ø
    42 ‘MS Mincho’ 1iIl 0Oo0Oo ø
    43 ‘MS PGothic’ 1iIl 0Oo0Oo ø
    44 ‘MS PMincho’ 1iIl 0Oo0Oo ø
    45 ‘MS Sans Serif’ 1iIl 0Oo0Oo ø
    46 ‘MS Serif’ 1iIl 0Oo0Oo ø
    47 ‘Palatino Linotype’ 1iIl 0Oo0Oo ø
    48 PMingliU 1iIl 0Oo0Oo ø
    49 PMingLiU-ExtB 1iIl 0Oo0Oo ø
    50 serif 1iIl 0Oo0Oo ø
    51 Symbol 1iIl 0Oo0Oo ø
    52 Times 1iIl 0Oo0Oo ø
    53 ‘Times New Roman’ 1iIl 0Oo0Oo ø
    54 ‘Trebuchet MS’ 1iIl 0Oo0Oo ø
    55 Wingdings 1iIl 0Oo0Oo ø
    56 ‘Yu Gothic’ 1iIl 0Oo0Oo ø
    57 ‘Yu Mincho’ 1iIl 0Oo0Oo ø
    58 方正舒体 1iIl 0Oo0Oo ø
    59 方正姚体 1iIl 0Oo0Oo ø
    60 仿宋 1iIl 0Oo0Oo ø
    61 黑体 1iIl 0Oo0Oo ø
    62 华文彩云 1iIl 0Oo0Oo ø
    63 华文仿宋 1iIl 0Oo0Oo ø
    64 华文行楷 1iIl 0Oo0Oo ø
    65 华文琥珀 1iIl 0Oo0Oo ø
    66 华文楷体 1iIl 0Oo0Oo ø
    67 华文隶书 1iIl 0Oo0Oo ø
    68 华文宋体 1iIl 0Oo0Oo ø
    69 华文细黑 1iIl 0Oo0Oo ø
    70 华文新魏 1iIl 0Oo0Oo ø
    71 华文中宋 1iIl 0Oo0Oo ø
    72 楷体 1iIl 0Oo0Oo ø
    73 隶书 1iIl 0Oo0Oo ø
    74 宋体 1iIl 0Oo0Oo ø
    75 宋体-ExtB 1iIl 0Oo0Oo ø
    76 微软雅黑 1iIl 0Oo0Oo ø
    77 新宋体 1iIl 0Oo0Oo ø
    78 幼圆 1iIl 0Oo0Oo ø
  • CSS 压缩 initial、normal

    CSS 压缩在完成简单的字符替换,空白符压缩之后,还可以进一步进行特定 value 压缩。

    比如:

    /* 压缩前 */
    .main{margin:initial}
    
    /* 压缩后 */
    .main{margin:0px}
    
    /* 进一步压缩 */
    .main{margin:0}
    

    最后只需要占用一个字符就达到 initial 效果。

    css initial 是一个特殊值,用于设置一些复杂、容易混淆的、难记忆的初始值非常有效。

    /* 压缩前 */
    .main{background:initial}
    
    /* 压缩后 */
    .main{background:rgba(0, 0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box}
    

    对于这种真实样式比 initial 更长的样式可以不用压缩。

    Chrome 下 css initial 对应真实值

    在多个浏览器遍历设置元素 css 样式为 initial,再通过 getComputedStyle 获取真实样式,将其中相同的部分归纳到 initial 集合中,提供给压缩脚本使用,即可完成 css 特定 value 压缩。

    同样可以压缩 css normal,使文件更小。

  • Webpack 打包 css,z-index 被重新计算

    使用 Webpack 打包 css 文件,发现打包后的 z-index 值跟源文件 z-index 不一致。

    如下图,左侧是源文件,右侧是打包后的文件:

    即使加上 !important,经过 OptimizeCssAssetsPlugin 调用 cssProcessor cssnano 处理之后也是 z-index: 2。

    因此,很可能是 cssnano 进行了重新计算(cssnano 称为 rebase),而且这种计算是不够准确的。

    因为打包后的文件有两处 z-index,这里是第二处,所以此处 z-index 是 2。

    cssnano 将 z-index rebase 归类为 unsafe,而不是 bug,只有在单个网页的 css 全部写入一个 css 文件,并且不通过 JavaScript 进行改动时是 safe。

    参考:http://cssnano.co/optimisations/zindex/

    项目中提取了公共的 css,已经对 layout 设置了很小的 z-index,因此受到 cssnano z-index rebase 的影响。

    cssnano 默认进行 z-index rebase。

    unsafe (potential bug) 优化项默认不开启应该比较友好。

    new OptimizeCssAssetsPlugin({
        cssProcessor: require('cssnano'),
        cssProcessorOptions: {
            discardComments: {removeAll: true},
            // 避免 cssnano 重新计算 z-index
            safe: true
        },
        canPrint: false
    })
    
  • 在浏览器端使用less.js解析less文件

    非常喜欢 less 的变量、混合以及嵌套。当不断重复书写 CSS 时,嵌套 CSS 必不可少,却又略显多余。因为大部分情况下,它并没有提升编写 CSS 的能力,只是不断地重复。

    了解到有多种 CSS 的扩展语言,首先尝试使用 less。

    less 的特性有很多,支持变量、混合、嵌套、函数、运算、颜色函数、命名空间、作用域、文件引入、甚至 JavaScript 表达式。

    利用 less.js 解析 less

    第一步,引入 style.less 文件

    <link rel="stylesheet/less" type="text/css" href="/static/ran/less/site/common.less?1.0.0"/>
    

    注意 rel 属性需要设置为 stylesheet/less。

    第二步,引入 less.js 文件

    <script src="http://cdn.bootcss.com/less.js/2.5.3/less.min.js?1.0.0"></script>
    

    一定要在所有 less 文件之后引入 less.js。

    第三部,保证 common.less 可以通过 AJAX 输出

    因为 less.js 通过 ajax 下载 common.less 文件,所以若 common.less 与当前网站不在同域,可能会导致无法下载。
    若 common.less 与当前网站不同域,需要在 header 信息中增加 Access-Control-Allow-Origin,允许网站通过 AJAX 访问。

  • IE DOM 高度临界值

    在 IE 浏览器中设置 DOM 元素的高度,并不是一定有效的。比如设置标签的 height 样式,如果这个值足够大,那么在 IE 下就可能是无效的。

    下表展示了 IE 浏览器 DOM 元素的最大高度:

    IE11 DOM 最大高度 1533957px
    IE10 DOM 最大高度 1460873px
    IE9 DOM 最大高度 1472560px