上一篇文章介绍了怎样使用compass合并雪碧图,生成的icons.css文件中单位是px,PC端可以直接在html文件中使用,但在移动端,我们需要根据不同分辨率的屏幕,来缩放图片大小,显然使用px单位肯定是不行的。所以需要做一下单位转换的工作。

移动端使用rem作为单位是最合适不过了。并不是使用了rem就可以,还需要做一些准备工作。我们都知道rem是基于html标签的font-size的,所以需要使用js动态的计算htmlfont-size。这里我使用淘宝的lib-flexible

在上一篇文章中,有讲过雪碧地图(Sprite maps),如下面:

$icons: sprite-map("icons/*.png", $spacing: 8px, $layout: smart);

.icon {
width: image-width(sprite-file($icons, card-icon));
height: image-height(sprite-file($icons, card-icon));
background-image: sprite-url($icons);
}

生成css:

.icon {
width: 77px;
height: 64px;
background-image: url('/images/icons-s37f950be3b.png');
}

现在,需要把px转换成rem。我们不可能在icons.css中转换,应该在icons.scss文件中转换。

icons.scss声明一个转换函数px2rem,:

@function px2rem ($px) {
@return $px / 64px * 1rem;
}

这里的64是因为视觉稿是640px的,如果是750px的就是75。可以看一下lib-flexible的说明。

加上转换函数的icons.scss文件是这样的:

$icons: sprite-map("icons/*.png", $spacing: 8px, $layout: smart);

@function px2rem ($px) {
@return $px / 64px * 1rem;
} .icon {
width: px2rem(image-width(sprite-file($icons, card-icon)));
height: px2rem(image-height(sprite-file($icons, card-icon)));
background-image: sprite-url($icons);;
}

生成的css如下:

.icon {
width: 1.20313rem;
height: 1rem;
background-image: url('/images/icons-s37f950be3b.png');
}

好了,第一步转换工作就完成了。我们都知道,使用雪碧图,肯定要使用background-position属性,它的单位也是px,也需要转换,所以需要在icons.scss加上:

$icons: sprite-map("icons/*.png", $spacing: 8px, $layout: smart);

@function px2rem ($px) {
@return $px / 64px * 1rem;
} .icon {
width: px2rem(image-width(sprite-file($icons, card-icon)));
height: px2rem(image-height(sprite-file($icons, card-icon)));
background-image: sprite-url($icons);
background-position: px2rem(sprite-position($icons, car-icon));
}

但是,编译的时候出错了,错误如下:

意思就是:background-position的值为-250px 0,并不能简单的使用px2rem函数,那该怎么办?我们先来判断一下传递给函数的参数的类型:

@function px2rem ($px) {
@warn type-of($px);
@return $px / 64px * 1rem;
}

再次编译(可以使用compass watch进行监听文件的修改),命令行提示如下图:

从图中可以知道:$width$height的类型是number,而$pos类型是list。知道了什么类型就可以对症下药了,修改函数如下:

@function px2rem ($px) {
@if (type-of($px) == "number") {
@return $px / 64px * 1rem;
} @if (type-of($px) == "list") {
@return nth($px, 1) / 64px *1rem nth($px, 2) / 64px * 1rem;
}
}

nth方法可以取出list中的每一项进行运算,输出css如下:

.icon {
width: 1.20313rem;
height: 1rem;
background-image: url('/images/icons-s37f950be3b.png');
background-position: -1.46875rem -1.40625rem;
}

这边又会有个问题:background-position的值有可能是0 00 100px或者100px 0,而0是没有单位的,这样转换的时候会报错,继续对px2rem函数进行改造,如下:

@function px2rem ($px) {
@if (type-of($px) == "number") {
@return $px / 64px * 1rem;
} @if (type-of($px) == "list") {
@if (nth($px, 1) == 0 and nth($px, 2) != 0) {
@return 0 nth($px, 2) / 64px * 1rem;
} @else if (nth($px, 1) == 0 and nth($px, 2) == 0) {
@return 0 0;
} @else if (nth($px, 1) != 0 and nth($px, 2) == 0) {
@return nth($px, 1) / 64px * 1rem 0;
} @else {
@return nth($px, 1) / 64px *1rem nth($px, 2) / 64px * 1rem;
}
}
}

上面对各种为0的情况进行了判断,避免了错误。

下面还需要对background-size属性进行转换。在PC端如果图片不要缩放的话,其实不需要该属性,但在移动端一般是需要的。在移动端,可能很多人不知道该怎么用background-size属性,到底是设置整个雪碧图的大小,还是设置单个sprite的的大小呢?其实是设置整个雪碧图的大小。

好像compass没有内置的方法获得雪碧图的大小,没关系,我们可以等到雪碧图生成的时候,再去查看雪碧图的大小。可以先用两个变量保存雪碧图的宽高,初始化为0

$bigWidth: 0;
$bigHeight: 0;

等雪碧图生成后,查看图片大小,再修改,如:

$bigWidth: 242px;
$bigHeight: 270px;

这时icons.scss文件内容如下:

$icons: sprite-map("icons/*.png", $spacing: 8px, $layout: smart);

