I thought that it was possible, but everyone tells me it's not.
I want context styling in my css file like:
div#foo {
h2 {
color: #F42
}
p.bar {
font-size: 12px
}
}
So that only h2 and p.bar in the div with id foo will be styled. Or is this only possible with LESS and other similar libs?
Thanks & kind regards,
Jurik
This is not possible with standard css, the 2 classes would need to be set like:
div#foo h2 {}
div#foo p.bar {}
This is not possible with pure CSS, that's why you should use SCSS or LESS (i suggest to use SASS/SCSS), which are CSS supersets
LESS/SASS-SCSS allows you to write dynamic CSS with ease, take a look at this comparision
check out COMPASS which is the main reason why I suggest you SASS/SCSS
It's possible, but as follows:
div#foo h2 {
/* styles go here */
}
div#foo p.bar {
/* styles go here */
}
What you have above is just a slightly altered version of:
div#foo h2 { color: #F42; }
div#foo p.bar { font-size: 12px }
I don't really see any gain to it.
Less let's you do pretty much what you described, as well as some other cool stuff like use variables in css etc.
Of course, once you let it compile, it'll just turn it into the valid CSS that has been suggested in the previous answers. Still worth a look IMHO.
yes but separated...
div#foo h2 {
color: #F42
}
div#foo p.bar {
font-size: 12px
}
but I would like too change a bit:
#foo h2 {
color: #F42
}
#foo p.bar {
font-size: 12px
}
you are using an ID so you don't need to say nothing before because ID's are unique
Its not possible using default CSS techniques.
But, by using sass and less however, it is possible.
The code in your question, works in both of the libraries above.
Related
I'm trying to slightly modify the styles of a block formatting plugin in Wordpress by overriding them in my own theme stylesheet. I use Sass but I'm new to it.
Pasting all of the selectors right out of Developer Tools works, but I know that's not the elegant/modular way to do it:
.an-accordion.an-accordion--v2.an-accordion.an-accordion--design-basic .an-accordion__heading {
color: gold
}
What's the right way to do this in Sass? I've tried something like this:
.an-accordion {
&--v2 {
&--design-basic {
&__heading {
color: gold;
}
}
}
}
but it doesn't work. I can tell I'm missing something about the way .an-accordion repeats.
You can use the power of local scoped string variables $something:... combined with the power of string interpolation #{...} and combine it with the current selector string & to create a compound selector for any combination of block, element, and modifier. Which I think is quite nice and readable:
.an-accordion {
$modifier-v2: #{&}--v2;
$modifier-design-basic: #{&}--design-basic;
$element-heading: #{&}__heading;
&#{$modifier-v2}#{$modifier-design-basic} {
#{$element-heading} {
color: gold;
}
}
}
which will result in:
.an-accordion.an-accordion--v2.an-accordion--design-basic .an-accordion__heading {
color: gold;
}
I tried it out on sassmeister.com
Note that I omitted the duplicated .an-accordion class in the selector; if this is important for you to increase the specifity you can insert it with #{&}.
BEM is about blocks, elements, and modifiers. Block scope is the biggest one, the element is some part inside the block and the modifier is optional and represents the status of your block-element. In Sass you can nest elements if they are parent and children and you don't need to repeat the parent element, in your stlesheet, if the beginning of your property is the same for both parent and child, but if the beginning is different you must repeat.
In a html like this:
<div class=" an-accordion an-accordion--v2 .an-accordion--design-basic .an-accordion__heading"></div>
You could have some scss code like this:
.an-accordion{
color: #000;
&__heading{
background-color: tomato;
}
&--v2{
font-weight: bold;
}
&--design-basic{
border: none;
}
}
With the LESS preprocessor, you can nest CSS code inside other CSS code, like this:
.Element {
.AnotherElement {
background-color: #FFF;
}
.YetAnotherElement {
background-color: #000;
}
}
This would make the background of .Element .AnotherElement white, and it makes .Element .YetAnotherElement have a background color of black. It does it all without writing it out like:
.Element .AnotherElement {
background-color: #FFF;
}
.Element .YetAnotherElement {
background-color: #000;
}
Does the first example coincide with CSS syntax, or do I have to use the LESS preprocessor?
Nesting is a feature of LESS and SASS, not native to CSS.
This is one of the most common uses for CSS preprocessors, but they offer a lot more too.
No, css doesn't support this syntax, in your css example the "Element" and "AnotherElement" will to receive this properties, AnotherElement will not inherit properties of Element.
does anybody know a way or a tool how inheritance can be used in CSS independent of the structure of the elements?
Example:
.bg_red {
background: red;
}
.bold {
font-weight: bold;
}
.bg_red_and_bold {
//this class should inherit all the properties of the above two classes
}
I hope it is clear what I mean...
Thanks
There is no way you can do that in CSS, but since you are looking for tools as well, you might look into CSS preprocessing:
LESS
SASS
Their mixin and #extend features should do what you are looking for.
ability to add multiple classes to element is there for exactly that reason.
<div class="bg_red bold">The red and bold text</div>
There is no such thing in CSS. Only thing you can do is:
.bg_red, .bg_red_and_bold {
background: red;
}
.bold, .bg_red_and_bold {
font-weight: bold;
}
CSS does not support this.
Consider using LESS, which compiles to CSS and supports mixins:
.bg_red_and_bold {
.bg_red();
.bold();
}
Probably not what you want but there is aggregation:
<div class="bg_red bold"...
The div will "inherit" characteristics of both styles.
I have an extremely messy stylesheet that I'm trying to clean up, and one thing I've searched for an answer to is how to clean an example of this up:
.element .Change {
font-size: 1em;
}
.element .Name {
font-size: 1em;
}
can this be re-written in a cleaner way? ex:
.element .Change, .Name {
font-size: 1em;
}
I should probably know this, but when I search for putting CSS on one line, I get examples of single-line CSS.
Thanks for your help
Yes, almost exactly as you propose.
.element .Change,
.element .Name {
font-size: 1em;
}
.element .Change, .element .Name {
font-size: 1em;
}
CSS redundancy is not all the bad, as you need to keep some buffer for future changes.
If you're sure that your styling won't change, then what you have done is perfectly fine.
I'd advise you to have a look at LESS and other similar compile-to-CSS languages.
I've been educating myself. Reading this:
The engine evaluates each rule from right to left, starting from the rightmost selector (called the "key") and moving through each selector until it finds a match or discards the rule. (The "selector" is the document element to which the rule should apply.)
For example:
ul li a {...}
#footer h3 {...}
* html #atticPromo ul li a {...]
Now, some example code SASS outputs for me:
#content #blog {
/* ... */
}
/* line 85, ../sass/screen.scss */
#content #flickr {
/* ... */
}
#content #flickr div p {
/* ... */
}
This seems a bit awkward.. am I doing something wrong? Is this a communication problem between me and Sass? Are we losing it?
Edit:
Some SCSS code:
#flickr {
#include columns(5,8);
background: url('../img/ipadbg.png') no-repeat;
#ipod-gloss {
z-index: 999;
position: relative;
}
div {
margin-top: -80px;
margin-right: 20px;
h2 {
color: $white;
font-size: 24px;
}
p {
margin-top: 40px;
}
}
}
Side Bonus!: The article says browsers (or at least Firefox) search the selectors from right to left. I couldn't understand why this is a more efficient why. Any clues?
You have to find your compromise between maintainability (nesting makes it easier to find your way around in the stylesheet) and rendering performance.
A rule of thumb says you should try to restrict yourself to a three-level nesting and you should avoid to nest IDs if it's not necessary.
However, I think nesting too much is not the biggest issue. As soon as I became aware of the power of mixins, I used them a lot.
For example, this is my often used button mixin:
#mixin small-button($active-color: $active-color, $hover-color: $button-hover-color, $shadow: true)
display: inline-block
padding: 4px 10px
margin:
right: 10px
bottom: 10px
border: none
background-color: $button-color
color: $font-color-inv
+sans-serif-font(9px, 700)
text-align: center
text-transform: uppercase
cursor: pointer
#if $shadow
+light-shadow
&:hover
text-decoration: none
background-color: $hover-color
&:last-child
margin-right: 0
a
color: $font-color-inv
&, &:hover
text-decoration: none
&.disabled
+opacity(0.75)
&:hover
background-color: $button-color
&.active
background-color: $active-color
&.disabled:hover
background-color: $active-color
You see, quite a bit code. Applying such mixins to many elements on your page will result in a big CSS file which takes longer to be interpreted.
In the old fashioned CSS-way you would give each button element e.g. the class .small-button. But this method pollutes your markup with unsemantic classes.
Sass provides a solution though: selector inheritance via the #extend directive.
If you set defaults for your parameter of the mixin, you can also provide a simple class, which uses the mixins with your default:
// Use this mixin via #extend if you are fine with the parameter defaults
.small-button
+small-button
And then you can just inherit from this class in various contexts:
#admin-interface
input[type=submit]
#extend .small-button
The resulting CSS statement aggregates all usages of .small button into one rule with comma-separated selectors:
.small-button, #admin-interface input[type=submit] {
display: inline-block;
...
}
Concluding, a naive usage of Sass can effect your CSS performance. Used wisely, however, it is maintainable thanks to well-structured and DRY code, it leads to proper separation of markup and styling (semantic classes only) and allows for smart and performant CSS code.
SASS is only a language that compiles down to CSS. If you're concerned with SASS' performance in terms of how it runs in the browser, then SASS doesn't enter the equation -- it'll be compiled and served to the browser as regular CSS.
From what I can see of your usage of SASS, there's a couple of things I could suggest:
You don't have to nest everything.
The ability to nest rules inside each-other in SASS is a language feature, but you don't have to do it if it doesn't make sense to do so.
In terms of your general CSS usage:
If the nesting gets too severe/unwieldly, consider using classes where it makes sense.
When it's necessary to use the hierarchy of DOM elements, consider using the [child combinator]: .foo > .bar.
IDs are meant to be unique, thus should always only reference a single element. Most of the time, they can be CSS rules unto themselves -- #content #flickr would become just #flickr, for instance -- and browsers will optimise the lookup for a single ID. The only time you would need something like #id1 #id2 is if #id2 needs to appear in different contexts on different pages.
If your selector contains things like #id div p, that div is either superfluous or serving a specific purpose.
If it's superfluous, change the rule to #id p, which selects any <p> that occurs as a descendant of #id.
If it serves a specific purpose, consider classing the <div> with a class name that describes its purpose -- perhaps <div class="photos-list">. Then your CSS could become .photos-list p, which is far more maintainable and reusable.