I wonder can I say that LESS/SASS CSS "pre-processors(I think they are called?)" is the opposite from optimizations like minification? I wonder if there will be any noticeable performance impact? or do you think easy of development is more important?
I ask this because what LESS CSS generates is something like
body #div1 #div2 p
body #div1 #div2 p a:link, body #div1 #div2 p a:visited
...
and I think it can really bloat up my CSS quite a bit. as you can see, such specificity is not required and it makes reading CSS hard (at least what I see in firebug).
In Sass you can control 'specificity bloat' by understanding how nesting works. You don't have to do any nesting at all if you don't want - it's something you can control.
Using the new #extend directive, you can actually reduce redundancy in your CSS by applying the priciples of OOCSS and can thus improve performance. Here's a good article to get you started with #extend. And a few more OOCSS resources:
http://www.stubbornella.org/content/category/general/geek/css/oocss-css-geek-general/
http://wiki.github.com/stubbornella/oocss/faq
http://oocss.org/
The great advantage of #extend in Sass is that it takes the manual effort involved in applying OOCSS and makes it wonderfully painless and easy.
Finally, as Andrea pointed out, Sass has a variety of options for minifying CSS (see the :compressed style), so overall you've actually got a pretty potent toolkit for not only improving your performance as a developer, but also improving the performance of your CSS. For an example of this in action, see how Chris Eppstein, author of Compass and core contributor of Sass, refactors the Digg stylesheet down from 125 lines of code to 85 lines of code (a 32% reduction).
You'd be surprised, but gzipped CSS files that have repeated blocks of code shouldn't be too much larger than ones with the shorter selectors.
This is thanks to how the compression algorithm handles duplicate strings in a file. Instead of including the same string twice, it replaces the second occurrence with a reference to the first one, and so that string only appears in the compressed file once. Take a look at how repetitive the selectors in your generated CSS file are - this should make them compress fairly well.
Naturally, the key to this is making sure your CSS files are gzipped - leaving them uncompressed will definitely increase the file size.
Depending on the options, SASS can give output in different styles. For production, you will want to set the output style to 'compact'.
There is a firebug addon for sass that should make things easier to read. You don't really need to read the output directly anyway.
Sass, less and xCSS will generate more output but I wouldn't call it bloat.
Hand written CSS, with it's many redundancies and duplications will degrade quickly as developers pile name spaces on top of others during the life cycle of the code. One of the symptoms of poorly maintained, designed or written software is bloat. And because CSS has some design deficiencies from the start, even the best CSS coders are effected by this limitation.
So you got to weigh up the initial footprint of your well formatted sass/less file against a hand written CSS file that has been edited a few times over.
Another benefit on sass is that your HTML becomes leaner. You don't need to append class names throughout your code to make up for the flat, global structure of CSS.
Related
This question already has an answer here:
Is there a SASS rule for outputting a descendant to the root?
(1 answer)
Closed 6 years ago.
For example, I want to make my code easier to read by doing this:
#article{
...
#article_inner{
...
}
}
However, I want it to compile into this:
#article{
...
}
#article_inner{
...
}
Is this possible using SASS?
Yes, #at-root will do what you want.
However, I question the premise of your question.
First, let's assume you really want to write #article { #article-inner {. For this, SASS will generate the code #article #article-inner {. You want it to generate #article-inner {. But why? Presumably you are concerned about the possibly lower efficiency of parsing, downloading, or applying the former as compared to the latter. Actually, though, any differences in efficiency would be miniscule to non-existent.
Second, I wonder why you think nesting the rules is "easier to read". Actually, to me it's harder to read. Presumably you think following the structure of the HTML is going to make it easier to read. Actually, following the structure of the HTML makes your CSS brittle. In computer science terms, this is called "coupling", generally considered a Bad Thing; in this case, you are coupling your HTML too tightly to your CSS. For instance, if for whatever reason #article-inner moved, or appeared somewhere else, then, even though the ID matched, your rule would stop working.
Experienced SCSS coders make very light use of its nesting capabilities. Instead, they write rules that are orthogonal to the HTML, which can be combined to create a number of styling effects, without being slavisly bound to the hierarchical structure of the HTML. Good SCSS coders I know limit themselves to nesting in the case of things like .class { color: red; &:hover { color: blue; } }, or in other cases to one level at most. In your case, if you have to use #at-root to do what you want, you have now actually made your code less readable in the name of readability.
SCSS is not going to live forever. Some day CSS will handle much of what it now does for us, including variables. Some shops are already moving away from SASS, with its ugly, verbose macros, mixins, hard-to-maintain features like #extend, and excessive nesting, back to raw CSS or forward to more modern preprocessors like suitCSS. We need SASS less and less for vendor-prefixing; other preprocessors support modularized, automated vendor prefixing tools. For all these reasons, therefore, it's not unreasonable when writing SCSS today to consider the potential that your code might need to be ported away from SCSS sometime in the future. That would indicate you should avoid using lots of SCSS-specific features when they're not really necessary, such as the nesting in your case.
If you want readability, add comments, which you should be doing anyway.
#article { ... }
/* The `#article_inner` element is inside `#article`.
#article_inner { ... }
More generally, I would question an ID-based approach to writing CSS. Presumably you intend to specify a bunch of properties on #article-inner, like font size, background, padding, or whatever. I've seen CSS where there are a dozen properties or more. What is the point? You might as well just write the properties in a style attribute directly on the element; at least then, you'd only have one file (the HTML) to manage. Instead, knowledgeable CSS designers create small, utility-like classes that can be applied to many elements. For instance, they might define a PaddedGrayBox class, that handles the padding and background. Then, they write in their HTML
<div id='article-inner' class='PaddedGrayBox FloatRight...'>
Now this is more readable. Someone looking at the HTML can immediately see what kinds of styling are being applied. If you take this approach consistently, you may find that you are able to do away with using IDs altogether, although I know that would be quite a departure for jQuery-oriented programmers who believe that doing $('id') (or getElementById) on every other line is the core of JavaScript programming.
By efficient I mean less code (less css rules).
Because I'm converting a CSS file to less, and I'm surprised to find out that the compiled CSS file is quite small (I haven't finished yet :P)
It really depends how you structure your code in LESS. The compiled output can become quite unwieldy if you use a lot of mixins (for example for gradients) or the # operator to nest selectors too liberally.
All in all one could argue that they 'can' produce more efficient code if used properly. But then, so can you I you use plain CSS.
LESS (when compiled) and Sass both minify your CSS. In addition to stripping out whitespace, you'll sometimes see things like border: 0 10px 0 10px get turned into border: 0 10px or colors like #666666 turned into #666. It isn't any more efficient, but it does make a smaller download for the user (which is valuable for mobile devices).
That said, Sass has a unique directive called #extend, which allows you to group your styles logically in the pre-compiled state, but will group them together to avoid duplication in the compiled state.
.classA { color: blue }
// 50 lines of code defining other elements...
.classB { #extend .classA }
Will output something that looks like this:
.classA, .classB { color: blue }
It doesn't seem like that big of a deal with 2 classes only having one thing in common, but its a bigger deal the more elements you are using and the more things they have in common.
Otherwise no. The efficiency is entirely based on the author.
As noted above, it largely depends on whether your CSS was inefficient to start with. However, there is almost no situation in practise that requires more "efficient" CSS (I'm talking about performance rather than repetition) - yes it's bad to duplicate rules etc, but first and foremost should be code readability and maintainability.
In general, I find that the productivity gains from using a pre-processor far outweigh any issues with rule repetition, and if it's actual filesize you want to cut down on then WinLESS (and other compilers) can minify at source.
In general tools like LESS or SASS will not be able to produce as streamlined CSS as writing it manually (with proper knowledge), because the tools have no knowledge of the DOM on which they're operating. Any optimizer will only be as good as how thoroughly it can assess the runtime environment, and the missing DOM is a pretty big variable. If you structure your document properly and write the CSS to take advantage of that, then the output will be far smaller than generated code.
The advantage to these tools like any form of code generation or even higher level languages for that matter is that they enhance productivity. More consistent and possibly maintainable output can be produced more easily, but in order to do so these tools will be uncompromisingly explicit and "safe", and therefore produce code that a human would able to easily recognize as unnecessary when associated with the document. In general development and maintenance costs are higher than CPU cycles, so the productivity gains win out out. There may be times like any other when there may be performance issues that need to be addressed, but "premature optimization is the root of all evil" - Knuth
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to Manage CSS Explosion
I intended to build my web site with consistent styles and a coherent CSS scheme. But styles have crept out of control as I fine-tune individual pages (especially the main search form).
I've already gone through the process one time of breaking down the styles and rebuilding almost from scratch, and now it looks like time to do that again. How can I be efficient about this? I'm looking for a methodology, not a software utility (though I'm open to suggestions there...unless they cost money...).
Added note: I'm using a CSS framework and it's difficult to keep padding and margin coordinated.
Added note 2: The initial responses to this post are about best practices for CSS. Let's assume I already tried to follow best practices (in fact, I did). Now it's the clean-up procedure I'm looking for.
Added note 3: As of 14 June, combining this response (which I just found) with my post below is possibly a comprehensive answer.
Closure notes:
I learned my question is too general, and for that reason I wish I hadn't posted it. (Maybe that's why it got a down-vote ... I'll never know without a comment to explain the reason.) On the other hand I got just what I needed, so I'm happy I did post it.
I'm surprised I didn't get an up-vote for my answer -- even with the priceless input by others, I think it stands up pretty well.
My acceptance is going to be based largely on the usability of the answer, from my point of view -- a point of view that is sadly unable to digest some of the more exciting and comprehensive responses.
Closed as an Exact Duplicate
I just tried posting this again (subject, body, tags) to see if SO would suggest the post "How to Manage CSS Explosion". Interestingly, it did not. I added the tag refactoring to that post.
Split your css into separate files.
Put in one file the CSS reset (if you use one)
Then create a global.css file where you will put global styles that
apply to many-all pages
Then create individual files for your individual pages
Then start styling your pages. Every time you find a style rule that is reusable on many pages make it a CSS class and put it in the global.css file. Avoid using css ID's. You will find that you more often reuse things or will reuse in the future. In this case you use of course CSS classes.
Eventually you will find out that in your global.css you will find mostly CSS classes rules and html tag rules.
In your individual page CSS files you will find specific styles for each page.
That should give you a good first level of organization in your CSS. You can try to keep this separation through the whole development process, and for releases merge the CSS files into one and minify it.
my 2p worth about css cleanup, from a a previous similar question:
Tips for cleaning and maintaining a big css file
hope that this may help you together with others' answers!
start branching the project (here I suppose that you are using a version control tool) - that will allow you to play independently with the code and tag any milestone you will reach.
format your CSS with a beautifier - it will increase readability and will help searching for specific declarations without missing any instances.
try to identify unused / redundant css and get rid of it.
you could try to make your selectors shorter (e.g. .main .foo .bar might be fine as .bar) - it will improve readability and increase the performance, but take this with a pinch of salt and be ready to go back if things start to break at every step you take.
try to eliminate, if possible, any !important - make the selector more specific if needed. A css reset could help with that if most of the !important statements were made to fix browser-specific issues, otherwise introducing a css reset now could potentially add more problems than solve them - this, if there is no css reset in your app at all.
break and regroup the css into different modules (and files if that helps) - Object Oriented CSS is a possible technique to keep things more maintainable, it works best if you start with it but it may also help you in refactoring. https://github.com/stubbornella/oocss/wiki is a valid one but there are alternatives that you can consider, like SMACSS.
After that , you may consider using a css preprocessor such as Less or Sass, allowing you to define variables and mixins (similar to functions), modularity and much more - this may end up being a very expensive task though, so evaluate carefully if this will bring you more benefits than pain.
test as much and as often as you can, consider unit tests to make sure that any changes you make don't break anything somewhere else.
Sometimes re-writing everything may end to be less time consuming than refactoring, so don't be afraid to leave things as they are if your assessment will show that refactoring will not bring enough benefits.
EDIT
Things change and evolve for good; with regards to OOCSS/SMACSS approach, I have been happily following for a while, Yandex's BEM methodology for CSS, I would like to add it as an additional recommendation to the above
The first thing I'll do is separate the CSS based on the purpose. Maybe first the general page layout (DIVs, boxes, ...), then the styling (fonts, H1/H2/.../Hn titles), then some more specialized CSS (CSS for tables, for forms, for specific components of the site).
Such a separation helps to organize the changes; if you have to change or add a font, you know you'll find it in the styling section.
If you have to change the page layout, there goes the same, and so on.
Things tend to get messy when you have "individual pages"; is their layout so different?
You probably have to abstract the common features of the pages (for example, a main content container box) as long as you can.
Then think about specializing more the layout (1-column, 2-column) and so on.
If you have a programmer background, just think about classes and inheritance, the concept - yes I know it's a totally different domain... - but the concept can be useful in designing your css.
Based on this current round of work, here is what I've got so far:
the Planning
Have a system for handling To-Do notations in your HTML and CSS. Many IDEs support this directly, or a global search function will do just fine. Besides tagging issues, you want to note priority and perhaps even functional area (but keep it simple, not a burden).
Don't start revising your code. Use your To-Do system to plan first.
Make a concise list of your overall goals.
Consider overall sylistic changes such as color or font scheme.
Review best practices for CSS. Identify areas where your approach is ineffective, or where a good approach can be applied more consistently. Examples:
Consolidate classes
Eliminate haphazard use of in-line styles
Remove styles that are unused or redundant or conflicting
Improve general consistency; apply a set of conventions
Improve units of measure
Use class and id names that reflect content rather than format
Decide how much of the browser market you want to support and how much to embrace or rely on the newest standards.
Decide if there are any new approaches you want to adopt. Examples:
Use of a reset style sheet to standardize browser presentation
Use of a CSS framework
Use of a specialized library, for example to help with forms
Dynamic CSS (I recently followed advice to use PHP to handle my CSS, so I could dynamically control my color scheme. But I returned to straight CSS, because I like the presentation of CSS code in my IDE and the hybrid method messed that up.)
Review your list of goals and decide which should be pursued now. Any large-scale change should be treated as separate, if possible. If your column layout is a mess, it's not the time to learn how CSS can elegantly replace your javascript. The same goes for best practices, stylistic changes, etc.
If you have your CSS files configured for speed (for example, compacted footprint or all CSS in a single file), change that. Break the code into a human-managable format. Later when you're finished, try benchmarking to see if the more legible version is also efficient enough for production use.
Submit your CSS to a validator. Note any violations you want to fix.
Find instances of in-line styles in your HTML (search for the style attribute). Note any that should be moved to a style sheet.
the Work
Follow your To Do manager. Make common-sense back-ups. As you go, test your work on several browsers.
If you are into regular expressions, be warned: regex is often not effective or safe for rewriting CSS. (Not as hazardous as for HTML, but still). Regex may be useful sending CSS changes into the HTML, but again be careful.
If you have a lot of tweaks to margins and padding, try globally resetting all of them to 0px (okay, use regex here). Then systematically build them back up. You can resolve a lot of confusions this way. Of course, don't include any library or framework style sheets in this process.
Again, submit your CSS to a validator.
I see people has already suggested using approaches like OOCSS etc., so I'm going to offer a different/additional line of thought. I believe that the problem lie deeper than within your CSS and the way you write it. I believe the reason your CSS gets out of hand is this quote from your question:
... as I fine-tune individual pages ...
That makes me think that the problem much lie within your design, rather than you CSS, so let me elaborate a little bit on that. In my opinion a great design is a design that doesn't have to be customized for each individual page - and there are several reasons for that. The main reason is, as you've mentioned yourself, your CSS get out of control. Small tweaks and fixes on individual elements, depending on where they are placed, often leads to a mess that is a pain to maintain and work with. There is also a usability-reason in play here. I believe a UI becomes easier to use if the user is familiar with the UI and recognize herself from page to page, without to much variation. Of course you could have some element that isn't present on each page, or that vary somewhat between pages, but I always strive to keep them at a minimum.
My suggestion is therefor that if you intend to rewrite your CSS, which is time-consuming and hard work anyway, then why not go over and re-evaluate your design at the same time. You will probably find that there are elements that you can modify so that they look the same. Make it a goal to get rid of as many UI-elements as possible, without compromising the design. When you've unified the design as much as possible, then it is time to refactor your CSS, and maybe even your markup?
At this point, it might be better to get rid of all your CSS and start fresh. If you continue on your old code, it is easy to get lazy and get stuck with some of your old less efficient code.
For the coding, I believe the other answers contain lots of good recommendations and best practices. I would personally vote for OOCSS, a new discovery for myself as well, but it has improved the way I structure my CSS a lot. So have a look at that! That will also help you think in terms of reusing elements and the CSS for them, which goes a long way for simplyfing your CSS.
This answer is in regard to the note;
"I'm using a CSS framework and it's difficult to keep padding and margin coordinated." only.
Using a css pre-processor will solve this problem.
Because css has no way to assign inheritance and therefore we have to repeat 'margin:10px' over and over.
with a pre-processor you just do
#margin {10px}
#padding {10px}
then
.mySelector{
margin: #margin;
padding: #padding;
}
For the broader question rethink/simplify your design as your css is directly proportional to the complexity of the design and there is not much you can do about that.
See also, http://www.stubbornella.org/content/2011/04/28/our-best-practices-are-killing-us/
This is more advice about making your css maintainable than the Q of how to manage the process.
I create a bunch of separate css files each narrowly tailored to a specific attribute (colors, fonts, margins, corners) or feature (nav, form). Then I use a compile phase to combine and minify these files into one or more files to be sent to the client. I do this during my built/test process, but it could be done dynamically by a CGI script.
Before adopting a pre-compiler, consider the often-overlooked multiple-selector syntax:
element,
otherlement
{
margin:10px;
}
In this example, whenever I want an element to have a 10px margin, I add it to the list. I separate different sets of attributes this way - I may list the same element 5 times in my css - associating it with 5 different sets of attributes.
Also don't overlook adding various classes to the body tag to create OO-like inheritance - say you have 3 main sections of your site - assign the body tag a class based on those sections. Likewise, if you have 1000 product pages, you can give the body tag a class like "product485" and then create styles that apply just to that page. For example:
h1 {
margin: 10px;
}
.product485 h1,
.product484 h1
{
margin: 5px;
}
.contact h1 {
margin: 15px;
}
This might all be in a file called "margins.css" which specifies only margins.
Though it's debatable, I've heard the majority of CSS developers prefer multi-line because of the ease of which a property can be found within the CSS file. But doesn't this make the CSS file bigger and less readable on the whole? I think single-line lets you scan the CSS file much faster. Any thoughts?
It's all a matter of preference based on what your team decides on. However, here's my take on why I use single-line formatting:
When I need to maintain CSS, I'm most often looking to modify an existing selector. If the start of every line is a new selector, and not just more style declarations, it makes it easier to scan the document for the selector I want to find. It also means less scrolling to find what I need.
Once I've found the selector I need to edit, good syntax highlighting makes it easy to read the rules for a specific selector, so I don't lose any readability by having all of my style declarations on a single line.
That being said, I wouldn't say it helps with file size any. I rely on YUI Compressor to compress my CSS for me automatically, rather than trying to manually maintain an efficiently declared style document.
IMO multi-line CSS is better because its more readable. But i would suggest you to follow your teams's standard and dont waste your time debating :)
And if you are worried about CSS file size, then you should minify / compress it.
Also, if you have time, you spend some on validating your CSS using Official W3C CSS Test Suites.
This is a matter of personal style - make sure whatever you choose that you are consistent. I personally tend to put each property on its own line for readability.
Use whatever style you find easy, at the time of development.
You can use a CSS minifier to reduce the size of the file at the time of deployment. You can find a lot of CSS minifiers which will help reducing the file size.
YUI compressor is a good one.
Just like JavaScript code, you would want to format your CSS the way that would conform to your team's standard, and let the compressor minifies it for deployment.
The drumbeat of writing terse CSS code has been beaten into my head for years. For example:
Do this:
.foo,.bar{
color:#f00;
}
Not this:
.foo{
color:#f00;
}
.bar{
color:#f00;
}
With GZIP compression isn't it irrelevant how I write the above CSS? Since GZIP will create a dynamic library with color:#f00 as a single instance and use pointers to its multiple uses. I want to know because it is more convenient to repeat style definitions versus searching for an identical declaration.
You could use a css minifier before publishing and stop worrying about readability and file size.
GZIP will definitely have a bigger before/after size impact with 'sloppy' CSS files, but having the smallest file possible before compression, is alwaysmost of the time a good thingtm, as it will be marginally smaller.
Remember: Source code is for humans to read, and only incidentally for machines to run.
It depends on what you try to achieve:
If .foo and .bar need to have the same colour, you´re better of using the first method because it is easier to maintain.
If your first statement is a result of you manually optimizing your file-size, and it´s just a coincidence that .foo and .bar have the same properties, I would definitely split it and use the second solution.
In the end gzip and / or a css compressor will handle the file size so I wouldn´t worry about that.
Worry about maintainability and readability instead.
If that makes sense, go for it. Otherwise, I'd write the CSS in a logical fashion so it can be maintained properly, and then rely on gzip + a CSS compressor (like YUI Compressor) to handle the dirty work for you.
I think you would still want to continue using the first method because it's more readable. Having a separate section for every thing will make you css bloated and difficult for people to get through it.