I know about mixins and parametric mixins. What we are looking for is a way to make any general purpose selectors in CSS / LESS into a mixin.
Eg in Twitter BootStrap, we have here
.navbar .nav > li {
float: left;
}
If I have to use it in a class say .mynavbar I want to be able to do this
INPUT->
.mynavbar {
.navbar .nav >li;
}
OUTPUT->
.mynavbar {
float:left;
}
Now I know this can't be done with the current version of LESS as the compiler flags a parser error. I wanted someone to help me out on changing the source code of less.js a little so that this is workable.
I've managed to reach the source code for the mixin parser. I've tried changing the RegExp there, but it interferes with other parts of the parser. I know we have to make only a few changes because, instead of just accepting .mixin and #mixin we have to accept any mixin like tags / attribute selectors like input[type=text].
It is currently needed for the development of a UI framework that uses Bootstrap. Unfortunately many places in bootstrap are littered with direct tag selectors instead of ids and classes.
This is possible since version 1.4.0 (2013-06-05) of LESS that include the extend feature. Based on the original example
.navbar .nav > li {
float: left;
}
.mynavbar:extend(.navbar .nav > li) {}
compiles to
.navbar .nav > li,
.mynavbar {
float: left;
}
Documentation here and discussion & example use for the original question here
EDIT: Added Code Sample
First off, I would strongly discourage doing such things. Instead, try to use the power of CSS and build your HTML such that the bootstrap rules apply, for example. Anyway, since you asked for it, here is the solution.
The problem is not the complexity of the selector, or the child rule, but the tag name selector part (i. e. the li). So, what we have to fix is the mixin parser only matching classes and ids. I guess we would not want to tamper with the first class or id test, since that is probably needed to distinguish mixins from normal CSS rules (although the tests run fine with that check commented out). (Actually, there is a parser preference in action, and the only thing tried after mixins are comments and directives, so we can safely remove that check as well). However, we can easily allow tag names in later parts of the mixin selector by adding a question mark after [#.] in the matching regular expression. So
while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
– i. e. line 825 – becomes
while (e = $(/^[#.]?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
The test cases still run through fine, afterwards, but subtle breakage my occur, so be cautious.
Edit: There is a GitHub Issue for the same problem. Apparently the less folks rather want the mixin feature to be more narrow and function-like, instead of allowing a more flexible … well … mixing in of rules. With regard to the CSS output, that's probably reasonable.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I frequently need to address generic elements inside some specific sections of a page. I find this approach most easy to understand in terms of what any rule is affecting:
.shop > .products > .product > .description > .warning {
color: red;
}
But I often see this:
.shopProductsProductDesc > .warning {
color: red;
}
Does it really matter which approach is taken?
It really depends on the problem you are trying to solve.
The selector .shop > .products > .product > .description > .warning to my understanding would be used for two cases:
You have multiple warning elements but you only want to select the elements inside your description and there are other selectors used for warning that you don't want to overwrite.
You need to overwrite a previous selector that is less specific. Ex. .shop > .products > .product > .description .warning
The other selector .shopProductsProductDesc > .warning is less specific than the first one but assuming the container of .warning has those two classes .description.shopProductsProductDesc then the outcome would be the same as the first one.
CSS is all about specificity, if your selector is more specific than the last one used the properties would change. This is why you have to be careful if you are using specific selectors because your last option to alter the properties would be to use !important.
I hope this helps to clear things out.
After trying a few different styles, I think that personal preference (or a set standard if you have collaborators) is really the way to go. I prefer the second version, but the first one is also quite legible.
If you consider efficiency of what the browser has to do under the hood to render CSS styles, BEM-style for example, is usually the ultimate winner as it is the most lightweight for the browser. I use BEM for some layout/common elements.
In real life unless you are doing something seriously wrong, modern browsers and devices make this difference of CSS parsing and rendering somewhat negligible. But that is if you code everything well.
I've worked with spaghetti CSS codebases that could take minutes to render all SCSS (it was a huge codebase, but a few files were big bottlenecks).
It matters because of specificity. The first style rule will always override the second, regardless of where they both appear in the stylesheet, because it is more specific (basically it has more class selectors in it).
That said, the first rule is a nightmare from a maintainability perspective, for a number of reasons:
It makes code incredibly hard to read and understand
It's harder to override (as we have seen).
If you change the structure of the HTML, it will break
You can only reuse it if you mirror the structure of the HTML exactly.
It's also bad from a performance perspective. When browsers are matching an element to a style rule they read each selector right-to-left and keep going till they either find a match or can exclude the rule. Therefore, the more simple the selector is, the faster a match can be determined. If a selector consists of just a single class name, the browser can match the element with the style rule more quickly than if it has to search upwards in the DOM tree.
The second rule is better, but optimal would be something like the following:
.shopProductsProductDesc--warning {
color: red;
}
This solves all the problems above, and it's long enough that there's unlikely to be name clashes elsewhere, (though obviously not impossible).
In general, nesting selectors in CSS is bad practise, in my opinion, and the best CSS methodologies are those that have ways of avoiding this, e.g. BEM, CSS-in-JS.
According to my own experience, the second option is often best, not for direct technical reasons (in fine, it will perform the same), but rather for UX consistency and code maintenance.
The first option produce an "heavy" selector, which will be harder to override. It can be wanted, but it is often the sign of an overall messy CSS, because if everything is overconstraint, it is less easily reusable/extensible.
From my understanding of CSS and frontend reusable components, you would always only need two levels.
The style of your warning component (no size, no margin, size depends on where you will display it, and margin is position, only internal design here):
.warning {
//Your design here
font-size: 1.5rem;
font-weight: bold;
color: orange;
}
And the positionining and variants inside containers:
.container > .warning {
//This is an example.
position: absolute;
right: 0;
border: solid 1px red;
}
Having long CSS selectors will make things more complex, hard to follow for your teammates, and hard to override because you will probably need a longer CSS selector, and it never ends. Plus, you will get an heavier bundle at the end.
If you want an efficient UX, the UI shouldn't be that different everywhere, so you should not need to have that many variants of the same component. Otherwise, maybe you need multiple different components, but you certainly want a simple and efficient UX, and that often goes with not so much visual concepts, so you must avoid tons of variants.
I am building websites for a while, and I have a question about CSS I can't really rid over. So there is that frequent situation when multiple classes affect a DOM element, and both classes declare the same properties. For example:
.first {
color:white;
}
.second {
color:black;
}
I know that if I have an element with class="first second" in that the text will be black. If I rather want it to be white, I have several options:
Using !important: I know this one is handy and I use it, but sometimes, if I use it too often, my CSS may become messy. I mean, multiple !important's can result the same basic situation.
Reordering the classes inline: if I am correct, which class comes first, it will be the priority one. This is nice, but i often work with environments where I can't affect that. Secondly, this is not a global but a local solution.
Reorder the CSS itself: well, this sounds interesting, but if I work with many stylesheets (and I do), it is hard to track, especially when it is WIP.
Actually what I am looking for is some workaround like z-index but for priorizing which class is stronger. Because I can't really find anything useful in this topic, I am just curious maybe it is a user error, and you guys know something I don't. How do you manage this? What do you suggest?
class="first second" is the same as class="second first". The priority is based on the position of the declarations in your css and not in their position on the html element.
So, if you want priority of a class against another, put the top priority class LAST on the css file.
.first {
color:white;
}
.second {
color:black;
}
in this example, class second has always priority over class first. This happens because browser scans through the css top-to-bottom and always applying the rules of matched classes that finds. So, the last matched class has priority over the previous matched classes.
see this fiddle: http://jsfiddle.net/5c29dzrr/
At the same specificity level, the CSS selector that is furthest down the stylesheet will be applied. So in your example, if you wanted in that situation to have the element with the white colour you would have to order your properties like so:
.second {
color: black;
}
.first {
color: white;
}
The order of the classes in the HTML tag is not important; it is the order in which they appear in your CSS.
The better way to handle this is to go with some better naming convention such as BEM or SMACSS so that you don't have the issue of conflicting class names.
Edit: It might be worth reading up on specificity and the cascade for a better understanding of this. I found this calculator to be pretty handy in determining which rules will take precendence, although these days you can just use the developer tools to find out that information.
When I want to define css selector with :hover and :active I have to do:
#mainPage #content div.group:hover, #mainPage #content div.group:active {}
As one can see it contians repeated #mainPage #content div.group and can get messy. Is there a way to group it somehow like:
#mainPage #content div.group:hover:active {}
In pure CSS there is not much of a better way to handle both more succinctly without adding a class or ids.
You could consider a CSS pre-compiler (like LESS or SASS/SCSS).
In LESS or SCSS:
#mainPage #content div.group {
&:hover, &:active {
color: red;
}
}
I suggest add ID for the element has class group and write below code will reduce the effort:
#idname.group:hover, #idname.group:active{}
Is there a reason why you're using #mainPage #content before div.group?
Generally, it's not necessary to add that much 'specificity' to your selectors - it's better to instead, have unique classes. So make sure that the class .group is only used for elements that you want to have the same styles.
If you do that, you should be able to style those elements just using
.group { styles here}
You might run into an issue now where if you try to override any of the styles you set like #mainPage #content, those will be more specific and so in effect 'stronger' than styles where you don't use the full list of parents. If possible, change all your styles not to include the parent elements - this is also worthwhile in case you ever want to move an object to a different part of the html!
It's also, in general, advisable not to use id's (#name) to attach css styles - if possible, just use classes. Unless you're doing javascript, you shouldn't have much need for id's.
Obviously there exceptions to the above, and for all I know you may have a perfectly good reason for doing things the way you have - in which case SASS (as suggested in a few other answers) is a good solution for you.
If not useful for you, I hope at least this answer might be useful for someone who might come along later - I've noticed that a lot of people newer to css don't realize how specificity of selectors works and end up making their styles a lot more complicated than necessary as a result! :)
Old question, but this should be relevant for somebody who needs this.
Pseudo-class released by the end of 2020
You can use :is() pseudo-class like so :
#mainPage #content div.group:is(:hover, :active) {
}
Here is a little snippet to picture it :
a:is(:hover, :focus) {
color: red;
outline: #5bc8ea dotted 4px;
outline-offset: 4px;
font-weight: 600;
}
Hover/Focus me
More informations about :is() pseudo class here: https://developer.mozilla.org/en-US/docs/Web/CSS/:is and here: https://css-tricks.com/almanac/selectors/i/is/.
Works with most of the popular browsers (incompatible with IE, Opera and Safari < 14) https://caniuse.com/css-matches-pseudo.
It surely is more often used to select elements than pseudo-classes like :hover or :focus but it will do the trick as I can't see any other solution for now.
Why you use #mainPage #content? #content should be enough to find the div your looking for without the #mainPage.
Also id's are only allowed to be used once and not in multiple places like classes are. Id's are usually reserved for script assignments and not CSS. I would do
#content .group:hover{}
#content .group:active{}
if i understood correctly, you want a group of elements to act a certain way? manipulate the parent class then.
.parent-class:hover {
.child-class {
…desired styles go here
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
In our project we use SASS for styles development. Also, we use Bootstrap and it contains next well-known mixin:
#mixin clearfix {
*zoom: 1;
&:before,
&:after {
display: table;
content: "";
// Fixes Opera/contenteditable bug:
// http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952
line-height: 0;
}
&:after {
clear: both;
}
}
And we use it in our styles:
.class-example {
#include clearfix();
. . .
}
After the compilation into CSS, SASS copies all content of mixin into each class we used mixin. So, it's a big amount of duplicated code. We use mixin about 100 times, so it's about 1000 extra lines in css.
So, the question: which is better form performance/support/readability/etc. point of view
Use mixin and allow duplicated code be
Create class .clearfix and use it in markup like <span
class="example-class clearfix"> ... </span> to avoid duplication
Also, if someone has better solution - I'll be glad to get it. Any comments/discussions are welcome.
To begin with, I'd like to mention that applying overflow: hidden to an element with floating children clears the floats much like how including the clearfix mixin you're talking about does it.
For readability and performance, this is probably the clear winner. I don't have any data supporting that overflow: hidden actually renders faster than the clearfix, but I wouldn't be surprised if it does. It's much less CSS, though, so it's definitely a winner in terms of downloaded data.
It's not always possible to use overflow: hidden though as your layout may have some relative positioning going on. In those cases, the best performant method is to create a global class for .clearfix and apply it to all elements that are supposed to clear their children. While it doesn't sound like it's easily maintainable, I'd argue that it is more easily maintainable that including that mixin throughout your CSS since you won't have to clear the cached CSS whenever you make changes.
My recommendation is to use both overflow: hidden and .clearfix. Scrap #include clearfix.
The reasoning is that you can't always get away with just one method (sometimes you may want to use the :after element for something else, sometimes you may want content to stretch outside their containers) so having both available makes sense anyway.
With both methods available you're able to adapt to any scenario. Just remember you could tie overflow: hidden to a class name to keep it just as DRY as .clearfix.
My 2¢.
Edit:
Alternatively, but maybe not ideally, you could use #extend to create an output like this:
.element-1,
.element-2,
.element-3,
.element-4,
.element-5 {
// clearfix stuff
}
So that clearfix is defined at one place rather than multiple times through the document. Personally I'm not a big fan of it, but perhaps it makes sense to you.
I would suggest to make it a "helper" -class as you fine said your self, they are alot more agile and you put them where they are needed, also there are different clearfixes depending on the situration, some are overflow fixes some are table layout fixes and so on, i would rather create a class and add them where its needed, this also makes you layout classes independent of clear fixing. So they can live as stand alone and reusable codes not to have to worry if the clearfix could mess up potential layouts :)
Im using them as classes for a better and more agile way to do my layouts.
Edit, so i would say your solution number 2 is the best also for not as u are saying duplicating 100 lines of code.
Like others have said already, for a simple utility mixin like this, I'd define it as an extension instead, like this:
%clearfix {
//clearfix code
}
And then use it in the SASS like this:
.container{
#extend %clearfix;
}
This way, no matter how many times you extend it, the code that it outputs is in the CSS only once, instead of hundreds of times.
I would argue against using classes like clearfloat or clearfix in the markup unless you reeeallly need to-- why muddle up the markup when you can do it better and faster with CSS? Instead of tracking through a lot of different markup files, you can easily change it in one place, in your SASS file.
This allows you to have everything in one place, instead of spread out in many places, which makes maintaining it much easier, as I know from experience.
I am using bootstrap's less files in my current project and it has the following in mixins.less file:
// UTILITY MIXINS
// --------------------------------------------------
// Clearfix
// --------
.clearfix {
*zoom: 1;
&:before,
&:after {
display: table;
content: "";
// Fixes Opera/contenteditable bug:
// http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952
line-height: 0;
}
&:after {
clear: both;
}
}
we can define so-called "mixins", which have some similarities to functions in programming languages. They’re used to group CSS instructions in handy, reusable classes. Mixins allow you to embed all the properties of a class into another class by simply including the class name as one of its properties. It’s just like variables, but for whole classes. Any CSS class or id ruleset can be mixed-in that way:
.container{
.clearfix();
}
As far as clearfix is concerned, I just use it as clearfix because it is doing one task which is clearing floats and i.e. what bootstrap offers one class to get a particular task. It is independent of other classes.
You can use it in html like this:
<div class="clearfix"></div>
I recommend using the mixin and don't worry about the very small performance hit. In the future if there are certain content types that you no longer want to use the clearfix on, you will have to go through all of your html to remove the tag.
It is always safer to keep your markup clean and do your layout and styling in the css. In this case you are taking a very small performance hit in order to save yourself in terms of future support. If you are seeing performance as an issue, you might want to think about ways that you could set up your markup or css so that you don't have so many classes that call .clearfix.
First of all!
I would start off by suggesting not using overflow: hidden. It is a hack and therefore will lead to confusing code for people in the future, especially new people to any business you apply this code in. There are also repercussions that a JavaScript developer would have to contend with for any position related elements.
So what are the PROS and CONS of applying a clearfix class everywhere or just applying an include within your SASS?
clearfix class
clearfix on a DOM element shows that the content is floating to any person without looking any further. The clearfix styling is written only once, making your Stylesheet files smaller.
#include clearfix
Great whoooop dee doo, let's all use the include everywhere and expand our Stylesheet mass shall we. But wait! I did find an interesting opportunity to really use it, which I will do for this exact reason.
If you have classes not in a template that requires a clearfix, so written all over the DOM. I could imagine wanting to use the include option. Though this is fairly rare.
Also, as a class undergoing responsive changes on the page suddenly requires a clearfix, you can nestle that within a nice #import media() with bourbon neat for example. But even this would be rare as you could just apply the clearfix again and be done with it right from the start.
Conclusion
I think a happy medium is called for, which should always be the case when writing SASS. But that is my personal opinion :-P
How does one go about establishing a CSS 'schema', or hierarchy, of general element styles, nested element styles, and classed element styles. For a rank novice like me, the amount of information in stylesheets I view is completely overwhelming. What process does one follow in creating a well factored stylesheet or sheets, compared to inline style attributes?
I'm a big fan of naming my CSS classes by their contents or content types, for example a <ul> containing navigational "tabs" would have class="tabs". A header containing a date could be class="date" or an ordered list containing a top 10 list could have class="chart". Similarly, for IDs, one could give the page footer id="footer" or the logo of the website id="mainLogo". I find that it not only makes classes easy to remember but also encourages proper cascading of the CSS. Things like ol.chart {font-weight: bold; color: blue;} #footer ol.chart {color: green;} are quite readable and takes into account how CSS selectors gain weight by being more specific.
Proper indenting is also a great help. Your CSS is likely to grow quite a lot unless you want to refactor your HTML templates evertime you add a new section to your site or want to publish a new type of content. However hard you try you will inevitably have to add a few new rules (or exceptions) that you didn't anticipate in your original schema. Indeting will allow you to scan a large CSS file a lot quicker. My personal preference is to indent on how specific and/or nested the selector is, something like this:
ul.tabs {
list-style-type: none;
}
ul.tabs li {
float: left;
}
ul.tabs li img {
border: none;
}
That way the "parent" is always furthest to the left and so the text gets broken up into blocks by parent containers. I also like to split the stylesheet into a few sections; first comes all the selectors for HTML elements. I consider these so generic that they should come first really. Here I put "body { font-size: 77%; }" and "a { color: #FFCC00; }" etc. After that I would put selectors for the main framework parts of the page, for instance "ul#mainMenu { float: left; }" and "div#footer { height: 4em; }". Then on to common object classes, "td.price { text-align: right; }", finally followed by extra little bits like ".clear { clear: both; }". Now that's just how I like to do it - I'm sure there are better ways but it works for me.
Finally, a couple of tips:
Make best use of cascades and don't "overclass" stuff. If you give a <ul> class="textNav" then you can access its <li>s and their children without having to add any additional class assignments. ul.textNav li a:hover {}
Don't be afraid to use multiple classes on a single object. This is perfectly valid and very useful. You then have control of the CSS for groups of objects from more than one axis. Also giving the object an ID adds yet a third axis. For example:
<style>
div.box {
float: left;
border: 1px solid blue;
padding: 1em;
}
div.wide {
width: 15em;
}
div.narrow {
width: 8em;
}
div#oddOneOut {
float: right;
}
</style>
<div class="box wide">a wide box</div>
<div class="box narrow">a narrow box</div>
<div class="box wide" id="oddOneOut">an odd box</div>
Giving a class to your document <body> tag (or ID since there should only ever be one...) enables some nifty overrides for individual pages, like hilighting the menu item for the page you're currently on or getting rid of that redundant second sign-in form on the sign-in page, all using CSS only. "body.signIn div#mainMenu form.signIn { display: none; }"
I hope you find at least some of my ramblings useful and wish you the best with your projects!
There are a number of different things you can do to aid in the organisation of your CSS. For example:
Split your CSS up into multiple files. For example: have one file for layout, one for text, one for reset styles etc.
Comment your CSS code.
Why not add a table of contents?
Try using a CSS framework like 960.gs to get your started.
It's all down to personal taste really. But here are a few links that you might find useful:
http://www.smashingmagazine.com/2008/08/18/7-principles-of-clean-and-optimized-css-code/
http://www.smashingmagazine.com/2008/05/02/improving-code-readability-with-css-styleguides/
http://www.louddog.com/bloggity/2008/03/css-best-practices.php
http://natbat.net/2008/Sep/28/css-systems/
Think of the CSS as creating a 'toolkit' that the HTML can refer to. The following rules will help:
Make class names unambiguous. In most cases this means prefixing them in a predicatable way. For example, rather than left, use something like header_links_object2_left.
Use id rather than class only if you know there will only ever be one of an object on a page. Again, make the id unambiguous.
Consider side effects. Rules like margin and padding, float and clear, and so on can all have unexpected consequences on other elements.
If your stylesheet is to be used my several HTML coders, consider writing them a small, clear guide to how to write HTML to match your scheme. Keep it simple, or you'll bore them.
And as always, test it in multiple browsers, on multiple operating systems, on lots of different pages, and under any other unusual conditions you can think of.
Putting all of your CSS declarations in roughly the same order as they will land in the document hierarchy is generally a good thing. This makes it fairly easy for future readers to see what attributes will be inherited, since those classes will be higher up in the file.
Also, this is sort of orthogonal to your question, but if you are looking for a tool to help you read a CSS file and see how everything shakes out, I cannot recommend Firebug enough.
The best organizational advice I've ever received came from a presentation at An Event Apart.
Assuming you're keeping everything in a single stylesheet, there's basically five parts to it:
Reset rules (may be as simple as the
* {margin: 0; padding: 0} rule,
Eric Meyer's reset, or the YUI
reset)
Basic element styling; this
is the stuff like basic typography
for paragraphs, spacing for lists,
etc.
Universal classes; this section
for me generally contains things
like .error, .left (I'm only 80%
semantic), etc.
Universal
layout/IDs; #content, #header,
or whatever you've cut your page up
into.
Page-specific rules; if you
need to modify an existing style
just for one or a few pages, stick a
unique ID high up (body tag is
usually good) and toss your
overrides at the end of the document
I don't recommend using a CSS framework unless you need to mock something up in HTML fast. They're far too bloated, and I've never met one whose semantics made sense to me; it's much better practice to create your own "framework" as you figure out what code is shared by your projects over time.
Reading other people's code is a whole other issue, and with that I wish you the best of luck. There's some truly horrific CSS out there.
Cop-out line of the year: it depends.
How much do you need to be styling? Do you need to change the aspects of alomost every element, or is it only a few?
My favorite place to go for information like this is CSS Zen Garden & A List Apart.
There are two worlds:
The human editor perspective: Where CSS is most easily understand, when it has clear structure, good formatting, verbose names, structured into layout, color and typesetting...
The consumer perspective: The visitor is most happy if your site loades quickly, if it look perfect in his browser, so the css has to be small, in one file (to save further connections) and contain CSS hacks to support all browsers.
I recommend you to start with a CSS framework:
Blueprint if you like smaller things
or YAML for a big and functional one
There is also a list of CSS Frameworks...
And then bring it in shape (for the browser) with a CSS Optimizer (p.e. CSS Form.&Opti.)
You can measure the Results (unpotimized <-> optimized) with YSlow.
A few more tips for keeping organized:
Within each declaration, adopt an order of attributes that you stick to. For example, I usually list margins, padding, height, width, border, fonts, display/float/other, in that order, allowing for easier readability in my next tip
Write your CSS like you would any other code: indent! It's easy to scan a CSS file for high level elements and then drill down rather than simply going by source order of your HTML.
Semantic HTML with good class names can help a lot with remembering what styles apply to which elements.