$bigWidth: 242px;
$bigHeight: 270px; @function px2rem ($px) {
@if (type-of($px) == "number") {
@return $px / 64px * 1rem;
} @if (type-of($px) == "list") {
@if (nth($px, 1) == 0 and nth($px, 2) != 0) {
@return 0 nth($px, 2) / 64px * 1rem;
} @else if (nth($px, 1) == 0 and nth($px, 2) == 0) {
@return 0 0;
} @else if (nth($px, 1) != 0 and nth($px, 2) == 0) {
@return nth($px, 1) / 64px * 1rem 0;
} @else {
@return nth($px, 1) / 64px *1rem nth($px, 2) / 64px * 1rem;
}
}
} .icon {
width: px2rem(image-width(sprite-file($icons, card-icon)));
height: px2rem(image-height(sprite-file($icons, card-icon)));
background-image: sprite-url($icons);
background-position: px2rem(sprite-position($icons, card-icon));
background-size: px2rem(($bigWidth, $bigHeight));
background-repeat: no-repeat;
}

生成css如下:

.icon {
width: 1.20313rem;
height: 1rem;
background-image: url('/images/icons-s37f950be3b.png');
background-position: -1.46875rem -1.40625rem;
background-size: 3.78125rem 4.21875rem;
background-repeat: no-repeat;
}

到这里,应该可以说是很完美了,但还有改进的空间。我们需要自定义很多类,如:

.icon1 {
width: px2rem(image-width(sprite-file($icons, card-icon)));
height: px2rem(image-height(sprite-file($icons, card-icon)));
background-image: sprite-url($icons);
background-position: px2rem(sprite-position($icons, card-icon));
background-size: px2rem(($bigWidth, $bigHeight));
background-repeat: no-repeat;
} .icon2 {
width: px2rem(image-width(sprite-file($icons, watch-icon)));
height: px2rem(image-height(sprite-file($icons, watch-icon)));
background-image: sprite-url($icons);
background-position: px2rem(sprite-position($icons, watch-icon));
background-size: px2rem(($bigWidth, $bigHeight));
background-repeat: no-repeat;
} ......

上面的每个类中的属性都是一样的,为什么不使用一个mixin,把相同的属性都放进这个mixin中,然后在每个类中引入就可以了。下面来定义一个mixin

@mixin sprite-info ($icons, $name) {
width: px2rem(image-width(sprite-file($icons, $name)));
height: px2rem(image-height(sprite-file($icons, $name)));
background-image: sprite-url($icons);
background-position: px2rem(sprite-position($icons, $name));
background-size: px2rem(($bigWidth, $bigHeight));
background-repeat: no-repeat;
}

使用这个mixin

.card {
@include sprite-info($icons, card-icon);
} .watch {
@include sprite-info($icons, watch-icon);
}

生成css如下:

.card {
width: 1.20313rem;
height: 1rem;
background-image: url('/images/icons-s37f950be3b.png');
background-position: -1.46875rem -1.40625rem;
background-size: 3.78125rem 4.21875rem;
background-repeat: no-repeat;
} .watch {
width: 1.3125rem;
height: 1.40625rem;
background-image: url('/images/icons-s37f950be3b.png');
background-position: 0 0;
background-size: 3.78125rem 4.21875rem;
background-repeat: no-repeat;
}

现在可以说是非常完美了。下面贴出icons.scss文件中最终的代码:

$icons: sprite-map("icons/*.png", $spacing: 8px, $layout: smart);

$bigWidth: 242px;
$bigHeight: 270px; @function px2rem ($px) {
@if (type-of($px) == "number") {
@return $px / 64px * 1rem;
} @if (type-of($px) == "list") {
@if (nth($px, 1) == 0 and nth($px, 2) != 0) {
@return 0 nth($px, 2) / 64px * 1rem;
} @else if (nth($px, 1) == 0 and nth($px, 2) == 0) {
@return 0 0;
} @else if (nth($px, 1) != 0 and nth($px, 2) == 0) {
@return nth($px, 1) / 64px * 1rem 0;
} @else {
@return nth($px, 1) / 64px *1rem nth($px, 2) / 64px * 1rem;
}
}
} @mixin sprite-info ($icons, $name) {
width: px2rem(image-width(sprite-file($icons, $name)));
height: px2rem(image-height(sprite-file($icons, $name)));
background-image: sprite-url($icons);
background-position: px2rem(sprite-position($icons, $name));
background-size: px2rem(($bigWidth, $bigHeight));
background-repeat: no-repeat;
} .card {
@include sprite-info($icons, card-icon);
} .watch {
@include sprite-info($icons, watch-icon);
}

生成的icons.css代码如下:

.card {
width: 1.20313rem;
height: 1rem;
background-image: url('/images/icons-s37f950be3b.png');
background-position: -1.46875rem -1.40625rem;
background-size: 3.78125rem 4.21875rem;
background-repeat: no-repeat;
} .watch {
width: 1.3125rem;
height: 1.40625rem;
background-image: url('/images/icons-s37f950be3b.png');
background-position: 0 0;
background-size: 3.78125rem 4.21875rem;
background-repeat: no-repeat;
}

