In Bootstrap tutorials, when people create their own Sass variables in a custom style.scss, I see lots of them using trailing !important.
If you want to see an example of what I mean, start at 13:45 here:
https://www.youtube.com/watch?v=MDSkqQft92o&time_continue=24&app=desktop
.navbar {
width: 100%;
background none !important;
#media(max-width: 34em) {
background: black !important;
}
}
But then other code in the .scss file doesn't use !important. No explanation of why that is.
Anyone have some suggestions?
!important means that the style preceding it will be "forced" onto the element, despite what other styles may set on it. For example:
.element {
font-weight: bold;
}
.custom-class {
font-weight: normal !important;
}
If you have an <span class="custom-class element"></span>, it will be displaying a font-weight normal, not bold.
! important guarantees (or at least it tries) that the rule you're trying to apply is more important than others. So it overwrites other rules that might interfere with the new one. ! important is not necessary if the rules are ordered correctly because the last rules prevail over previous ones. ! important must be avoided as much as possible. Use it only if it's really necessary.
Related
I have two CSS from two big projects, whereas I need to merge the two CSS together. Essentially, I just included both CSS in the HTML header of the new project that needs both CSS.
Using WebStorm what is the best way to find and track colliding CSS properties?
For example (note this is just a basic example to express my point):
first.css
.my-class-1 {
background: #eeeeee;
color: #ffffff;
font-family: 'Poppins', sans-serif !important;
min-height: 59%;
}
second.css
.my-class-2 {
background: #000000;
color: #ffffff;
font-family: 'Poppins', sans-serif !important;
min-height: 100%;
}
And given that it is used
<div class="my-class-1 my-class-2" ></div>
From these examples, the background and min-height properties are colliding to each other.
I think your best bet would be to actually load the page in your browser, and use chrome dev tools to inspect the styles. You can do this with most browsers, but I would choose either Chrome or Firefox as they're probably the most refined. This can show you the computed styles and what styles are overwritten by others.
You need to check for these styles manually as your IDE won't have the context to understand that there are conflicting classes being used in the html.
However, if you want to search for duplicate CSS within the CSS file, I would suggest something like http://csslint.net/
The best solution is to use https://stylelint.io/
With this configuration:
{
"extends": "stylelint-config-standard",
"rules": {
"no-duplicate-selectors": true
}
}
It is able to detect similar names which actually help (mostly) finding the colliding CSS properties based on common names.
On my website, I'm constantly doing style="font-size: #ofpx;". However, I was wondering if there's a way to do it with scss so that, when I declare a class, it would also change the font size. For example:
<div class='col-lg-4 font-20'>whatever here</div>
and this would change my font-size to 20. If I did font-30, it would change my font-size to 30 and etc...
What I have so far:
.font-#{$fontsize} {
font-size: $fontsize;
}
This can't be done for arbitrary sizes. The nature of SCSS is that is needs to be flattened down to CSS before it gets applied to the HTML. What you are asking for, however, is essentially to create rules at run-time rather than compile-time.
In other words, SCSS makes it easier to write some of the repetitive parts of CSS, but it doesn't allow you to do anything new that wasn't already possible with plain old CSS.
What you're asking for is also a code smell. It smells like your markup isn't semantic enough. The purpose of a CSS class is to group objects with similar characteristics, but you're using them instead to describe the styles they impart. I would suggest stepping back and reconsidering what it is that you really want.
You obviously have details of certain elements that are context-dependent. For example, maybe you are applying these rules to buttons when you want to make them smaller or larger than usual. You need to identify the scenarios in which the buttons change. Maybe they are 20% smaller if they are in a modal dialog? Then write your normal .button rules, and also create rules for .modal .button which make it smaller.
If you're positive that you want to define font-size for each element within the HTML (and sometimes there are good reasons for doing so), just continue using inline styles. The only reason inline styling is frowned upon is because it combines model and view logic in a way that harms reusability; however, what you are requesting does so in exactly the same way. This is what inline styles were made for. Don't re-invent the wheel.
With all of that said, you can use sass loops to automatically generate classes for integers within a range. For example:
/* warning: this is generally a bad idea */
#for $i from 1 through 100 {
.font-#{$i} {
font-size: #{$i}px;
}
}
This is not a good idea. Pragmatically speaking it doesn't offer any advantages over just using inline styles and with large ranges your resulting file will be larger (which affects website load times).
Aside: There is a CSS philosophy (or fad, if you're feeling ungenerous) called Atomic CSS (or sometimes Functional CSS) which defies the classical advice given in this answer. I won't give an opinion on its effectiveness at producing clean, maintainable code, but it does typically require more tooling than SCSS alone if used with the degree of specificity requested in this question.
Just going to add, mixins are great, but if you want a util class (attach a class to an element, get that font-size applied to it, do a for-loop in SCSS like so..
#for $i from 1 through 4 {
$fontsize: 10px * $i;
.font-#{$i} {
font-size: $fontsize;
}
}
compiles to
.font-1 {
font-size: 10px;
}
.font-2 {
font-size: 20px;
}
.font-3 {
font-size: 30px;
}
.font-4 {
font-size: 40px;
}
If you want the class to match the # of pixels...
#for $i from 1 through 4 {
$base: 10;
$fontsize: $base * $i;
.font-#{$fontsize} {
font-size: $fontsize + 0px;
}
}
Which compiles to
.font-10 {
font-size: 10px;
}
.font-20 {
font-size: 20px;
}
.font-30 {
font-size: 30px;
}
.font-40 {
font-size: 40px;
}
Codepen example.
When using "words" instead of "numbers" for variables, and the word not being at the end of the classname. I could work something out using CSS Attribute selectors ("wildcard selector"). I can iterate over a map object, and use text values to build CSS selectors.
SASS
//map
$colors: (
primary: #121212,
success: #8bcea8
);
//loop
#each $color, $value in $colors {
//can't do this: div.first-class.is-style-#{$color}-component
//can do this:
div.first-class[class*="is-style-#{$color}-component"] {
background-color: $value;
}
}
HTML
<div class="first-class is-style-primary-component"></div>
This will generate a div.myComponent[class*="is-style-primary-component"] selector and so <div class="first-class is-style-primary-component"></div> (.first-class is not required, selector could be div[class*="is-style-#{$color}-component"] or even [class*="is-style-#{$color}-component"] only).
Yet, in some cases of CSS class naming, it could be limited due to the wildcard selector, which is "larger" than a specific class selector rule.
Of course, inline style tags are bad form. So yes, you should add some classes for font size, or just set font size on the elements you need to as you go. Up to you. If you want, you could use a mixin like so:
#mixin font-size($size) {
font-size: $size;
}
.some-div { #include font-size(10px); }
But that's probably overkill unless you get a group of rules that usually go together.
Just for those of you who might stumble across this question in a more recent time and are new to FrontEnd Development.
What Woodrow Barlow said about using inline-styles instead of rule specific classes isn't quite an up-to-date opinion. For instance, Bootstrap has some of those and Tachyons is entirely built upon them. Actually this practice is called Atomic CSS or Functional CSS.
It's better explained by John Polacek in his CSS Tricks article:
https://css-tricks.com/lets-define-exactly-atomic-css/
You can use mixins like this
#mixin font($fontsize) {
font-size: $fontsize;
}
.box {
#include font(10px);
}
One feature I really love with LESS is nested rules. It makes the stylesheet much cleaner that way and you can find an element very quickly.
I was wondering if there's an option when compiling to optimize selectors. For example...
#global {
/* Styles here maybe */
.container {
/* Styles here maybe */
#sidebar {
/* Styles here maybe */
.title {
font-weight: bold;
}
}
}
}
will be compiled to #global .container #sidebar .title { font-weight: bold; }.
But the first two selectors are useless, since #sidebar should be unique in my page.
Is there a way to ask LESS to compile this to #sidebar .title { font-weight: bold; } instead?
Your assumption is wrong that multiple IDs in CSS are redundant. Imagine, as an example, a site where the CMS generates the page type into the output, like that it's the contact page:
<body id="contact">
<section id="content">Blah</section>
</body>
According to your logic, the following piece of CSS would be a candidate for 'optimization':
#contact #content {
background:red;
}
Now however, your home page has <body id="home"> of course in this imaginary CMS. And suddenly the content of your homepage has a red background because you decided to erroneously optimize that #contact selector out of the CSS, while it most certainly shouldn't have a red background according to this rule.
So no, LESS cannot do this because it would break code. If you don't want the selectors, don't use them and don't put them in your code.
Other answers, including the accepted one, have explained convincingly why LESS cannot simplify your nested selectors in the way you want.
Actually, SASS has the ability to do this:
#global {
.container {
#at-root #sidebar {
.title {
font-weight: bold;
The #at-root directive essentially ignores all the higher nesting selectors. I don't know if LESS has something similar. The above compiles into simply
#sidebar {
.title {
font-weight: bold;
But there is a deeper issue here, starting with the fact that you "love" nested rules in LESS. Stop loving them quite so much. I don't know about you, but most people love nested rules because they think it's cool to exactly mimic the hierarchical structure of their HTML. The SASS docs even claim this as a benefit:
Sass will let you nest your CSS selectors in a way that follows the same visual hierarchy of your HTML.
So people with HTML such as
<div class="foo">
<ul>
<li class="item">
write LESS like
.foo {
ul {
li.item {
This is a horrible, horrible idea, It makes the structure of CSS completely dependent on the structure of the HTML. If you change one nesting level in the HTML, your CSS breaks. Often this approach is combined with a lot of rules defined against tag names such as ul instead of class names, which aggravates the dependency, so changing the ul to ol in the HTML breaks the rules again. Or it's combined with rules based on Bootstrap classes such as col-md-6, so if you ever change that to col-md-4 things break again.
CSS rules should be orthogonal to the HTML. They represent a different dimension. They represent styling concepts which are applied selectively throughout and across the HTML.
I am guessing that you wrote
#global {
.container {
#sidebar {
.title {
font-weight: bold;
because you are adopting this mistaken idea of mirroring the HTML structure in your LESS. Then, you notice that this compiles down to having selectors which contain multiple IDs, which you imagine must be inefficient (although, actually, the degree of inefficiency is minimal). You yourself are writing extraneous nesting levels in your LESS, then complaining that they may be slowing down performance!
Worse, you've hard-wired assumptions about the HTML structure into your CSS. It's of no consequence that the sidebar happens to fall inside a .container which is inside a global element. So don't write them. Perhaps at some point you decide to change the container class to container-fluid. Boom, instantly your CSS breaks. What is the point of conditionalizing the fact that the title should be bold on it being contained with a container class, which in any case is a layout-related class that has (or should have) nothing to do with styling? If you're going to duplicate your HTML structure in your CSS using preprocessor nesting, just go back to writing inline styles. At least that way you'll only have one file to change when you change your HTML around.
When designing CSS, you should think just as hard about the design of the rules as you do about the design of classes and methods when writing JS. In this case, you need to ask yourself, "What characterizes the situation where I want some title to be bold? What drives that? What is the nature of boldness? What am I indicating by boldness? What is the semantic notion indicated by boldness?"
Let's say that you want all titles to be bold. Then you simply say that:
.title { font-weight: bold }
Let's say that you want a title to be bold only when it's in the sidebar. Then you simply say that:
#sidebar .title { font-weight: bold; }
My suggestion here is to go cold turkey. Stop using nesting during a withdrawal period. Write rules with the minimum number of selector components. Refactor your classes to have semantic names (such as title-emphasis). Once you're "sober", you can go back to cautiously using LESS's nesting capability when it is useful, such as perhaps for hover:
#boo {
color: red;
&:hover {
color: blue;
}
}
This is actually useful and saves you from writing #boo twice, and groups the rules in an easy-to-understand way.
I am trying to use .less to modify a Joomla Gantry template. The text I'm trying to change with the "aa" class has linked audio, so the whole text shows up in blue color, which I am trying to change to dark brown. Here what I'm working with in my .less file:
.aa {
cursor: url(/images/listen.cur), progress !important;
color: #2E1507;
}
It's very simple, but I couldn't make the cursor change before without "progress !important", which doesn't make sense to me.
Now I am trying to change the color, but I can't find a way. Is there something important that I'm missing in trying to change these styles?
I think #seven-phases-max provide you the right answer in the first place. !important in LESS has the same meaning as in CSS. You will use !important to overrule the CSS specificity rules. In most cases it is not a good idea to use !important, try to find the a selector with a higher specificity instead. Read also: http://css-tricks.com/when-using-important-is-the-right-choice/. One reason to use !important mentioned here will be utility classes. Maybe this is why you choose to use it here too.
progress sets your cursor type, see http://www.w3schools.com/cssref/pr_class_cursor.asp. Cause you already use a url() for this, progress should not have any effect (auto is the default style).
Note if you need !important to set your cursor, you probably also will need it to set your color: color: #2E1507 !important;
When using a mixin in LESS you can set the !important; for all your properties once like:
.importantaudio(){
cursor: url(/images/listen.cur), progress;
color: #2E1507;
}
.aa{ .importantaudio() !important;}
CSS (result):
.aa {
cursor: url(/images/listen.cur), progress !important;
color: #2E1507 !important;
}
I hope this question isn't too weird and arbitrary. When I'm viewing some CSS using Firebug, I've noticed that the CSS properties for each tag are in alphabetical order.
Is it trying to tell us something?
Apart from the obvious benefit of being able to find the property you're after more quickly, I was wondering this: Is it quicker for a browser to apply the properties if they are in alphabetical order in the original stylesheet?
For example is this...
body {
background: #222;
color: #DDD;
font-size: 0.85em;
}
#content {
background: #444;
padding: 1em;
}
p {
border-bottom: 0.9em;
line-height: 1.2em;
text-align: justify;
}
...better than this...?
body {
font-size: 0.85em;
background: #222;
color: #DDD;
}
#content {
padding: 1em;
background: #444;
}
p {
text-align: justify;
line-height: 1.2em;
border-bottom: 0.9em;
}
Can this be tested effectively?
This would obviously be replicated throughout the entire stylesheet so would a browser benefit from doing things in order and, if so, would it be worth revisiting past stylesheets to reorder things?
-- edit --
Ok, a slight alteration to my question: What if the attributes are always in the same order for each tag. Background always before border always before color etc and so on (I know I've missed some!) for each and every tag. Alphabetical would aid you in keeping things in order rather than being the optimal method.
Looks like the overwhelming consensus is that it matters not, however!
There's definitely no speed benefit in ordering your styles alphabetically.
If you want real speed benefits, you should minify your CSS.
There are so many programs to do that, but here's one of them: CSSTidy. This program also has the option to put your styles in alphabetical order (if you want that for your benefit).
I don't think order of statements affects speed in any way, however, the efficiency of the statements can affect performance. (Slightly tangential, I guess...)
See: http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
The performance benefit is for visual parsing only - FireBug will re-arrange your style attributes into alphabetical order when you inspect an element, which I find much quicker to locate a style attribute.
Firebug do it so that developers can search for an attribute value easily, and if you want speed benefit, write your css judiciously, which includes mainly avoiding repetition and redundancy and being DRY
Also when a page loads and CSS is parsed and layout is rendered once, next time its not done again, so stay calm, and try to make it more maintainable instead
Writing CSS in an alphabetical order just makes one thing easy: finding your attribute. It has nothing to do with speed.
To Increase speed, you can use shorthands rather than using separate attributes. Things like border-color, border-width, border-style can be used in a single attribute called border.