Sass Multiple Selector Refactoring - css

I remember reading about a Sass feature that allowed you to specify a list of elements and then a child and it would compile to a list of multiple selectors. I ahve searched around but can't find it.
I want it to compile down to this:
header .container,
footer .container
background: yellow
But i'm sure there is a feature of Sass that allows writing that in a much nicer way.
Any ideas?

That style could be refactored as this:
.container {
header &, footer & {
background: yellow;
}
}
But maybe you are thinking of a Compass feature? http://compass-style.org/reference/compass/helpers/selectors/#nest

Related

overwrite css items depening on className

I'm having problems with my CSS markup in my code.
I'm building a control and my plan is to add a standard class to it so it has a fixed layout and add any userdefined css classes behind it, to personalise the control. but during my tests I noticed a problem which I can't resolve.
when I have an element like this
<div class="test1 test2"></div>
and underlaying code in another stylesheet file.
.test1
{
width: 200px;
height: 200px;
background-color: red;
}
.test2
{
background-color: yellow;
}
then it doesn't matter if I put test1 first or test2. the div will always be yellow only because test1 is written last on the css file.
if I replace test2 with test1 in the css file itself then the div will always be red.
how can I make the background-color overwrite incase its added a second time depending on the order its written in the className itself?
I also want to take notice I don't want to force users to use the !important tag. I already know about this and yes that works fine but I need it without. Any ideas on how to resolve this issues is welcome. I'm open for alternatives
You could make it so .test2 when combined with .test1 becomes yellow
.test1.test2{
background-color: yellow;
}
a better way tough is not to work like this at all. have a read of this article instead. It explains a technique for CSS called BEM (Block, Element, Modifier) which is pretty awesome. When trying to modify a existing style it will look like:
.test{
width: 200px;
height: 200px;
background-color: red;
}
.test--warning{
background-color: yellow;
}
and your div will look like <div class="test test--warning">
You can twiddle the precedence of the class's selectors like this:
.test2[class*=test2]
{
...
}
This should make class test2 override other classes that have only class name selectors.
(sorry, this part is not correct)
If you want to lower test1's precedence, you could do it like this:
[class*=test1]
{
...
}
(I haven't tested this, you might need to name it *[class*=test1] instead)
I been researching for a long time and posted here because I couldn't find a good answer. thx to the answers and responses here I was able to find an article over the problem I'm facing here CSS howto
What I'm trying to do is not possible because of the order css in generated. What I wanted is my css to work between browser default and external or internal stylesheets. I will look for an alternative solution to my project.

How to override SASS style without duplicating CSS [duplicate]

This question already has answers here:
SCSS extend a nested selector and override the nested rulesets
(4 answers)
Closed 7 years ago.
I'm pretty new to SASS and I'm currently using a library written in SASS.
I would like to override not only variables from this library but also styles for a few bits. How can I override this style without duplicating CSS for that specific class ?
To be clear, let's say I have this class in my library which I import in my main.scss:
.twitter-foo {
float: none;
}
Now in my own file:
.twitter-foo {
float: a lot more;
}
Then my output is:
.twitter-foo {
float: none; // overriden!
}
.twitter-foo {
float: a lot more;
}
Well it works but it's dirty and I hate duplicating code, not mentioning the slightly longer page load. In case I would like to redefine .twitter-foo from my library, what can I do to avoid the bloated CSS ?
EDIT: I'm not talking about a middleware (minifier?) between SASS and CSS output but just SASS really.
What you could do is be more specific, meaning add more selectors so you can target .twitter-foo in different ways. Try giving your body tag a page id or your main element is what I usually do. So...
<body id="page1">
</body>
then in the scss you can:
#page1 .twitter-foo {
float:none;
}
OR
to override or not override add !important to the end of the style for example:
.twitter-foo {
float:none !important;
}
hope that helps.
Edit
As discussed Can the SASS minifier remove duplicate styles?
you may be able to compile your sass then run it through a css tidy which will remove duplicate classes and stuff or try out that ruby gem in the answers http://zmoazeni.github.io/csscss/.

CSS grouping :hover & :active

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
}
}

How to #extend from another sass file, or how to achieve OOSASS? [duplicate]

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;}.

removing item from many css selectors

I have a vague memory, but can't find anything on it, about being able to use a keyword "with" or "like" to do something similar to the following.
using .class1{
#a1, #a4{color:#ffffff;}
#a2{color:#dddddd;}
#a3{color:#eeeeee;}
}
instead of having to write:
.class1 #a1, .class #a4{color:#ffffff;}
.class2 #a2{color:#dddddd;}
.class3 #a3{color:#eeeeee;}
The issue is that I'm including some html/css in a page and the css is screwing up the rest of the page. So, I'd like to modify the css so it only affect the small portion, rather than the whole page. I'm doing all this programmatically on a large number of pages, so it'd be much easier to just wrap all of the new css in something like "using .class1" rather than parsing through the css and add .class1 to the beginning of every selector.
Any ideas? thanks!!
There is no way to achieve what you want unless you use some CSS preprocessor like SASS. Here's how it would look when done using SASS:
.class1 {
#a1, #a4 {
color: #ffffff;
}
#a2 {
color: #dddddd;
}
#a3 {
color: #eeeeee;
}
}
Reference: little link.
Wrap the block of included HTML in its own ID like #overRideCSS
Then if you ever need to over-ride specific styles, you can preface your selector with that ID:
#overRideCSS <other selectors> {etc...}

Resources