removing item from many css selectors - css

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

Related

How to use CSS custom variables for properties

My stylesheets have large amounts of styles declared, often with a lot of repeated values. I read about variables in CSS to solve that problem.
I tried to use them, but it is not working:
element {
--main-bg-color: brown;
}
body {
background-color: var --main-bg-color;
}
What am I doing wrong?
You did everything right, just keep the variables in (put variable here)
element {
--main-bg-color: brown;
}
body {
background-color: var(--main-bg-color);
}
var() notation works like a method
var(<custom-property-name>)
might consider putting your variables in a :root selector...
:root {
--main-bg-color: brown;
}
/* The rest of the CSS file */
body {
background-color: var(--main-bg-color);
}
:root is similar to global scope, but the element itself (ie body { --myvar: ... }) or ancestor elements (ie html { --myvar: ... }) can also be used to define variables
Refer to MDN reference page. A brief, to use custom variables you need to place them inside :root selector:
:root {
--main-bg-color: brown
}
In order to use it in another selector yo use var():
body {
background-color: var(--main-bg-color)
}
For me, the problem was that #charset "UTF-8"; was not the very first characters in the css file, and this messed up the :root{--my-variable: large }.
You need to add var(--my-variable) when using the variables.
But that's not something you should use CSS custom properties (variables) for.
Bear in mind some browser can't understand CSS variables, most noticeably IE. So using any pre-processor instead will be better for compatibility, as they are compiled to regular CSS values. Either SASS, LESS, POSTCSS... whatever floats your boat.
CSS custom properties are much more powerful than pre-processor ones, as they can be changed at runtime with javascript and be used in all sorts of awesome ways, but when you're using them as regular variables, pre-processor variables are always better for compatibility.
If you want to declare them globally, I would recommend to use it in:
* { --var : #colorName; }.
This has actually helped me in Angular application.

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

Conditional Sass Operation

Quick question-- in Sass, is it possible to get the content of an element, and based off of it, return a certain style?
For example:
<div class="number">5</div>
// CSS
.number {
color: red; //If content of .number > 5
color: blue; //If content of .number < 5
}
Sorry if this has been asked before, there are a ton of Sass/Conditional questions, and if so, I'll just delete this.
Since SASS actually has to be precompiled to be converted to CSS, which works without knowledge of what HTML will be used: No, this is not possible.
You will have to use Javascript or different semantic CSS classes.

LESS compiler magically adds unwanted classes to my selector

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.)

Sass Multiple Selector Refactoring

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

Resources