【译】如何编写“移动端优先”CSS
原文链接:https://zellwk.com/blog/how-to-write-mobile-first-css/
构建响应式网站是如今前端开发者的必备技能,当我们谈到响应式网站时,“移动端优先”这个词立刻就会出现在脑海中。
我们知道从“移动端优先”这个角度开始设计很重要,但我们很少谈到使用“移动端优先”的方法来写代码。
今天,我想与你分享“移动端优先”添加样式的方法,为什么这种方法更好,以及如何发挥它的魔力。
贴士:如果你在学习使用Susy来建立响应式布局,这篇文章会对你帮助非常大。
#什么是“移动端优先”和“桌面优先”方法?
在开始讨论为什么“移动端优先”方法更好之前,我们先了解下“移动端优先”与“桌面优先”之间的区别。
“移动端优先”添加样式的方法指的是首先在移动设备上应用样式,然后通过媒体查询在样式表中加入应用于大屏幕的高级样式和其他覆盖样式。
这个方法使用min-width媒体查询。
这里是一个简单的例子:
// 这个样式在0px到600px应用
body { background: red; } // 这个样式在大于600px时应用
@media (min-width: 600px) {
body { background: green; }
}
在上面的例子中,当视口小于600px时,<body>的背景是红色的,当视口等于或大于600px时,背景变成绿色。
另一方面,“桌面优先”添加样式的方法指的是首先在桌面设备上应用样式,然后通过媒体查询在样式表中加入应用于小屏幕的高级样式和其他覆盖样式。
这个方法使用max-width媒体查询。
这里是一个简单的例子:
// 这个样式在大于600px时应用
body { background: green; } // 这个样式在0px到600px应用
@media (max-width: 600px) {
body { background: red; }
}
在任意宽度下,<body>会有一个绿色的背景,但当屏幕小于600px时,背景颜色会变成红色。
#为什么要写“移动端优先”代码?
为大屏幕编写的代码通常会比为小屏幕编写的代码更复杂,所以编写“移动端优先”代码可以简化你的代码。
设想这样一个场景,你的网站有一个“内容-边栏”布局,.content在移动端占会100%的宽度,在桌面则占60%的宽度。
大部分情况下,在小屏幕中,我们可以依赖默认属性给内容应用样式,在这个例子中,<div>的默认宽度为100%。
如果我们用的是“移动端优先”方法,Sass代码会是这样的:
.content {
// 为小屏幕设置属性
// 这里不需要设置任何属性,因为我们可以使用默认样式 // 为大屏幕设置属性
@media (min-width: 800px) {
float: left;
width: 60%;
}
}
如果我们用的是“桌面优先”的方法,大部分情况下我们需要为小视口重写默认样式,Sass代码会是这样:
.content {
// 为大屏幕设置属性
float: left;
width: 60%; // 为小屏幕设置属性
// 注意我们需要重写两个默认属性才能使这个布局正常显示
@media (max-width: 800px) {
float: none;
width: 100%;
}
}
在这个例子中,我们节省了两行代码以及几秒钟的思考时间(不用思考令人头疼的CSS)。想象下如果你在建立一个更大的网站,这个方法会给你省下多少时间和努力。
大多数时候min-width查询足够帮助你写一个网站,然而,在只使用min-width无法满足需求的情况下,min-width和max-width的结合使用能够帮助你减少麻烦。
让我们来研究一下这些情况。
#使用“移动端优先”方法和max-width查询
当你希望在小于特定视口大小时应用某样式的时候,max-width查询就能发挥它的作用了。min-width和max-width媒体查询的结合使用则可以在两个不同视口大小间控制样式。
设想一个缩略图库例子,在小视口中,这个图库每行显示3个缩略图,在大视口中,每行4个。
因为每个缩略图之间没有间隔,所以代码很简单:
.gallery__item {
float: left;
width: 33.33%;
@media (min-width: 800px) {
width: 25%;
}
}
如果每个缩略图之间有空白间隔,情况会变得稍复杂。
假设这些间隔占整个宽度的5%:
.gallery__item {
float: left;
width: 30%;
margin-right: 5%;
margin-bottom: 5%;
}
我们还需要把每行最后的(第3个)缩略图的margin-right设为0,以免它被推到下一行。
.gallery__item {
float: left;
width: 30%;
margin-right: 5%;
margin-bottom: 5%;
&:nth-child(3n) {
margin-right: 0;
}
}
当每行有4个缩略图时也应该是这样,但如果我们还是使用之前所用的min-width查询.....
.gallery__item {
float: left;
width: 30%;
margin-right: 5%;
margin-bottom: 5%;
&:nth-child(3n) {
margin-right: 0;
} @media (min-width: 800px) {
width: 21.25%; // (100% - 15%) / 4
&:nth-child(4n) {
margin-right: 0;
}
}
}
情况并非预想中的那样,这是因为我们指定第3n(3的倍数)个缩略图的margin-right为0,由于层叠效应,这个属性在大视口中依然起作用,破坏了我们的预想中的模式。
我们可以通过重设第3n(3的倍数)个缩略图的margin-right为5%这个方法来解决问题:
.gallery__item {
// ...
@media (min-width: 800px) {
// ...
&:nth-child(3n) {
margin-right: 5%;
}
&:nth-child(4n) {
margin-right:;
}
}
}
这个方法并不是太好,因为如果我们需要修改大视口中缩略图的数量,我们要重复margin-right: 5%;
我们应该尽可能使代码保持DRY(Don't Repeat Yourself. 不要重复代码。)。
更好的解决办法是使用max-width查询把选择器nth-child(3n)限制在对应的视口中。
.gallery__item {
float: left;
margin-right: 5%;
margin-bottom: 5%;
@media (max-width: 800px) {
width: 30%;
&:nth-child(3n) {
margin-right: 0;
}
} @media (min-width: 800px) {
width: 21.25%; // (100% - 15%) / 4
&:nth-child(4n) {
margin-right: 0;
}
}
}
这个办法能起作用是因为max-width属性把选择器限制在小于800px的视口中,其中定义的样式不会影响其他视口的样式。
现在想象一下有一个更大的视口,你想要在图库中每行显示5个缩略图,这时候该min-width和max-width查询联手出动了。
.gallery__item {
float: left;
margin-right: 5%;
margin-bottom: 5%;
@media (max-width: 800px) {
width: 30%;
&:nth-child(3n) {
margin-right: 0;
}
} // min-width和max-width查询结合使用
@media (min-width: 800px) and (max-width: 1200px) {
width: 21.25%; // (100% - 15%) / 4
&:nth-child(4n) {
margin-right: 0;
}
} @media (min-width: 1200px) {
width: 16%; // (100% - 20%) / 5
&:nth-child(5n) {
margin-right: 0;
}
}
}
#视频!
Webucator上一群很好的小伙子自愿制作了一个视频来总结这篇博客,所以如果你觉得视频更适合你,一定要去看看他们的视频。
#总结
建立响应式网站时,min-width媒体查询非常有用,因为它减低了代码复杂度。不过,从上面的例子中可以看出,min-width查询并非所有问题的解决方案,有时在样式表中使用max-width查询也是有益的,它能帮助你保持代码更DRY。
【译】如何编写“移动端优先”CSS的更多相关文章
- 移动端特殊css样式
一般会用normalize.css或者reset.css重置样式 移动端特殊css样式 去除ios 按钮按下的默认高亮效果 -webkit-tap-highlight-color : none; io ...
- 开始编写寄几的 CSS 基础库
前言 在现在的互联网业务中,前端开发人员往往需要支持比较多的项目数量.很多公司只有 1-2 名前端开发人员,这其中还不乏规模比较大的公司.这时前端同学就需要独挡一面支持整个公司上下的前端业务,项目如流 ...
- golang学习笔记18 用go语言编写移动端sdk和app开发gomobile
golang学习笔记18 用go语言编写移动端sdk和app开发gomobile gomobile的使用-用go语言编写移动端sdk和app开发https://blog.csdn.net/u01249 ...
- 编写可维护的CSS
在参与规模庞大.历时漫长且参与人数众多的项目时,所有开发者遵守如下规则极为重要: 保持 CSS 便于维护 保持代码清晰易懂 保持代码的可拓展性 为了实现这一目标,我们要采用诸多方法. 本文档第一部分将 ...
- 移动端页面(css)调试之“weinre大法”
移动端页面调试一般分两步.第一步我们需要把本地(pc端)写的页面效果展现在移动端,一个很方便的办法是用 fiddler 作为代理,具体可以参考 如何用 fiddler 代理调试本地手机页面,这样我们就 ...
- 【转】编写更好的CSS代码
原文转自:http://blog.jobbole.com/55067/ 编写好的CSS代码,有助提升页面的渲染速度.本质上,引擎需要解析的CSS规则越少,性能越好.MDN上将CSS选择符归类成四个主要 ...
- 编写更好的CSS
编写好的CSS代码能提升页面的渲染速度.本质上,一条规则都没有引擎解析的最快.MDN上将CSS选择符归拆分成四个主要类别,如下所示,性能依次降低. ID 规则 Class 规则 标签规则 通用规则 对 ...
- 【JavaScript】【译】编写高性能JavaScript
英文链接:Writing Fast, Memory-Efficient JavaScript 很多JavaScript引擎,如Google的V8引擎(被Chrome和Node所用),是专门为需要快速执 ...
- 移动端页面 css reset
这个是通用的 css reset.这个版本适用于 移动端页面 如果需要在 PC端使用,可以 修改 html{font-size: 10px;}为html{font-size: 12px;} 其他地方 ...
随机推荐
- sparkSQL脚本更改问题
相应的pom依赖文件 <dependencies> <!-- <dependency> <groupId>org.apache.storm</group ...
- 【安卓基础】ImageView与EditText联动实现隐藏与显示密码
项目中经常会有这样的需求,在密码输入框的右边有一个小图标,点击就切换显示和隐藏密码. 其实这里需求实现起来是比较容易的,主要考虑是复用问题,因为登陆.注册.修改密码界面都会有这样的情景,如果每个界面都 ...
- 推荐一个好用的E2E前端测试框架cypress
Cypress 是一个E2E的前端自动化测试框架,同样是基于BDD的思想设计的,话不多说,上demo https://github.com/Spillage/cypress-demo PS, 还有一个 ...
- 【转】Binlog 基本操作
MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的. 一般 ...
- go生成不重复的纯数字6位的随机数
最近在学go, 按照入门指南学完go的基础语法, 开始学习go的标准库; 借用生成这个小任务复习一下go的基础语法. 推荐go编辑, jb公司的goland, 超级好用. 推荐go入门指南, htt ...
- 最长绝对文件路径——算法面试刷题1(google),字符串处理,使用tree遍历dfs类似思路
假设我们通过以下的方式用字符串来抽象我们的文件系统: 字符串"dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext"代表了: dir subdir1 su ...
- GNOME 系统设置
详细的GNOME系统设置全文,参见这里. 以下摘录使用到的部分. 1. 在任务栏上显示日期或周几(二选一).秒数 $ gsettings set org.gnome.desktop.interface ...
- FastDFS 与 Nginx 实现分布式图片服务器
FastDFS 与 Nginx 实现分布式图片服务器 本人的 Ubuntu18.04 用户名为 jj 点我下载所有所需的压缩包文件 一.FastDFS安装 1.安装 fastdfs 依赖包 ① 解压 ...
- 在电脑端同时安装Python2,Python3
参考文档:http://www.cnblogs.com/zhengyihan1216/p/6011640.html 重点: 1.安装路径最好在一起,方便管理 2.安装路径下不建议有空格 3.Pytho ...
- jdbc模板
public class JdbcTest { public static void main(String[] args) { //数据库连接 Connection connection = nul ...