CSS 'lookbehind' using sass / less - css

I am currently using sass to help structure my CSS. A trivial given below.
.container {
.list {
.selected {
background-image : url('highlighted.png');
}
}
}
However I am also using modernizr (http://modernizr.com/docs/) and want to utilise CSS3 where possible. In this example I want to test for availability of border-radius , and use border-radius rather than a background image. Therefore I need to check for the presence of borderradius class on the html element. Is it possible to achieve this using some sort of look behind? Or do I have to repeat the code again with the .borderradius class, the end result being the following :
.container {
.list {
.selected {
background-image : url('highlighted.png');
}
}
}
.borderradius .container {
.list {
.selected {
background : yellow;
border-radius : 10px;
}
}
}
To me this looks messy and difficult to maintain in a large project. Does anyone have a more elegant ways of achieving this?

You can reference parent selectors using the ampersand (&), like this:
.container {
.list {
.selected {
background-image : url('highlighted.png');
.borderradius & {
background : yellow;
border-radius : 10px;
}
}
}
}
Which will compile to:
.container .list .selected {
background-image : url('highlighted.png');
}
.borderradius .container .list .selected {
background : yellow;
border-radius : 10px;
}
Check out this article, or this one for a more in-depth explanation of how useful this can be:
...you can place a trailing ampersand (&) character at the end of your selector declaration in place of the repeating selector, and sit back and enjoy the awesomeness of Sass

Related

Change pseudo-element style based on grandparent class

Consider the following scss:
.link {
....
span {
....
&:after {
....
.link.active & {
background-color: red;
}
.link:hover & {
background-color: red;
}
I want to change the background-color for the span :after pseudo-element when link is either being hovered or has the .active class.
What I've tried ( the code posted above ) doesnt seem to work.
Is there anything I'm missing ?
you should try it like this scheme :
.link {
span {
&:after {
...
}
}
&.active,
&:hover {
span:after {
background-color: red;
}
}
}
Working example : http://jsfiddle.net/92gqap5y/
This question seems to be asked often, as mentioned in this thread.
They increase the size of the link element to be as large as the span. Though I would recommend moving the :hover selector and .active class to the span element directly.

Less cascading & refactoring

I am trying to refactor some css looking like this:
path.myClass {
//some CSS
}
.someOtherClass.myClass {
//some other CSS
}
I am struggling to find the right syntax for the first part. I am trying to have something looking like this:
.myClass {
path.& {
// some CSS
}
.someOtherClass {
// some other CSS
}
}
How can I refactor this correctly?
You can do it like below. Since the top level selector already has . there is no need to add it again before the parent selector (&) in the inner selector. The second one is fairly straightforward as you can append the parent selector either at the start or at the end. The order of classes doesn't matter.
(Note: There should be no space before the parent selector as it would change the meaning.)
.myClass {
path&{
color: red;
}
.someOtherClass& { /* can do &.someOtherClass also, order doesn't matter */
color: blue;
}
}
Below is the compiled CSS output:
path.myClass {
color: red;
}
.someOtherClass.myClass {
color: blue;
}

Sass back nesting issue

I'm trying to figure out how to back nest specifically to the parent of the css nest I'm in. Meaning, my current set up is a parent class to a span to a before pseudo. I need to change a style on the pseudo based on a modifier on the parent. If I do this:
.parent {
span {
&:before {
// styles
.modifier & {
// Other styles
}
}
}
}
The output is .modifier .parent span:before What I need is .parent.modifier span:before
Isn't there a way to do this without adding the modifier to the parent and pathing to the pseudo again? This is what I want to avoid.
.parent {
span {
&:before {
// styles
}
}
&.modifier {
span {
&:before {
// Other Styles
}
}
}
}
This is certainly possible, it does require the use of some of the less known sass functions #at-root, & ampersand and string interpolation #{}.
Basically it works in the following manner;
Use #at-root to jump outside of the class, to the 'root'.
We place our class after that, I've used .--modifer-is-red.
We attach the classes that we jumped outside of by using interpolation of the &, #{&}.
Live Example
Example used for clarity
.parent {
span {
&:before {
// styles
color: black;
// Modifiers attached to the parent
#at-root .--modifier-is-red#{&} {
color: red;
}
}
}
}
// output
// .--modifier-is-red.parent span:before {
// color: red;
// }
Exact example to reflect your code
.parent {
span {
&:before {
// styles
#at-root .modifier#{&} {
// Other styles
}
}
}
}
There is some limitations to this, also it does look slightly odd that the modifier is placed before the parent in the output, but the browser doesn't mind.
I hope this solves your problem.
Isn't there a way to do this without adding the modifier to the parent and pathing to the pseudo again?
No, because you only have the & variable to work with, which is always a single unit consisting of the entire complex selector. You can't specify where exactly in the middle of the complex selector you want your modifier to go. The best you can do is attach it as a compound selector or use it with a combinator.

LESS CSS naming convention - Child selectors on hover

In LESS, you can reference a child selector as follows:
<div class="button">
<div class="button-text"> Text </div>
</div>
.button {
&-text {
color:red;
}
}
This will output:
.button .button-text { color:red; }
This is neat and ideal, however, when using a hover, is there a way to maintain the same / similar syntax for the child element? Currently, this wouldn't naturally work:
.button {
&:hover {
&-text {
color:red;
}
}
}
This won't work and as expected, outputs something along the lines of
.button:hover .hover-text { }
Is there a way to get the expected hover result without defining the full class name, in this instance ".button-text"?
Any help would be greatly appreciated.
Because the parents selector & represents all parent selectors (not just the nearest ancestor), nesting under hover, will always include the :hover text.
This rule:
.button {
&:hover &-text {
color:red;
}
}
Will provide the result (lessismore playgroud):
.button:hover .button-text {
color: red;
}

Apply a style on element A if element B contains a certain class

Is it possible to check the class of an element, see if it exists, and then apply the style for another class?
Example pseudo code:
if (.myClass .myBlock == true) {
.otherClass {
display:none
}
}
It's not possible in this context. But you can achieve a similar result with the cascading nature of CSS.
Apply a class to the body of your website:
.another-class {
display: none; // hides .another-class by default
}
body.special-class {
.another-class {
display: block; // shows if the body contains .special-class
}
}
Since the specificity of the generated output is higher at the second rule, the elements with .another-class will be visible.
Give the following row a class
Utilising the + selector enables us to display the row after the mentioned class. This way we can style dropdowns popups, given we have the following HTML:
.popup {
display: none;
}
.popup:hover {
display: block;
}
.container:hover + .popup {
display: block;
}
<div class="container">Hover me!</div>
<div class="popup">This is a popup!</div>
I'm afraid that's all that is possible with CSS.

Resources