I'm getting an error when attempting to compile my SCSS file into CSS. The error reads: "selector groups may not be extended" in reference to this line #extend .btn, .btn-link;.
Note: I'm importing Bootstrap to use in my main scss file.
Full snippet:
button {
#extend .btn, .btn-link;
background-color: $lf-green;
color: #fff;
font-size: 10px;
padding: 2px 5px;
text-transform: uppercase;
&:hover {
background: rgba(5,97,43,0.9);
color: #fff;
text-decoration: none;
}
}
What am I doing wrong?
Thanks!
UPDATE:
For posterity: The reason I couldn't do this was because I was using lib-sass via node-sass, which doesn't mesh with the current version of sass available through traditional means https://github.com/andrew/node-sass#reporting-sass-compilation-and-syntax-issues.
I believe you cannot extend multiple selectors this way.
Try using this:
#extend .btn;
#extend .btn-link;
Although that seems a little repetitive, but works fine in my codes.
EDIT: while reading through SASS_REFERENCE, I found that:
Multiple extends can also be written using a comma-separated list of selectors. For example, #extend .error, .attention is the same as #extend .error; #extend.attention.
I did found it in the changelog that this format was first introduced in version 3.1.15, so I suppose you are using an older version of Sass than that.
I strongly encourage you to upgrade to the latest version, as it has a lot of great features, just make sure your codes are not broken by an update, although most of the inconsistencies can be worked out rather easily.
You cannot extend more than one selector.
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.
This is the important part of my LESS file:
input.ng-invalid {
color: #e74c3c;
border-color: #e74c3c;
}
It compiles into this:
input.ng-invalid .form-control {
color: #e74c3c;
border-color: #e74c3c;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
http://plnkr.co/edit/118uS4RciQYVPa5KH6oU
The form-control class is from Bootstrap and wouldn't break the selector if LESS didn't insert a space (input.ng-invalid.form-control works just fine)
The problem is that the browser is looking for the children of input with the class form-control. Apparently, there are no childrens of input in my HTML.
Is there a setting in bootstrap's LESS files that binds the form-control class to every input?
I've taken a look at the zip package you provided and there your input.ng-invalid is defined as (selfmade.less:L97):
input.ng-invalid {
.form-control-validation(#brand-danger; #brand-danger);
}
which is expected to compile to what you actually get (i.e. appending nested classes defined within .form-control-validation). This is just what this mixin is supposed to do.
-
Is there a setting in bootstrap's LESS files that binds the form-control class to every input?
I can't see any (at least in Bootstrap 3.1.1), so I can only suggest the following trick:
.danger_ {
.form-control-validation
(#brand-danger, #brand-danger);
}
input.ng-invalid.form-control
:extend(.danger_ .form-control all) {}
which will compile to this css (assuming bs-3.1.1).
-
Alternatively there's .has-error class which you can extend the same way:
input.ng-invalid.form-control
:extend(.has-error .form-control all) {}
and get a bit more compact output but with slightly different colours (#state-danger-text instead of #brand-danger).
This is not really an answer, but an investigation of your problem which doesn't fit in the comments box. I did't go through your set of less files since I don't have a 7z uncompressor here, but maybe I can give you some ideas to help you fix the problem or hack it.
One way of obtaining a contextual relationship like this:
input.ng-invalid .form-control { ... }
Is having a block like this somewhere in your Less files:
input.ng-invalid {
...
.form-control { ... }
...
}
Now that association might happen through a mixin so you probably won't find that exact pattern above, but you might find want to discover where .form-control is declared (a mixin, perhaps).
Now if you want this:
input.ng-invalid.form-control { ...}
and you a block like the one I showed above, you can add a & before the .form-control selector so that instead of obtaining a contextual relationship from the nesting blocks, you add a class. The & represents the selectors from the parent block. It would be something like:
input.ng-invalid {
...
&.form-control { ... }
...
}
See if you discover where .form-control is defined and try it out.
(Be aware that if other parts of your code use this mixin or selector, they may not work as before - this was just an analysis of a possible solution using Less and not the Bootstrap framework; add a bootstrap tag to your question and you might attract some Bootstrap specialists who might have a better solution.)
I'm trying to learn SASS now, and I'm having trouble trying to visualize exactly how differently I would arrange my code. How would I, for instance, arrange the following code into SASS so that it avoids repetition?
a: link {color: #000; text-decoration: none;}
a: visited {color: #000; text-decoration: none;}
a: acive {color: #000; text-decoration: none;}
Currently the only way I can think of is adding two different variables with the following appropriate attributes, but that still seems repetitive to me. I have also considered mixins, but am unsure how exactly to incorporate them in this example.
��Thanks in advance for the help. Also, as far as I understand it, SASS isn't meant to enhance web performance, just workflow. Is this correct? I say this specifically because, when processed, the code ends up looking the same on CSS.
The repeated part of this is the a and the styles color: #000; text-decoration: none.
So, with SASS you can nest your styles so you only need to write a once. The syntax for :link etc, is &:link.
Therefore, you can write:
a {
&:link,
&:visited,
&:active {
color: #000;
text-decoration: none;
}
}
Or if you do have variables, e.g. $black: #000; you can swap them in. color: $black.
It's not only for workflow though. One of the main advantages of using SASS (or LESS) is that you can organise your SASS files separately e.g. _buttons.scss, _layout.scss etc, and then import (using #import) them all into one 'theme.scss' and then have SASS compile the 'theme.scss'.
How this compilation is done depends on your setup, but Compass (Compass.app for the UI lovers like me) is a very popular option. What you end up with is the browser only request 1 file for styles, rather than many.
#mixin links($color:#000,$tdec:none){
a{
&:link,&:visited,&:active{
color:#{$color};
text-decoration: #{$tdec};
}
}
}
Then use the mixin ;
#include links();
or
#include links(#fee,underline);
may be this is what you're looking for.
Yeah. SASS doesnt meant to enhance web performance. But im sure SASS can mess your CSS if you use it wrong way(unnecessary nesting etc).
When you get used to it, it'll save your coding time alot.
This question already has answers here:
False positive "undefined variable" error when compiling SCSS
(4 answers)
Closed 7 years ago.
My question is actually broader than the title says. This is just where I am running into a snag with my idea, but I am open to all sorts of solutions. Let me explain my overall goal.
I like what CSS preprocessors can do. I like the ideas of OOCSS and SMACSS. I am new to all of this. I am trying to upgrade my design methods to somehow incorporate the best of all worlds. I have a theoretical method that works like this:
use only semantic class names or id's or whatever
define modules or patterns in some common style sheet
have per page stylesheets that #extend modules from the common stylesheet onto the semantic selectors pertaining to a given page
So this:
/* modules.scss */
.ruddy {color: red}
.fullwidth {width: 100%; display: block;}
plus this:
/* homepage.scss */
#import modules.sass
#intro {#extend ruddy; #extend fullwidth}
aside {#extend ruddy;}
.thing {#extend fullwidth;}
becomes this:
/* homepage.css */
#intro, aside {color: red}
#intro, .thing {width: 100%; display: block;}
I haven't necessarily seen anybody else do this but it seemed like a good idea to me. The problem I am running into in my grand scheme is that #extend doesn't seem to work from an imported file. Someone somewhere else on SO said that it is not possible. Is this true? I got mixins to work but problem with them is that they duplicate every attribute in the output css, which doesn't seem ideal.
I'm actually more partial to LESS (syntax), but that doesn't even have extending at the moment. Should I not worry about the inefficiencies of mixins or is there some way to achieve what I'm asking for?
Note:
I am auto-compiling my sass with a tool called Prepros. When I try to compile code such as the above I get an error like.
WARNING on line 11 of ... \sass\home.scss: "#intro" failed to #extend "ruddy".
The selector "ruddy" was not found.
If I just copy the code from module.scss into homepage.scss then the problem goes away.
The problem is here:
#intro {#extend ruddy; #extend fullwidth}
aside {#extend ruddy;}
.thing {#extend fullwidth;}
ruddy and fullwidth aren't selectors. If you're extending the .ruddy class, you need to include the period, as that is part of the selector.
#intro {#extend .ruddy; #extend .fullwidth}
aside {#extend .ruddy;}
.thing {#extend .fullwidth;}
It is not true.
You can declare classes (including the %-prefixed ones) in one file, import the first file into the second file and extend the classes in the second file.
Example:
foo.sass
%foo
color: red
bar.sass
#import foo.sass
html
#extend %foo
Run sass bar.sass bar.css.
bar.css appears
html {
color: red; }
PS For real SASS experience, you should leverage Compass. Compass is a bunch of things under one name:
a handy tool to compile SASS efficiently;
a huge library of handy SASS styles for all occasions;
an ecosystem of extensions that you can install and use in your projects effortlessly. This is what makes SASS stand out. You don't have to reinvent the wheel over and over again.
UPD Finally error text!
You're missing the dot in the name of the class. aside {#extend ruddy;} should be aside {#extend .ruddy;}.
I'm not sure what to call this, but basically let's say I have a style that I use a lot,
.somepattern{
font-size:16px;
font-weight:bold;
border:2px solid red;
}
but sometime I want to change the font-size and the color for border. Is it possible to treat this code as a library, where I can set the style to a div
<div class="somepattern">Text</div>
but still control the 16px and red like we do with functions?
I know I'm late to the party but the selected answer IS NOT the right answer since it's deferring it to CSS preprocessors.
To answer the specific question "Do CSS functions exist?", the answer is: Yes.
However, CSS functions work completely different than the OP's concept initially is.
cuixiping's answer seems the most correct answer.
Examples of CSS functions are:
url()
attr()
calc()
rotate()
scale()
linear-gradient()
sepia()
grayscale()
translate()
A detailed, comprehensive list can be found here:
CSS functions on MDN Updated link 18/9/20
You can't programatically control CSS from your markup, but you can use one of the many CSS extensions to make CSS work more like a compiled language.
http://lesscss.org/
http://sass-lang.com/
If we wrote your example in LESS, we'd get something like this:
.somepattern(#color: red, #size: 16px) {
font-size:#size;
font-weight:bold;
border:2px solid #color;
}
And then you could use it in your LESS file like so:
.myclass {
.somepattern(green, 20px);
}
Nope. No CSS functionality like you require. At least not directly.
But there are at least two rather generic ways for you to use to accomplish what you need:
Class combining
You can of course combine as many classes as you like in any element like:
<div class="heading run-in">
Some heading
</div>
Lorem ipsum dolor sit amet...
and you'd have CSS defined as:
.heading {
color: #999;
font-size: 16pt;
font-weight: bold;
border-bottom: 2px solid red;
display: block;
margin: 1.5em 0 .5em;
}
.run-in {
display: inline;
margin: 0;
font-size: 1em;
}
LESS CSS
And there is of course LESS CSS project that lets you define variables (and has other sugars as well) and use them in other classes.
LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions. LESS runs on both the client-side (IE 6+, Webkit, Firefox) and server-side, with Node.js.
If your server platform is .net there's a project DotLessCSS with a library in .net as well. And there's also T4 template by Phil Haack.
Mind that there are many CSS preprocessors/enhancers like LESS CSS as well:
SASS
xCSS
HSS
CleverCSS
And probably some others that I didn't mention. Some support nesting CSS3 selectors as well others don't. Some are aimed at particular server-side technology some don't. So choose wisely.
you can redefine style by adding the style tag to your HTML:
<div class="somepattern" style="font-size:5px">Text</div>
or by applying multiple classes like class="somepattern small".
HTML
<div class="somepattern small"> Text </div>
CSS
.small {
font-size:5px;
}
the small class will be applied after the somepattern class and will therefore override any properties set in the some pattern class.
Even later to the party!
You can now do this with css custom variables.
In our css using the var() function:
.some-pattern {
font-size: var(--font-size);
font-weight: bold;
border: var(--border);
}
Then in our html defining the custom variables inline:
<div
class="some-pattern"
style="--border: 3px double red; --font-size: 16px;"
>
test
</div>
What you described is actually done with style attribute.
<div class="somepattern" style="font-size:10px;">Text</div>
I think this is exactly what you want. And it is not recommended, because it breaks the usual (good) pattern of spitting content and its visual style. (Although, honestly, I do use it a lot. ;-))
its a css class. It cannot be used like functions if that's what you are asking. There is no code library as its not a compiled. CSS is just presentation semantics (formatting) of a document written in a markup language. You can include all css classes in a .css file and use it where ever you want instead.
I've come to realize through the comments of others that this solution overcomplicates the problem at hand. This solution works but there are easier and better alternatives that do not depend on server-side scripting.
You can actually control your stylesheet if you make it a php file stylesheet.php?fontsize=16 and then inside your stylesheet you can retrieve the variable
<?php
header("Content-type: text/css");
$fontsize=16;
?>
.somepattern{
font-size: $fontsize;
font-weight:bold;
border:2px solid red;
}
Yes, it's possible. But you have to make it on your own with the help of Recatjs(u don't have to go deeper, basic is enough for this). Actually, think like that If bootstrap can make such things where we just have to define the class name and it automatically designes HTML files, then why we cannot do it.
Here's the image of my code(https://i.stack.imgur.com/hyePO.png)
and this is how I used it in my jsx code (https://i.stack.imgur.com/yK6VD.jpg)
Do you mean inline styles ? <div class="somepattern" style="border-color:green">Text</div>