I'm learning angular and I'm testing the directive ngClass.
With ngClass I can do something like that:
<li ng-repeat="language in languages" ng-class="{line:$even}">{{language}}</li>
But I can also do this with the css selectors:
li:nth-child(even) {
// some css code here
}
What is better?
First of all two cases are not equivalent. But if what you are looking is a way to style even/odd elements, then without any doubt: you should use CSS to do CSS job, not javascript. Using javascript to add class names is possible but if it's not important to have actual class names on elements then sticking to :nth-child approach is preferred in this case.
Two main benefits of pure CSS way:
Avoiding additional watchers Angular would have to set for data binding.
Performance and cleaner HTML code.
I see ng-class as a visual port of some property of the model. It is not intended just for styling, but can offer it.
IMO it is always best to do as much as you can using standards, that way you're less dependent on others.
There are plenty other reasons why using CSS is better, like: performance, less error prone, less dependent etc.
Related
What is the best way of defining general non-block-specific styles throughout the site?
For example:
html
<div class="intro">
<p class="intro__text">foo</p>
</div>
<div class="profile">
<p class="profile__text">bar</p>
</div>
sass/css
.intro__text {
}
.profile__text {
}
.text {
margin-bottom: 0.5em;
}
If I wanted the text to be styled the same, would I (given I am using a pre-processor) #extend .text into the .intro__text and .profile__text classes, or just have all paragraphs throughout the site have a class of text?
Both those solutions seem slightly incorrect to me.
If I have a very common style, it feels like I'm going to be duplicating a lot of styles throughout my rendered css (bumping up the filesize) but having a class of text repeated all throughout my markup seems unnecessarily verbose and untidy.
Is there a best practice for this situation?
I can't say that there is the best way to do it. It depends on the structure of your project and what style your prefer. Both approaches are used in mostly code.
If you like to manage styles through css files - write #extend. However in case you want an element without common style you have to create a modifier for the el. For example - .profile__text--reset.
If you want declare common styles, your class list with common classes may become too long. But it is more clear and specific. And you have a possibility to manage it via javascript.
One improvement for this code is that it is better to use helpers with modifiers. For example, instead of simple .text use .text--sm or .text--m-sm. Or if you want only margin - .m-sm. But it is up to you.
You have several options:
Preprocessor (Sass/LESS/etc) mixins + clean-css/postcss cleaner — this way is simple and powerful, but not flexible, since it's not useful for dynamic landing pages, SPA, etc.;
Element of outer block mix (BEM/runtime mixin): class="intro__text grid__text" — in that way you just splitting manually visual and positioning styles and use their classes together;
Other block mix: class="intro__text paragraph paragraph--valuable" — almost like the previous variant but without linking to the abstract grid block, the best and the most flexible way (IMHO).
NB: Also you can extend BEM mixes with modifiers even in runtime, it's VERY powerful tool.
NB2: If you don't need dynamic web pages, you can freely use sass mixins. Personally I don't use sass/less mixins, only global variables for colors, grid, gaps, etc used in my own classes.
Does a css class selector always require a definition? For example, if you found in the html: div class="banner", should you always find a .banner in a css file? I ask this question as I've been looking at some website themes and I sometimes find these selectors without any other reference. I'm just not sure if it's an oversight or something common.
There are many reasons to have class names on your HTML elements without having CSS rules associated with them. A couple of examples:
More readable markup. If a component is properly labeled, it's easier to find, debug, or work collaboratively on.
Javascript. Sometimes an element requires some Javascript behaviors, but doesn't inherently need CSS styling itself.
So to answer your question: No, you do not need to define each class or selector in your CSS.
Lets say that youre using Twitter Boostrap and you have their generic boostrap.css and other boostrap associated css files, and you want your own classes to have identical attributes to some of the given boostrap classes. To my understanding, you would not want to directly modify the css bootstrap files, but you would want to extend them by creating a custom.css file.
So without touching the boostrap files. How would I replicate a boostrap class for my own class? Would the only way be to copy and paste from the boostrap.css file. Or is there a way to do
.myownclass {
-- some command to replicate class 'alert alert-error' without repeating the CSS that has already been written
}
You could use a css preprocessor. Other ways already cited by other users are fine but using a css preprocessor is the best way.
Bootstrap is built using LESS, so you can use LESS. Take a look at here: http://bootstrap.lesscss.ru/less.html.
Also SASS can be used. According to me SASS is better. You find a tutorial here: http://www.1stwebdesigner.com/css/build-website-using-twitter-bootstrap-sass-1/
What are CSS preprocessors?
A browser can only understand CSS, as the styling technique for any DOM element being rendered. CSS, as a language has its own feature set, which at times might not be enough to create a clean and reusable chunk of rules. Eg. Not being able to reuse a collection of rules in multiple selectors, unavailability of variables which may lead to ambiguous pieces of data across the stylesheet. To overcome most of these limitations, the concept of a preprocessor was born – offering an advanced way of writing CSS, which extends the basic functionalities. This advanced code is later compiled as normal CSS code using respective compilers (which depends on what preprocessor you are using), which the browser will understand.
Should you use preprocessors?
The decision of adopting preprocessors for your next project, in my opinion, should be made after much analysis and solely depending on your expertise level and most importantly the project requirement and workflow of the team as a whole. Here are some tips that might help you come to a decision:
Not for beginners: If you are a beginner and starting to explore the fantastic world of CSS, I would suggest you get your hands dirty with normal CSS before moving into a framework or preprocessor of any sorts. It’s really important to understand and be able to use the core concepts of any language that you work with, and that’s true for CSS as much as any other programming language.
Are you a team of front end developers? As a team of front end developers, adopting preprocessors will be a great move. But only if somebody on the team really knows how to handle huge CSS files and structure them accordingly. By making use of the powerful features offered by the language, it is important to first structure the whole CSS into reusable chunks and define a strategy for CSS organization. Eg. Are you going with multiple CSS files for typography, forms, layout etc. Are you going for theme-able UI, where you might need to use variables extensively, etc.
Are you willing to cross the barrier? Adopting preprocessors means you are going to be implementing more programming concepts into your CSS coding approach. There will be a lot of concepts that are native to any basic programming language, which you might want to learn and implement, by using a preprocessor. This means, you will definitely need to brush-up your programming skills and might forever change the way you see a CSS code. If you are willing to cross this barrier, and feel ready to embrace the change confidently, this is for you.
In CSS this is not possible. The only way to do it, is to chain the classes in your html tags.
<div class="alert alert-error myownclass"></div>
If you are using less you can do it like this:
.myownclass {
.alert
.alert-error;
}
This will copy the settings from one class to another. The result will be the same as if you copy the contents of the class directly.
If you are using Sass you can do it without copying the class contents. Just reference the classes as shown below. This will not copy the contents, instead it will reference your custom class at the right position in your css code.
.myownclass {
#extend .alert;
#extend .alert-error;
}
Ref: Sass #extend
You would have to use LESS to avoid copy/paste:
.myClass {
.bootstrapClass;
}
Or you could use any of the other CSS preprocessors TBS has been ported to (Sass has one, not sure on the others).
You could give the element two classes - the original Bootstrap class, and then one of your own making. Then you would target it like this:
HTML
<h1 class="original_class myownclass">Hello</h1>
CSS
.original_class.myownclass {
// css code
}
Here's a little jsfiddle illustrating the concept: http://jsfiddle.net/ApEpr/
This does not require the use of a CSS preprocessor - it's just regular old CSS.
I am fairly new to css3 using selectors (or simple css selectors in general) and am curious about the performance comparison of these css selectors vs jquery or javascript selectors?
Say you have something like this:
css version
#someID > div:nth-child(2n) { some css .... }
jquery version (edit)
$("#someID").children(":nth-child(even)").css({ some css ....});
Is it often faster to use the css selectors whenever you can, or use jquery selectors to adjust the css involved with an element or set of elements? Mainly when the set gets rather large. I would assume there wouldn't be much performance difference with only a handful of items?
Thanks!
jQuery's selector engine shares most of the same syntax as CSS, effectively extending the selector standard. This means you can pass most valid CSS selectors (with some exceptions) to jQuery and it'll handle them just fine.
jQuery optimizes valid CSS selectors for modern browsers that support the selectors API by passing them directly to document.querySelectorAll(). This means your jQuery selector will have almost equal performance with the equivalent CSS selector, with the only overhead being the $().css() and the selectors API calls.
For browsers that don't support the selectors API, well, it's pretty obvious that jQuery will be really slow as it has to do all the heavy lifting on its own. More importantly, it will simply fail on the exceptions that I link to above as well as any other CSS selectors a browser doesn't support.
However, with all that said, jQuery will invariably be slower, as the browser has to run through a script and evaluate it before getting a chance to apply and compute your styles.
And after all this, honestly, it's not much even if you had hundreds of items — chances are the browser is going to take longer to fetch the markup than to render the styles. If you need to do styling, and CSS supports it, why not use CSS? That's why the language was created in the first place.
Pure CSS will always be faster since it's done within the browser and optimized!
The downside is that some selectors might not be supported by the browser you're on. See http://caniuse.com/#feat=css-sel3
For me if I use jquery means that I want to put some effect on it, say like
$("#someID:nth-child(even)").css({ some css ....}).fadeIn('slow');
Apart from that you better use CSS itself, but we are barely to see the difference of it anyway, at least for a small scope system.
I've found this web that compare selector capability from different javascript framework and jquery does it quite well.
javascript framework selector test
I understand that in jQuery, it's advantageous to be more specific when using selectors so that jQuery doesn't have to traverse the entire DOM to find what you're looking for. For example, $('span.description') is better than just $('.description') if I know that the description class is only ever applied to <span> elements.
Is this the case with CSS, too? Is there any specific advantage for me to use span.description { } instead of .description { }? I'm thinking in terms of speed, optimization, etc. Am I saving the browser any work by telling it exactly where to look?
This is true in CSS -
A good rule is to descend from the nearest ID.
IDs are indexed so locating them is extremely fast. There is no reason to use more than one in your selector.
Google Code- Optimize browser rendering
This answered a lot of questions I had on the subject including this one-
I hope you find it useful.
Read up on css specificity - which is the most important reason to be more or less specific with your css.
http://www.w3.org/TR/CSS2/cascade.html#specificity
As browser performance is pretty much a non-issue (except for in jquery, as you've mentioned), my guideline is to be specific when you are controlling precedence, or when you want to make something a bit more readable in your css. Over specifying can make it tricky to re-use css selectors and make things overly complicated.
Edit
This looks like a bit of a duplicate:
CSS Performance Question
it always depends on your amount of html code and the structure. It is definitely a good idea to use especially ids and appropriate selectors. (ie #nav li instead of li.nav). Since browser first load the html and then apply the css you are helping a lot.
This said, when it comes to pure css (no jquery) the difference in speed is nowadays not easy to distinguish, because the rendering engines are highly optimized - especially when it comes to applying css. So normally it shouldn't matter.
As far as I know, how specific your selectors are make very little difference on the performance.
The two areas where more specific selectors are most useful, is to reduce the risk that it's not applied where you don't want it, and to make one selector take precedence over another.
A more specific rule has precedence over a less specific rule, so:
span.myclass {}
has precedence over:
.myclass {}
(no matter what the order is in which the rules were declared)