Less的图片管理

栏目: CSS · 发布时间: 5年前

内容简介:从18年8月开始,我开始了我的野生前端职业生涯。不管是自学期间还是工作之后,网上的文章对我的学习帮助良多。所以我想开始分享一些我没在网上看到过的知识。通常我们展示图片是用html的由于安卓手机会对点击的

从18年8月开始,我开始了我的野生前端职业生涯。不管是自学期间还是工作之后,网上的文章对我的学习帮助良多。所以我想开始分享一些我没在网上看到过的知识。

图片载体

通常我们展示图片是用html的 <img> 标签或者css的 background-image 属性。

由于安卓手机会对点击的 <img> 进行放大显示,所以本人喜欢用 background-image 多一点。

安卓 <img> 点击默认放大的解决方法:css可以用 pointer-events:none ;js可用 e.preventDefault()

当然这两种载体还有其他区别,可以自行去搜索,下面就只用 background-image 来作为图片的载体。

自动获取图片宽高

不知道有没有人和我一样,工作中写的页面大多数是通过图片堆砌起来的,不论是通过一些开发辅助工具(pxcook等),都要查看每张图片的宽高,所以自从我看到了Less中有获取图片宽高的函数后,我就和Less擦出了火花。

.logo {
        width: image-width("logo.png");
        height: image-height("logo.png");
    }
    
    编译成
    
    .logo {
        width: 10px;
        height: 20px;
    }
复制代码

先说下这个函数的缺点,用多了之后会使项目的编译速度变慢(包括热更新),如果你的电脑本身就慢的话不推荐用。

1、首先要配置rem和把函数封装成mixin

移动端中的适配直接使用px单位是不行的,所以我们要进一步的改写

@designWidth: 750;
    html {
        //因为移动端已经兼容了vw和calc,所以不再需要用js来配置rem
        font-size: calc(10000vw / @designWidth)
    }
    .image-size(@url) {
        width: unit(image-width(@url) / 100, rem);
        height: unit(image-height(@url) / 100, rem);
    }
复制代码

2、配置background-image的mixin

首先我们的图片都要放在路径是 src/assets/img/ 的文件下,而不是和组件放在一起

.contain {
        background-size: contain;
        background-repeat: no-repeat;
        background-position: center;
    }
    .image-size(@url) {
        width: unit(image-width(@url) / 100, rem);
        height: unit(image-height(@url)/ 100, rem);
    }
    .bg-contain (@url) {
        // 路径是从项目的根目录开始的
        .image-size('./src/assets/img/@{url}');
        // 这里使用webpack来解析图片模块
        background-image: url('~@/assets/img/@{url}');
        // 使用继承减少生成的css代码量
        &:extend(.contain); 
    }
    
    使用如下
    
    .logo {
        .bg-contain('logo.png');
    }
    
    .homeLogo {
        .bg-contain('home/logo.png');
    }
    
复制代码

3、进一步减少bg-contain()的代码量

在进一步改写之前我们先来了解下Less的List Functions。

@paths: 'home', 'index';
    value: extract(@paths, 1);
    
    编译成
    
    value: 'home';
复制代码

很明显这就是以1为开始下标的数组,并且可以通过 extract() 函数取值。

有三处可以减少我们的代码量

  • 图片处于的文件夹目录
  • 图片的格式
  • 参数差异化兼容
@paths: '/img';
    .bg-contain (@name, @arg1: 'png', @arg2: 1) {
        // 暂时没想到更漂亮的方法来兼容参数的差异化
        // 有想到的话请务必告诉我
        @suffix1: if(isstring(@arg1), @arg1, '');
        @suffix2: if(isstring(@arg2), @arg2, '');
        @pathIndex1: if(isnumber(@arg1), @arg1, 0);
        @pathIndex2: if(isnumber(@arg2), @arg2, 0);
        @suffix: @suffix1 + @suffix2;
        @pathIndex: @pathIndex1 + @pathInde2;
        @path: extract(@paths, @pathIndex);
        .image-size('./src/assets/@{path}/@{name}.@{suffix}');
        background-image: url('~@/assets/@{path}/@{name}.@{suffix}');
        &:extend(.contain); 
    }
    
    使用如下
    
    // home.vue
    @paths: '/img/home';
    .logo {
        .bg-contain('logo');
    }
    .gif {
        .bg-contain('logo', 'gif');
    }
    .test {
        .bg-contain('logo', 'gif', 1);
    }
    
    // index.vue
    @paths: '/img/index', '/img/common';
    .logo {
        .bg-contain('logo');
    }
    .commonLogo {
        .bg-contain('logo', 2);
    }
