kittygiraudel / sass-guidelines Goto Github PK
View Code? Open in Web Editor NEWGuidelines for writing sane, maintainable and scalable Sass.
Home Page: http://sass-guidelin.es
License: MIT License
Guidelines for writing sane, maintainable and scalable Sass.
Home Page: http://sass-guidelin.es
License: MIT License
.element
is used as an example SASS rule.
Naming classes either 'element' (vague) or after an element (eg '.p' - redundant, there is already an element for that) is generally considered poor.
These examples should be either elementName
or className
I'd like to suggest prefixing variable names with a namespace(?) whenever possible. This makes auto-complete a lot more useable, especially for things that can end up with weird names like colors and breakpoints. It can save trips to other files as well. Yes, I am that lazy.
$color--sass-pink: hsl(330, 50%, 60%);
$color--theme-primary: $color-sass-pink;
$breakpoint--narrow: 767px;
$breakpoint--wide: 900px;
Initially developed in Ruby Sass, varied ports popped here and there
Should probably be:
Initially developed in Ruby Sass, varied ports popped up here and there
Another:
LibSass, written in C is now close to be fully compatible
Should be:
LibSass, written in C, is now close to being fully compatible
Media-queries in rulesets should immediately follow element's declarations. Otherwise if a ruleset is to contain other (sometimes many) nested elements, the media-query related to the element is shifting context and is less readable.
.foo {
display: none;
@include respond-to("small") {
display: block;
}
.bar { ... }
span { ... }
&:hover {
color: red;
.bar { ... }
}
}
A very good guide of Outlining a system for writing Sass.
In the Zeros section it's said "Numbers should display leading zeros before a decimal value less than one."
On the contrary, the TL;DR section at the bottom recommends "No leading or trailing 0;"
While I agree that we should generally avoid nesting there are few instances where it should be allowed:
.is-active
classes and each triggers different properties)In any case it shouldn't be definetly limited to just one use case as long as we are aware of output.
Ping @ghost.
First off, I am going to say I had an irrational anger at the article posted in December. This is partially a reply to that, while also explaining why the prohibition of @extend in the Sass Guidelines is foolish. That being said, I am not here to say that @extend should be used all the time, but merely that there are many reasons why it should be used within a project.
TL;DR: @extend has a place in our hearts and stylesheets, but certainly isn't the end-all
Chunky bacon! Chunky bacon!
— Why
There are two big places I find using @extend is most helpful. First off, for components, and components that might need repeating. I emphasize the might here, because although we set this up on all our work, we don't use it for each one. For every component we make, we create a silent extend class that can be used in other elements further along. I will admit, part of this comes from working within the Drupal ecosystem, where we find we have to @extend a large set of styles on another class, because it is impractical to change the classes/markup. It would also be impractical to change all of a bit of styling we have done into a mixin just for something that is found much later on.
Second, for base styles that are replicated often. The core example I always use for this are buttons. Why? Because we use buttons all the bloody time, and for most of our sites, they use the exact same base stylings. The need for a mixin that repeats those stylings is not needed, and can easily "dirty-up" the code base. Now, I can see you from here going "BUT GZIP!"...
To assume makes an an 'ass' out of 'u' and me'
— The only way I remember how to spell assume.
We should never make assumptions on how other pieces of our ecosystem are setup, or where our code will end up next. This is a belief I hold very firm, especially if we are talking about guidelines on how to write Sass. Those who are getting the advice may not have the server knowledge, or even the ability to ensure their hosting environment is setup in this way— and as arbitrators of knowledge, we can suggest that they look into that, but we cannot rely out outside technology to solve our problems for us. We must, always, make our code as efficient as possible and suggest others do the same. I think back to when I was considering hosting my site on Amazon S3, which does not support sending of gzipped assets if you are using it as a static host. S3 is not alone in this, and many static hosts have similar... issues.
All this being said, yes— everybody should be using gzipping of assets. But just because we say that, doesn't mean we can say we don't have to write good Sass because of it.
Harry could not be seen, but Snape could hear the pitter-patter of somebody's shoes down the hall.
— Not a quote from Harry Potter
I was on a project a while back where mixins were being used to create a grid system. A single mixin was called like 10 times to re-build the entire grid system with different classes so that we had a huge amount of excess code. It was a bad idea, and I hated it from day 1, but the client wanted it. When we tried to @extend something out of it @extend .grid-1-2-of-5
, there were vast unexpected consequences, as one would expect. This is not a good way of using @extend.
And then the actual grail came, %silent_extenders. These, these had some power. By using them, we remove any and all chances of having "unexpected consequences". We use each silent extender once, and only once, and when we extend one— we know exactly what will happen and where it will happen. IMHO, @exend should never be used on not a silent extend.
Wasn't that supposed to say bass? No trouble...
Yes, there is no way to use @extend within a media selector. There are huge amounts of reasons why, not least of which is it would produce unexpected consequences. This to me is a feature, not a bug and should be celebrated. 🎉
As a note, selectors that we are extending that do have @media directives in them WILL be extended as we would expect them. There is no issue with having a complex set of rules with @media involved being extended, we just cannot use @extend from within. http://sassmeister.com/gist/ddfe57c65a9d7042913a
Yes, @extends cannot accept arguments. That is what @Mixins are for. That doesn't mean we shouldn't use @extend.
I suggest changing the wording from "To sum up, the @extend directive is prohibited." to describing where @exend should be used. I think that should be only with silent extenders, and judiciously. But to ban it outright is to ignore valid use cases.
Ping @pierrechoffe.
How do you handle descendants in mixins?
For example, this mixin creates media objects (image on one side, text on the other): https://github.com/Keats/snowflake/blob/master/components/_media-object.scss and needs to set some values on the nested items in addition to itself.
How would you do that without nesting the 2 selectors in the normal case and the --reverse case?
EDIT: I should mention I use libsass and there's no at-root that I could use I guess
The often overlooked topic of alphabetically sorting declarations in rulesets: I guess it still boils down to preference, but there are numerous benefits of doing so. First off the legibility both in the editor and browser's web inspector. And secondly GZip can create better patterns, which allow for better compression. People might argue it's marginal, but it's such a simple thing to do for contributing to better performance.
See #28.
The current architecture compiles to onegigantic css file that contains the css for all pages. For a website bigger than a 3 page site this is a crazy structure. What you want is one css file for the main layout and another (small one) for every page that needs extra css. This way selectors can't collide and it doesn't download all css when you just need the homepage.
Some developers pointed out that double quotes are a pain to type on qwerty keyboards. That may be a reason valid enough to switch to single quotes.
Current guidelines, about lists:
do not add a trailing comma. It is ugly and it does not help.
And maps:
comma (,) at the end of each key/value except the last;
I agree with these guidelines when the list/map fits in a signle line, but I like adding a trailing comma for multiline lists and maps. It allows to keep clean diffs when moving, appending or deleting lines, and don't require the developer (or a script) to handle differently the last line when editing code (this is annoying when using sed
, multicursors, range substitution or macros for example).
I know this is not something everybody likes, but at least the two style guides I follow for JavaScript and PHP are recommending this too, and I see Rust is looking forward to recommend this practice too.
So basically, I'm for the following (let's assume the example strings are long enough to require a multiline structure):
$foo: (
"a": "b",
"c": "d",
);
$bar: (
"a",
"b",
);
However, I would be okay with not having commas at all in a multiline list.
Opinions?
Ping @varemenos and @kmargaritis.
I think the guidelines would benefit from supporting both SCSS and Sass syntax.
As a .sass
user (and proponent) I don't think we should disregard either as both are a core feature/offering of the language and therefore a feasible choice for each end user.
Maybe doing something like the Sass Docs and offering a toggle page wide would be wise.
Hey Hugo,
I really appreciate the effort you've put in to create this, I personally know how much effort it takes to write something as comprehensive as this and applaud your effort. That being said, this looks very official, it's copy is very official sounding, and you put enough stuff out into the world that people may think it's official. The disclaimer is too hidden, it should be much further towards the top; maybe have the tagline be something like "An opinionated styleguide for writing sane, maintainable and scalable Sass." This is especially true for your Architecture section which is not just highly opinionated, but is likely to not be a good fit depending on the compiler/CSS architecture/build system someone is using.
I'm just wondering why you recommend using named colors. I always avoid them as a general rule because of the potential that they may be output as their hex value in compressed mode when referenced in maps (i.e. why you always quote named colors in maps).
I know you know this, but here's a visual reference:
https://gist.github.com/una/83cd6d4feb16b3ebcb01
So it seems like it would be a best practice to avoid them altogether for consistency.
Trailing zeros, not so much. I would make leading zeros required.
// Very clear a decimal is in use
.element {
padding: 2em;
opacity: 0.5;
}
// Not so clear
.element {
padding: 2em;
opacity: .5;
}```
To lighten or darken a color, do not use lighten and darken Sass functions.
these functions manipulate the lightness
value of a color in the HSL space by adding or removing lightness. These are convenience aliases for adjust-color($lightness: -10%)
. Note that scale-color($lightness: 10%)
changes the lightness 10%
towards the end point. Mix does this but in a way that can change the hue and saturation. Maybe that's what people want... but it seems bad to just tell them "don't use these functions".
In the Sass guidelines, it states that:
When dealing with lengths, a 0 value should never ever have a unit.
First of all, I 1000% agree with this. However, developers may run into calculation issues by following this rule due to a Sass unitless zero-value calculation issue, and I'm not sure whether it will get resolved or not. To get around the issue, developers will have to specify a unit for zero-values when that value is involved in multiplication/division with another similar unit value:
// Main Stylesheet
$shelf-width: 100px !default;
$book-width: 10px !default;
$books-per-shelf: floor($shelf-width / $book-width);
.shelf > .book:nth-child(#{$books-per-shelf}n) {
content: "I'm the last book!";
}
// Developer Stylesheet
// (for the developer who can't afford shelves)
// can't do this!
$shelf-width: 0; // 0/px isn't a valid CSS value.
// forced to do this
$shelf-width: 0px; // Unfortunately goes against the guidelines
@import 'path/to/_main-stylesheet';
About Sass section:
Some good, some bad, so unusual
Should this be:
Some good, some bad, some unusual
?
This is likely something that comes down to preference, but I usually prefer import lists to look something like this:
@import "vendors/bootstrap",
"vendors/jquery-ui";
@import "utils/variables",
"utils/functions",
"utils/mixins",
"utils/placeholders";
@import "base/reset",
"base/typography";
@import "layout/navigation",
"layout/grid",
"layout/header",
"layout/footer",
"layout/sidebar",
"layout/forms";
@import "components/buttons",
"components/carousel",
"components/cover",
"components/dropdown";
@import "pages/home",
"pages/contact";
@import "themes/theme",
"themes/admin";
And (I've not tested this), but maybe even:
@import
"components/buttons",
"components/carousel",
"components/cover",
"components/dropdown";
Pros
Cons
In the unit section it states how to properly add a unit to a unitless number but doesn’t say why it works that way. This is a particular point of confusion for many newcomers to Sass who assume units can be treated like strings. These values are not strings and have meaning. Showing people that units behave like algebraic symbols is important to understanding and manipulating them in Sass.
How about also following a pattern of grouping/ordering of CSS properties? It makes the code more readable & easy to find where a particular property will be available or should be placed.
Ex: What many people do
.goodlooking-box {
font-size: 14px;
display: inline;
margin: 10px;
color: #EFEFEF;
border: 1px solid #EEE;
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
padding: 15px 10px;
margin-top: 15px;
}
Here is what I am suggesting
.goodlooking-box {
display: inline;
margin: 10px;
margin-top: 15px;
padding: 15px 10px;
/** width, height, position, top, left, right, bottom etc **/
font-size: 14px;
font-weight: bold;
/** font-family, font-style, line-height etc **/
color: #EFEFEF;
text-transform: uppercase;
border: 1px solid #EEE;
/** background, outline, border-radius, box-shadow etc **/
cursor: pointer;
/** z-index, content etc **/
}
Yes, there is no strict rule or pattern here. But I believe this is still better than the first example where there is a good chance of a property getting repeated again.
Let me know what yo guys think :)
Zero is zero, no unit involved.
In CSS, only lengths can legally omit the unit. So this is not true for the <angle>
, <time>
, <frequency>
, nor <resolution>
numeric types. See: http://www.w3.org/TR/css3-values/#lengths for the note that says that lengths can be unit-less when 0
. that note is not present for other types.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.