使用sass与compass合并雪碧图(二)的更多相关文章

  1. 使用sass与compass合并雪碧图(一)

    雪碧图就是很多张小图片合并成一张大图片,以减少HTTP请求,从而提升加载速度.有很多软件可以合并雪碧图,但通常不太容易维护,使用compass生成雪碧图应该算是非常方便的方法了,可以轻松的生成雪碧图, ...

  2. Sass和Compass制作雪碧图

    1.安装好了sass与compass之后设置一个配置文件 2.新增一个雪碧图文件夹用来存放将要合并的图片例如color文件夹 3.@import命令引用 .Compass看到@import指令的参数为 ...

  3. compass做雪碧图

    由于最近没什么时间好好写博文,我把用sass做雪碧图的关键点贴出来方便自己记忆: config.rb注释 # Set this to the root of your project when dep ...

  4. 使用Compass制作雪碧图

    遇见好的文章,笔者也会转载.但是正所谓好记性不如烂笔头,单纯的拿来主义也不如自己的亲自实践.所以每次需要转载的文章,我都会自己敲一遍,中间加入一些自己的思考. 这篇文章转载自:http://www.h ...

  5. 利用compass制作雪碧图

    compass是什么?是sass一款神奇插件,具体教程,我还是推荐阮一峰sass,compass教程,简单清晰明了. 用ps制作雪碧图,工作效率太低了.用compass来制作,方便很多.下图的用com ...

  6. compass Sprites 雪碧图 小图片合成[Sass和compass学习笔记]

    demo 源码 地址 https://github.com/qqqzhch/webfans 什么是雪碧图? CSS雪碧 即CSS Sprites,也有人叫它CSS精灵,是一种CSS图像合并技术,该方法 ...

  7. compass与css sprite(雪碧图)

    什么是css sprite? css sprite,中文叫雪碧图,也有人喊CSS精灵,就是一种背景拼合的技术,然后通过background-position来显示雪碧图中需要显示的图像. MDN相关链 ...

  8. sass制作雪碧图

    1.配置文件config.rb http_path = "../../../" css_dir = "Content/css" sass_dir = " ...

  9. compass框架的sprite雪碧图的用法简要

    ---恢复内容开始--- **简介** CSS SPRITE 即 CSS雪碧,即是将诸多图片合成一张图片,然后使用CSS 的background和background-position属性渲染. 这样 ...

随机推荐

  1. 集合之Map总结

    在前面LZ详细介绍了HashMap.HashTable.TreeMap的实现方法,从数据结构.实现原理.源码分析三个方面进行阐述,对这个三个类应该有了比较清晰的了解,下面LZ就Map做一个简单的总结. ...

  2. NYOJ 44 字串和 (最大字串和 线性dp)

    题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=44 子串和 时间限制:5000 ms  |  内存限制:65535 KB 难度:3 ...

  3. ArcGIS中的坐标系统定义与投影转换(转)

    ArcGIS中的坐标系统定义与投影转换 ArcGIS中的坐标系统定义与投影转换 坐标系统是GIS数据重要的数学基础,用于表示地理要素.图像和观测结果的参照系统,坐标系统的定义能够保证地理数据在软件中正 ...

  4. Android :Activity、Adapter、List的初步学习

    Activity Activity 是一个应用组件,用户可与其提供的屏幕进行交互,以执行对手机应用操作. 每个 Activity 都会获得一个用于绘制其用户界面的窗口.窗口一般是会充满屏幕,但也不一定 ...

  5. block本质探寻八之循环引用

    说明:阅读本文,请参照之前的block文章加以理解: 一.循环引用的本质 //代码——ARC环境 void test1() { Person *per = [[Person alloc] init]; ...

  6. NRF52832初步使用

    开发环境搭建 开发环境涉及到协议栈SDK版本.keil PACK版本的匹配问题,目前测试通过的环境如下: windows系统:win10 硬件:NRF52832测试板.JLINK-V8仿真器 Keil ...

  7. 20145209刘一阳《JAVA程序设计》第七周课堂测试

    第七周课堂测试 1.命令"CREATE DATABASE "用来创建一个数据库.(A) A .true B .false 2.以下不属于驱动的四种类型的是(C) A .JDBC-O ...

  8. PostgreSQL集群方案相关索引页

    磨砺技术珠矶,践行数据之道,追求卓越价值 返回顶级页:PostgreSQL索引页 本页记录所有本人所写的PostgreSQL的集群方案相关文摘和文章的链接: pgpool-II: 1 pgpool-I ...

  9. PyQt5 笔记(05):信号/槽

    PyQt 的很多类都内置了信号和槽.下图是 Qt 官方文档对 QThread 类中包含的信号/槽的描述: 一.信号/槽 都是内置的 请看一个最简单的程序: 按钮点击后,窗口关闭 代码: class T ...

  10. Spring 单元测试 RequestContextHolder.getRequestAttributes()).getRequest(); 为空的原因

    原因是因为单元测试时没有加载 web.xml 中的: <!-- spring在service层获取session和request需要创建的监听器 --> <listener> ...