复制代码

4、用遍历来减少代码量

我用的循环可不是loop when这种那么恶心的东西,而是用Less v3.7.0 版本的新特性each()来进行遍历。

首先让我们来看一下怎么用each()来减少代码量

@imgs: logo, avatar;
    each(@imgs, {
        .bg-@{value} {
            .bg-contain(@value);
        }
    )
复制代码

不知道你们有没有和我一样看到这段后感觉很 ,不过这里要注意一下。

当我们要用遍历出来的 @value 来作为选择器时,我们的数组里放的元素是不能带引号的,不过我们可以通用Less的 e() 函数 来去引号。

因为在Less中带引号的是 Value 类型,而不带引号的是 Node 类型,只有 Node 类型可以用来作为选择器使用。感兴趣的话可以看下Less的源码。

自动引入图片

上面的代码还是要在css里写图片名字然后在html里写上相应的class,感觉写的有点不舒服。不知道你们有没有想到怎么连css都不写就能用图片呢。

我先说下我的思路:

  • 获取图片路径和规范化图片的class命名。
  • 把图片路径和类名分别定义成全局变量引入。
  • 在less中遍历数组,配置类名和引入图片资源。

是不是很简单?

当然这种方式是有缺点的,就是不能动态地更新自动引入的图片,所以如果用这种方法来自动引入图片的话,你需要在 yarn serve 前就把要用到的图片给放在图片目录下。

下面我就用 Vue + Node + Less 来做自动引入图片。

这里我用 vue-cli 3.0 来生成项目,然后在项目根目录下配置 vue.config.js 文件。

1、定义遍历函数

Less的图片管理

2、生成Less的全局变量对象

Less的图片管理

3、输出配置

Less的图片管理

4、遍历全局数组生成类

Less的图片管理

5、关于class的作用域限制

你当然可以使用上面的前置字符串来限制class的作用域,使用如下:

<div class="bg-logo"/>
复制代码

我这里还有一种我喜欢的方式来限制class的作用域,不过肯定不是人人都喜欢的方式,首先看看怎么使用:

// html版
    <bg logo/>
    
    // pug版
    bg(logo)
复制代码

极简主义,有没有!!!

首先我们知道 <bg /> 这个标签是不存在的,对于这种标签浏览器是会把它看成 inline-block ,所以我们要把 <bg />display 属性定义为 block 。(这里我没有看HTML的规范,所以如果说的不准确的话请大家指出)。

bg {
        display: block;
    }
复制代码

然后如果直接在 vue 里的 <template> 中使用这种不存在的HTML标签的话,vue 会从当前组件配置的components属性中找有没有这个组件,没有的话会报错,虽然报错不会影响输出结果,但是看着报错心里就不舒服了,所以我们可以改一下vue源码的 isHTMLTag 变量,在 makeMap 中加一个 bg 字符串。

Less的图片管理

然后再改一下Less的遍历函数

Less的图片管理

好了,我已经想不到更简洁的方式引入图片了 over~

结尾

第一次写这种分享文章,可能有的地方写的不好,请多多包涵。

其实Less还有很多很棒的特性,比如 @plugin Maps range() 等。

最后,知道我为什么后半段都用图片吗?就是想你们参观一下我的 :sparkles: 0 star :sparkles: github


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Django 1.0 Template Development

Django 1.0 Template Development

Scott Newman / Packt / 2008 / 24.99

Django is a high-level Python web application framework designed to support the rapid development of dynamic websites, web applications, and web services. Getting the most out of its template system a......一起来看看 《Django 1.0 Template Development》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具