sass入门
Have you always wanted to learn Sass, but never quite made your move? Are you a Sass user, but feel like you could use a brush up? Well then read on, because today we are going to review the features of Sass and some of the cool things you can do with it.
您是否一直想学习Sass,但从未真正采取行动? 您是Sass用户,但感觉可以使用画笔吗? 好吧,请继续阅读,因为今天我们将回顾Sass的功能以及您可以使用它完成的一些很酷的事情。
什么是萨斯? (What is Sass?)
Sass (Syntactically Awesome Style Sheets) is a CSS preprocessor. It is to CSS what CoffeeScript is to Javascript. Sass adds a feature set to your stylesheet markup that makes writing styles fun again.
Sass(语法上很棒的样式表)是CSS预处理程序。 对CSS而言,CoffeeScript对Javascript而言。 Sass在样式表标记中添加了一个功能集,使编写样式再次变得有趣。
那么,它如何运作? (So uh, how does it work?)
Funny you should ask. There are several ways you can compile Sass:
你应该问有趣。 有几种编译Sass的方法:
- The original Ruby Sass binary. Install it with
gem install sass
, and compile it by runningsassc myfile.scss myfile.css
. 原始的Ruby Sass二进制文件。 使用gem install sass
进行gem install sass
,并通过运行sassc myfile.scss myfile.css
编译。 - A GUI app such as Hammer, CodeKit, or Compass GUI应用程序,例如Hammer , CodeKit或Compass
- My personal favorite libsass, which is a blazing fast Sass compiler written in C. You can also install libsass via NPM with node-sass (
npm install node-sass
). 我个人最喜欢的libsass ,这是一个用C语言编写的快速Sass编译器。您还可以通过NPM使用node-sass (npm install node-sass
)安装libsass。
Which one should you use? That depends on what you are doing.
您应该使用哪一个? 那要看你在做什么。
I work with large scale e-commerce codebases, so Ruby Sass is a little slow when compiling large source sets. I use node-sass in my build system, but I have to remain wary of the fact that libsass is not in 100% feature parity with Ruby Sass.
我使用大型电子商务代码库,因此Ruby Sass在编译大型源集时有点慢。 我在构建系统中使用了node-sass,但是我必须谨防libsass与Ruby Sass不能100%地实现同等功能。
If you aren't a command line person, the GUI apps are great. You can set them up to watch scss files, so when you edit them they will compile automatically.
如果您不是命令行用户,那么GUI应用程序就很棒。 您可以将它们设置为监视scss文件,因此在编辑它们时它们将自动编译。
If you want to just screw around, or share examples, I highly recommend Sassmeister. It is a web based Sass playground that I will be using throughout this article.
如果您只是想转转或分享示例,我强烈推荐Sassmeister 。 这是一个基于Web的Sass游乐场,我将在本文中使用。
.sass与.scss有什么关系? (Whats the deal with .sass vs .scss?)
When Sass first came out, the main syntax was noticably different from CSS. It used indentation instead of braces, didn't require semi-colons and had shorthand operators. In short, it looked a lot like Haml.
当Sass首次问世时,主要语法与CSS明显不同。 它使用缩进代替大括号,不需要分号,并且具有简写运算符。 简而言之,它看起来很像Haml 。
Some folks didn't take too kindly to the new syntax, and in version 3 Sass changed it's main syntax to .scss. SCSS is a superset of CSS, and is basically written the exact same, but with all the fun new Sass features.
有些人对新语法不太友好,在第3版中,Sass将其主要语法更改为.scss。 SCSS是CSS的超集,基本上写成完全相同,但是具有所有有趣的Sass新功能。
That said, you can still use the original syntax if you want to. I personally use .scss, and I will be using the .scss syntax in this article.
也就是说,您仍然可以使用原始语法。 我个人使用.scss,并且在本文中将使用.scss语法。
我为什么要使用Sass? (Why would I use Sass?)
Good question. Sass makes writing maintainable CSS easier. You can get more done, in less code, more readably, in less time.
好问题。 Sass使编写可维护CSS更加容易。 您可以用更少的代码,更少的时间,更可读的方式完成更多工作。
Do you need more of a reason than that?
您是否需要更多的理由?
建立 (Set Up)
Without any further ado, lets get this party started. If you want to try some of these concepts while following along, either:
事不宜迟,让我们开始这个聚会。 如果您想在尝试时尝试其中一些概念,请执行以下任一操作:
- Install your compilation method of choice, and create a
style.scss
file. 安装您选择的编译方法,并创建一个style.scss
文件。
Or
要么
- Follow along on Sassmeister 跟随萨斯迈斯特(Sassmeister)
变数 (Variables)
Thats right, variables. Sass brings variables to CSS.
没错,变量。 Sass将变量带到CSS。
Acceptable values for variables include numbers, strings, colors, null, lists and maps.
可接受的变量值包括数字,字符串,颜色,空值,列表和映射。
Variables in Sass are scoped using the $
symbol. Lets create our first variable:
Sass中的变量使用$
符号限定范围。 让我们创建第一个变量:
$primaryColor: #eeffcc;
If you tried to compile this and didn't see anything in your CSS, you're doin' it right. Defining variables on their own doesn't actually output any css, it just sets it within the scope. You need to use it within a CSS declaration to see it:
如果您尝试对其进行编译而在CSS中看不到任何内容,那么您就正确了。 单独定义变量实际上不会输出任何CSS,而只是在范围内进行设置。 您需要在CSS声明中使用它才能看到它:
$primaryColor: #eeffcc;
body {
background: $primaryColor;
}
Speak of the devil (scope), did you know that Sass has variable scope? Thats right, if you declare a variable within a selector, it is then scoped within that selector. Check it out:
说到魔鬼(范围),您知道Sass的范围可变吗? 没错,如果您在选择器中声明变量,则该变量将在该选择器中作用域。 看看这个:
$primaryColor: #eeccff;
body {
$primaryColor: #ccc;
background: $primaryColor;
}
p {
color: $primaryColor;
}
// When compiled, our paragraph selector's color is #eeccff
But what if we want to set a variable globally from within a declaration? Sass provides a !global
flag that comes to our rescue:
但是,如果我们想从声明中全局设置变量,该怎么办? Sass提供了一个!global
标记来帮助我们:
$primaryColor: #eeccff;
body {
$primaryColor: #ccc !global;
background: $primaryColor;
}
p {
color: $primaryColor;
}
// When compiled, our paragraph selector's color is #ccc
Another helpful flag, particularly when writing mixins, is the !default
flag. This allows us to make sure there is a default value for a variable in the event that one is not provided. If a value is provided, it is overwritten:
另一个有用的标志是!default
标志,尤其是在编写mixins时。 这样,我们可以确保在未提供变量的情况下为变量提供默认值。 如果提供了一个值,它将被覆盖:
$firstValue: 62.5%;
$firstValue: 24px !default;
body {
font-size: $firstValue;
}
// body font size = 62.5%
Play with some variables below to see how the Sass you are writing is compiled to CSS:
使用下面的一些变量来查看您正在编写的Sass如何编译为CSS:
Play with this gist on SassMeister.
数学 (Math)
Unlike CSS, Sass allows us to use mathematical expressions! This is super helpful within mixins, and allows us to do some really cool things with our markup.
与CSS不同,Sass允许我们使用数学表达式! 这在mixins中非常有帮助,并允许我们使用标记做一些非常酷的事情。
Supported operators include:
支持的运营商包括:
+ | Addition |
- | Subtraction |
/ | Division |
* | Multiplication |
% | Modulo |
== | Equality |
!= | Inequality |
+ | 加成 |
-- | 减法 |
/ | 师 |
* | 乘法 |
% | 模数 |
== | 平等 |
!= | 不等式 |
Before moving forward, I want to note two potential "gotchas" with Sass math.
在继续之前,我想指出Sass数学的两个潜在“陷阱”。
First, because the /
symbol is used in shorthand CSS font properties like font: 14px/16px
, if you want to use the division operator on non-variable values, you need to wrap them in parentheses like:
首先,由于/
符号用于速记CSS字体属性(例如font: 14px/16px
,如果要对非变量值使用除法运算符,则需要将其包装在括号中,例如:
$fontDiff: (14px/16px);
Second, you can't mix value units:
其次,您不能混合使用价值单位:
$container-width: 100% - 20px;
The above example won't work. Instead, for this particular example you could use the css calc
function, as it needs to be interpereted at render time.
上面的例子不起作用。 相反,对于此特定示例,您可以使用css calc
函数,因为它需要在渲染时calc
作用。
Back to math, lets create a dynamic column declaration, based upon a base container width:
回到数学上,让我们根据基本容器的宽度创建一个动态的列声明:
$container-width: 100%;
.container {
width: $container-width;
}
.col-4 {
width: $container-width / 4;
}
// Compiles to:
// .container {
// width: 100%;
// }
//
// .col-4 {
// width: 25%;
// }
Awesome, right? Check out in the example below how we can further leverage Sass math to add margins. Play around with the values to see our example change:
太好了吧? 在下面的示例中查看我们如何进一步利用Sass数学来增加边距。 试一下这些值以查看我们的示例更改:
Play with this gist on SassMeister.
功能 (Functions)
The best part of Sass, in my opinion, are it's built in functions. You can see the full list here. It is EXTENSIVE.
我认为,Sass最好的部分是内置函数。 您可以在此处查看完整列表。 太贵了 。
Have you ever wanted to make a cool looking button, and then taken the time to mess around on a color wheel, trying to find the right shades for 'shadowed' parts?
您是否曾经想过要一个看起来很酷的按钮,然后花时间在色轮上弄乱,试图为“阴影”部分找到合适的阴影?
Enter the darken()
function. You can pass it a color and a percentage and it, wait for it, darkens your color. Check this demo out to see why this is cool:
输入darken()
函数。 您可以为它传递颜色和百分比,然后等待它使颜色变暗。 查看此演示以了解为什么如此酷:
Play with this gist on SassMeister.
套料 (Nesting)
One of the most helpful, and also misused features of Sass, is the ability to nest declarations. With great power comes great responsibility, so lets take a second to realize what this does, and in the wrong hands, what bad things it could do.
嵌套声明的功能是Sass最有用,也是最被滥用的功能之一。 强大的力量伴随着巨大的责任,因此,让我们花点时间来意识到这是做什么的,并在错误的手中掌握它可能会做的坏事。
Basic nesting refers to the ability to have a declaration inside of a declaration. In normal CSS we might write:
基本嵌套是指在声明内具有声明的能力。 在普通CSS中,我们可以这样写:
.container {
width: 100%;
}
.container h1 {
color: red;
}
But in Sass we can get the same result by writing:
但是在Sass中,我们可以通过编写以下内容获得相同的结果:
.container {
width: 100%;
h1 {
color: red;
}
}
Thats bananas! So what if we want to reference the parent? This is achieved by using the &
symbol. Check out how we can leverage this to add pseudo selectors to anchor elements:
那就是香蕉! 那么,如果我们想引用父母呢? 这是通过使用&
符号。 看看我们如何利用它为锚元素添加伪选择器:
a.myAnchor {
color: blue;
&:hover {
text-decoration: underline;
}
&:visited {
color: purple;
}
}
Now we know how to nest, but if we want to de-nest, we have to use the @at-root
directive. Say we have a nest set up like so:
现在我们知道如何嵌套,但是如果要嵌套,则必须使用@at-root
指令。 假设我们像这样设置了一个嵌套:
.first-component {
.text { font-size: 1.4rem; }
.button { font-size: 1.7rem; }
.second-component {
.text { font-size: 1.2rem; }
.button { font-size: 1.4rem; }
}
}
After realizing that the second component might be used elwhere, we have ourselves a pickle. Well, not really. @at-root
to the rescue:
意识到第二个组件可能在其他地方使用后,我们自己得到了一个泡菜。 好吧,不是真的。 @at-root
上进行救援:
Play with this gist on SassMeister.
Cool huh? Nests are a really great way to save some time and make your styles readable, but overnesting can cause problems with overselection and file size. Always look at what your sass compiles to and try to follow the "inception rule".
酷吧? 嵌套是节省时间和使样式易于阅读的好方法,但是嵌套过多会导致选择过多和文件大小问题。 始终查看您的混蛋编译的内容,并尝试遵循“初始规则”。
The Inception Rule: don’t go more than four levels deep.
初始规则:不要超过四个层次。
via http://thesassway.com/
通过 http://thesassway.com/
If possible, don't nest more than four levels. If you, in a pinch, have to go five levels deep, Hampton Catlin isn't going to come to your house and fight you. Just try not to do it.
如果可能的话,嵌套的层数不要超过四个。 如果您在紧要关头必须深入五个层次,汉普顿·卡特琳(Hampton Catlin)就不会来您家与您抗争。 只是尝试不做。
进口货 (Imports)
Easily my second favorite part of Sass, imports allow you to break your styles into separate files and import them into one another. This does wonders for organization and speed of editing.
轻松地成为Sass的第二个最喜欢的部分,导入使您可以将样式分解为单独的文件,然后将它们相互导入。 这确实为组织和编辑速度带来了奇迹。
We can import a .scss file using the @import
directive:
我们可以使用@import
指令导入.scss文件:
@import "grids.scss";
In fact, you don't even really need the extension:
实际上,您甚至根本不需要扩展名:
@import "grids";
Sass compilers also include a concept called "partials". If you prefix a .sass or .scss file with an underscore, it will not get compiled to CSS. This is helpful if your file only exists to get imported into a master style.scss
and not explicitly compiled.
Sass编译器还包含一个称为“部分”的概念。 如果为.sass或.scss文件添加下划线前缀,则该文件不会编译为CSS。 如果您的文件仅存在以便导入到主style.scss
而不进行显式编译,则这将很有帮助。
扩展和占位符 (Extends & Placeholders)
In Sass, the @extend
directive is an outstanding way to inherit already existing styles.
在Sass中, @extend
指令是一种继承现有样式的出色方法。
Lets use an @extend
directive to extend an input's style if it has an input-error
class:
如果input-error
具有input-error
类,则使用@extend
指令扩展输入的样式:
.input {
border-radius: 3px;
border: 4px solid #ddd;
color: #555;
font-size: 17px;
padding: 10px 20px;
display: inline-block;
outline: 0;
}
.error-input {
@extend .input;
border:4px solid #e74c3c;
}
Please note, this does not copy the styles from .input
into .error-input
. Take a look at the compiled CSS in this example to see how it is intelligently handled:
请注意,这不会将样式从.input
复制到.error-input
。 看一下此示例中的已编译CSS,以了解如何对其进行智能处理:
Play with this gist on SassMeister.
But what about if we want to extend a declaration with a set of styles that doesn't already exist? Meet the placeholder selector.
但是,如果我们想用一组尚不存在的样式扩展声明,那该怎么办? 遇到占位符选择器。
%input-style {
font-size: 14px;
}
input {
@extend %input-style;
color: black;
}
The placeholder selector works by prefixing a class name of your choice with a %
symbol. It is never rendered outright, only the result of its extending elements are rendered in a single block.
占位符选择器通过在您选择的类名称前加上%
符号来起作用。 它永远不会被完全渲染,只有其扩展元素的结果会在单个块中渲染。
Check out below how our previous example works with a placeholder:
请在下面查看我们之前的示例如何与占位符一起使用:
Play with this gist on SassMeister.
混合蛋白 (Mixins)
The mixin directive is an incredibly helpful feature of Sass, in that it allows you to include styles the same way @extend
would, but with the ability to supply and interperet arguments.
mixin指令是Sass的一项非常有用的功能,因为它允许您以与@extend
相同的方式包含样式,但是具有提供和自变量的能力。
Sass uses the @mixin
directive to define mixins, and the @include
directive to use them. Lets build a simple mixin that we can use for media queries!
Sass使用@mixin
指令定义mixins,使用@include
指令使用它们。 让我们构建一个可用于媒体查询的简单mixin!
Our first step is to define our mixin:
我们的第一步是定义我们的混合:
@mixin media($queryString){
}
Notice we are calling our mixin media
and adding a $queryString
argument. When we include our mixin, we can supply a string argument that will be dynamically rendered. Lets put the guts in:
注意,我们正在调用mixin media
并添加$queryString
参数。 当包含mixin时,我们可以提供将动态呈现的字符串参数。 让我们胆量:
@mixin media($queryString){
@media #{$queryString} {
@content;
}
}
Because we want our string argument to render where it belongs, we use the Sass interpolation syntax, #{}
. When you put a variable in between the braces, it is printed rather than evaluated.
因为我们希望我们的字符串参数能够呈现它所属的位置,所以我们使用Sass插值语法#{}
。 当您在括号之间放置一个变量时,将打印该变量而不是对其求值。
Another piece of our puzzle is the @content
directive. When you wrap a mixin around content using braces, the wrapped content becomes available via the @content
directive.
我们的另一个难题是@content
指令。 当您使用大括号将内容混合到内容中时,可通过@content
指令使用已包装的内容。
Finally, lets use our mixin with the @include
directive:
最后,让我们的mixin与@include
指令一起使用:
.container {
width: 900px;
@include media("(max-width: 767px)"){
width: 100%;
}
}
Check out the demo below to see how our new mixin renders media queries:
观看下面的演示,看看我们的新mixin如何呈现媒体查询:
Play with this gist on SassMeister.
功能指令 (Function Directives)
Function directives in Sass are similar to mixins, but instead of returning markup, they return values via the @return
directive. They can be used to DRY (Don't repeat yourself) up your code, and make everything more readable.
Sass中的函数指令与mixins相似,但是它们不返回标记,而是通过@return
指令返回值。 它们可以用来使您的代码干燥(不要重复),并使所有内容更具可读性。
Lets go ahead and create a function directive to clean up our grid calculations from our grid demo:
让我们继续创建一个函数指令,以从网格演示中清除网格计算:
@function getColumnWidth($width, $columns,$margin){
@return ($width / $columns) - ($margin * 2);
}
Now we can use this function in our code below:
现在,我们可以在下面的代码中使用此功能:
$container-width: 100%;
$column-count: 4;
$margin: 1%;
.container {
width: $container-width;
}
.column {
background: #1abc9c;
height: 200px;
display: block;
float: left;
width: getColumnWidth($container-width,$column-count,$margin);
margin: 0 $margin;
}
Pretty cool, eh?
很酷吧?
演示版 (Demo)
Now that we have all these tools at our disposal, how about we build our own configurable grid framework? Lets roll:
既然我们拥有所有这些工具,那么我们如何构建自己的可配置网格框架? 来吧:
Lets begin by creating a map of settings:
让我们从创建设置图开始:
$settings: (
maxWidth: 800px,
columns: 12,
margin: 15px,
breakpoints: (
xs: "(max-width : 480px)",
sm: "(max-width : 768px) and (min-width: 481px)",
md: "(max-width : 1024px) and (min-width: 769px)",
lg: "(min-width : 1025px)"
)
);
Next lets write a mixin that renders our framework:
接下来,让我们编写一个渲染我们的框架的mixin:
@mixin renderGridStyles($settings){
}
We are going to need to render markup for each breakpoint, so lets iterate through our breakpoints and call our media mixin. Lets use the map-get
method to get our breakpoint values, and our @each
directive to iterate through our breakpoints:
我们将需要为每个断点渲染标记,因此让我们遍历断点并调用我们的媒体mixin。 让我们使用map-get
方法获取我们的断点值,并使用我们的@each
指令遍历我们的断点:
@mixin renderGridStyles($settings){
$breakpoints: map-get($settings, "breakpoints");
@each $key, $breakpoint in $breakpoints {
@include media($breakpoint) {
}
}
}
We need to render the actual grid markup within our iteration, so lets create a renderGrid
mixin. Lets use the map-get
method to get our map values, and our @while
directive to iterate through columns with $i
as our index. We render our class name using interpolation.
我们需要在迭代中渲染实际的网格标记,因此让我们创建一个renderGrid
mixin。 让我们使用map-get
方法获取我们的地图值,并使用@while
指令遍历以$i
为索引的列。 我们使用插值法渲染类名。
@mixin renderGrid($key, $settings) {
$i: 1;
@while $i <= map-get($settings, "columns") {
.col-#{$key}-#{$i} {
float: left;
width: 100% * $i / map-get($settings,"columns");
}
$i: $i+1;
}
}
Next, lets add container and row styles:
接下来,让我们添加容器和行样式:
.container {
padding-right: map-get($settings, "margin");
padding-left: map-get($settings, "margin");
margin-right: auto;
margin-left: auto;
}
.row {
margin-right: map-get($settings, "margin") * -1;
margin-left: map-get($settings, "margin") * -1;
}
It's alive! Check out the demo of our framework below:
它还活着! 在下面查看我们框架的演示:
Play with this gist on SassMeister.
结语 (Wrap Up)
You may reach this point and think that we have covered quite a bit of Sass, but really it is just the tip of the iceberg. Sass is an extremely powerful tool that you can do some really incredible things with.I look forward to following up with an article on advanced concepts, but until then Happy Sassing and check out some of the resources below:
您可能会到达这一点,并认为我们已经涵盖了相当多的Sass,但实际上这只是冰山一角。 Sass是一个非常强大的工具,您可以使用它来做一些非常令人难以置信的事情。我希望继续阅读有关高级概念的文章,但是在此之前,Happy Sassing并查看以下一些资源:
资源资源 (Resources)
- The Sass Way - A phenomenal source of Sass tutorials. Sass Way -Sass教程的惊人来源。
- Hugo Giraudel - An amazing tech writer & Sass wizard with a keen focus on Sass. Hugo Giraudel-一个了不起的技术作家和Sass向导,热衷于Sass。
- SassNews - A twitter account managed by Stuart Robson that will keep you in the know. SassNews-由Stuart Robson管理的Twitter帐户,它将使您随时了解。
sass入门