This is in particular reference to the Compass spriting framework
Following the documentation here http://compass-style.org/help/tutorials/spriting/#magic-selectors
I have used this method so that this:
selectors/ten-by-ten.png
selectors/ten-by-ten_hover.png
.edit {
#include selectors-sprite(ten-by-ten);
}
generates:
.selectors-sprite, .edit {
background: url('/selectors-sedfef809e2.png') no-repeat;
}
.edit {
background-position: 0 0;
}
.edit:hover, .edit.ten-by-ten_hover, .edit.ten-by-ten-hover {
background-position: 0 -20px;
}
which is really great. However, I was wondering If/How in another instance I could include the "ten-by-ten.png" image from the sprite without including the magically attached hover state?
i.e.
I want this:
.view {
background: url('selectors/ten-by-ten.png') no-repeat;
}
Where hovering over this icon does not trigger the :hover state (ten-by-ten_hover.png).
But I was wondering if there was a way to achieve this still referencing the sprited image?
Thanks for any help/advice.
You can add sprites directly to an element using the #extend directive. The syntax is #extend .folder prefix - sprite name - state (ie, .selectors-sprite-name_hover):
.view {
#extend .selectors-ten-by-ten
}
&:hover {
#extend .selectors-ten-by-ten_hover
}
&:active {
#extend .selectors-ten-by-ten_active
}
.selectors-ten-by-ten_hover, .selectors-ten-by-ten_active, etc returned class not found errors for me in Compass.
This worked however:
.viewHover { #extend .selectors-ten-by-ten:hover; }
.viewActive { #extend .selectors-ten-by-ten:active; }
Related
I have used scss variables in all of my code, like this:
$primary: royalblue;
body {
background: $primary;
color: black;
}
.list-item {
// some code
span, a {
background: black;
color: $primary;
}
}
now, I want to create an animation for body background color:
#keyframes bganimation {
from {
$primary: royalblue;
}
to {
$primary: tomato;
}
}
but I know scss is a language that compiles to css... is there any other way to do that?
I can't rewrite the code, help please.
I guess you first have to understand how SCSS Variables actually work:
When compiling SCSS to CSS the variables are replaced with the actual current value of the variable so in the end there won't be any variables anymore.
That said your keyframes block will simply be an empty block in the end.
If you want to have real variables, you would have to use actual CSS Variables
--some-variable: red;
(Notice that this won't work out of the box in "browsers" like IE)
There are more things you should fix in your code:
- There is no animation set for any of the elements (via animation attribute)
- In the keyframes block you have to define which attribute should animate and what value they should take while animation
eg:
#keyframes bganimation {
from {
background-color: red;
}
to {
background-color: blue;
}
}
So you would have to rewrite the code at least a bit for it to work.
You have to animate the background-color property, so it should be:
#keyframes bganimation {
from {
background-color: $primary;
}
to {
background-color: tomato;
}
}
I'm searching a way to use a particular color depending on a class on the body tag.
I have a main scss file like this
// variables.scss
$bg-main: white;
$color-first: red;
$color-second: green;
And in my other files, I use the colors
// content.scss
.content {
.some-selector: {
// some styles
color: $color-second;
}
a:hover {
// some styles
color: $color-second;
}
}
// and same goes for menu.scss etc.
Now I have a dynamic class on the body, that changes depending on the current selected menu. I would like $color-second to be different for each body classes, and I don't know how to do that. The only solution I found was to move all the $color-second from each files into one single file, like this:
.body-1 {
.content a:hover, .content .some-selector {
color: green;
}
}
.body-2 {
.content a:hover, .content .some-selector {
color: blue;
}
}
.body-1 {
.content a:hover, .content .some-selector {
color: black;
}
}
So I don't need to write the color in each files. This works well, but if I need to set this $color-second to some other selector, I need to put that in this big file.
Is this possible to do this an other way?
I already checked these answers, but it didn't helped me much:
SASS set variable depending on CSS class
Creating or referencing variables dynamically in Sass
Merge string and variable to a variable with SASS
There are multiple ways to do this. The most obvious two which come to mind are mixins and loops:
Mixins
Just put everything you want into a single mixin, and then use it for every body class:
#mixin colored-content($color) {
.content a:hover, .content .some-selector {
color: $color;
}
/* Any other rules which use $color here */
}
.body-1 {
#include colored-content(green);
}
.body-2 {
#include colored-content('#FF0000');
}
.body-3 {
#include colored-content(darken(red, 20));
}
You can extend this example with any number of arguments (for example, $textColor and $bgColor), conditions or rules.
With this approach you will not have SCSS code repetitions, and any updates will be introduced easily.
Loop
Another way is to use a simple loop:
$body_themes: (
"body-1": green,
"body-2": #FF0000,
"body-3": darken(red, 2)
);
#each $body_class, $color in $body_themes {
.#{$body_class} {
.content a:hover, .content .some-selector {
color: $color;
}
/* Any other rules which use $color here */
}
}
It is even shorter, but imho it is less readable.
P.S. It is possible to combine mixins and loops, by the way :)
I want to add scope to my selectors.
A good way to achieve it in my opinion is to select css selector and return mySelector + oldSelector
For example I have .old { background: black; }, I would transform it into .mySelector .old { background: black; }
Let's say I have this CSS
.a
{
background: red;
}
#b {
background: green;
}
input {
background: blue;
}
[type=custom] {
background: white;
}
I would do .+?{, but it selects not needed parts. Inverse of {.+?} would work, but I don't know how to inverse it. Any ideas ?
I figured out I can use String.match({.+?}) to get all rules and String.split({.+?}) to get selectors in JavaScript.
Also I've found a library to easily parse CSS in JavaScript https://github.com/reworkcss/css
I have this simplified Less script
.placeholder(#color: #333333) {
&::-webkit-input-placeholder { color: #color; }
}
input {
.placeholder();
}
.placeholder {
margin-top: 20px;
}
The output when I run this through my local compiler or winless online less compiler is
input {
margin-top: 20px;
}
input::-webkit-input-placeholder {
color: #333333;
}
.placeholder {
margin-top: 20px;
}
Insted of the desired output
input::-webkit-input-placeholder {
color: #333333;
}
.placeholder {
margin-top: 20px;
}
Is this a bug or am I missing something here?
By the result it looks to me like I can't have CSS-selectors with the same name as mixins with default values.
I'm running into this problem when compiling Bootstrap with my site specific code. In this particular case I can work around it, but as the project grows and I include other projects I can't imaging I have to keep track of any mixins with default values?
Edit: I see now that I should have read the manual and pretty much seen on the first page of the docs that everything can be treated as a mixin.
In Less, everything is technically a mixin irrespective of whether we write it with parantheses (as in with parameters) or without parantheses (as in like a CSS class selector). The only difference between the two is that when the parantheses are present, the properties present within it are not output unless called from within a selector block.
Quoting the Less Website:
It is legal to define multiple mixins with the same name and number of parameters. Less will use properties of all that can apply.
In this case, since the other mixin has a default value for its only parameter, both the properties can apply when called without any parameter and hence there is no way to avoid it from happening.
Workaround Solution: One possible solution to work-around this problem is to enclose all such conflicting rules within a parent selector (like body).
.placeholder(#color: #333333) {
&::-webkit-input-placeholder { color: #color; }
}
input {
.placeholder();
}
body{
.placeholder{
margin-top: 20px;
}
}
Compiled CSS:
input::-webkit-input-placeholder {
color: #333333;
}
body .placeholder {
margin-top: 20px;
}
Option 2: Extracted from the solution posted by seven-phases-max in the Less GitHub Issue thread.
For the particular use-case one of possible workarounds is to isolate conflicting classes in unnamed scope so they won't interfere with external names:
.placeholder(#color: #333333) {
&::-webkit-input-placeholder { color: #color; }
}
input {
.placeholder();
}
& { // unnamed namespace
.placeholder {
background: #ffffff;
}
} // ~ end of unnamed namespace
Note: The above is a straight copy/paste from the GitHub thread without any modifications so as to not tamper with the information.
#mixin placeholder(#color: #333333) {
&::-webkit-input-placeholder { color: #color; }
}
input {
#include placeholder();
}
.placeholder {
margin-top: 20px;
}
that should work.
So if i understood right, you just want to add 20px on top of the placeholder ? Add padding-top to input instead.
input {
padding-top: 20px;
}
I am using SASS and there is nice feature: I can create "fake/virtual" class and then use it for extend.
Example:
%myFakeClass
{
color:#fff;
background-color:#000;
}
.myRealClass
{
#extend %myFakeClass;
}
.myRealClass2
{
#extend %myFakeClass;
}
Output:
.myRealClass, .myRealClass2
{
color:#fff;
background-color:#000;
}
The question:
Does LESS has something similar? In other words, I want to create a "virtual class" that I can inherit from, but the "virtual class" itself not exists in output.
Not Directly as of Yet
As of this date (11-22-2013) there is still a feature request that would allow this by doing extending on empty parameter mixins (which do not output css themselves). So eventually something like this would be possible (which mirrors almost exactly what you want):
.myFakeClass() {
color:#fff;
background-color:#000;
}
.myRealClass {
&:extend(.myFakeClass);
}
.myRealClass2 {
&:extend(.myFakeClass);
}
And output as you expect.
Workaround for now
This was mentioned by Bass Jobsen, but not explicitly demonstrated. In LESS 1.5, you build a file for your fake classes, say fakeClasses.less, which for our example has this in it:
.myFakeClass {
color:#fff;
background-color:#000;
}
Then in your file that you want to extend to it, let's say styles.less, you do this:
#import (reference) fakeClasses.less;
.myRealClass {
&:extend(.myFakeClass);
}
.myRealClass2 {
&:extend(.myFakeClass);
}
This will import the fakeClasses.less classes but NOT compile them to css (so they are "fake" within the context of styles.less, but "real" in that they can be extended to), and you will get the output you expect.
.myRealClass, .myRealClass2 {
color:#fff;
background-color:#000;
}
Maybe the following helps you img { &:extend(.img-responsive); } from Why gives Grunt / Recess an error and Lessc not when compiling Bootstrap 3 RC1?
update from How do I create a mixin using less.js that doesn't output in the final stylesheet:
.myFakeClass()
{
color:#fff;
background-color:#000;
}
.myRealClass, .myRealClass2
{
.myFakeClass();
}
since LESS 1.5 you could also place you virtual classes in a separate file and use:
#import (reference) "file.less";
We have another import option - reference. This means that any
variables or mixins or selectors will be imported, but never output.
I'm not entirely sure if #extend works the same as a "mixin", but it looks the same.
.myFakeClass(#textColor: #fff, #bgColor: #000 )
{
color:#textColor;
background-color:#bgColor;
}
.myRealClass
{
.myFakeClass();
}
.myRealClass2
{
.myFakeClass();
}
The out put for this would be the same as what you have above. I added variables in the mixin for easier customization for this mixin.
Example:
.myRealClass3
{
.myFakeClass(#369, #00f);
}
The output for all three classes would be:
.myRealClass, .myRealClass2
{
color:#fff;
background-color:#000;
}
.myRealClass3
{
color:#369;
background-color:#00f;
}
Like I said, I'm not entirely sure if there is a big difference between extending a class in SASS and using a mixin in LESS. Hope this helps either way.
Oh, and just to clarify, if the .myFakeClass() class is in a separate .less file that is imported, it will not show up in your CSS unless it is used. I tested this on a website I'm building. I have:
.box-shadow(#a, #b, etc..) {
box-shadow: #a #b etc..;
-webkit-box-shadow: #a #b etc..;
etc: #a...;
}
The class .box-shadow does not show up in my CSS at all.
Link: http://lucienconsulting.com/gs-news/wp-content/themes/TheStone/css/style.css
However, if you write a mixin like this:
.myMixin{
background: #000;
color: #fff;
}
It will show up like a normal class even if not used. Obviously, it looks just like a normal class and could be used by itself, or as a mixin, like so:
.myClass{
.myMixin;
border: 1px solid #fff;
}
This would compile to:
.myClass{
background: #000;
color: #fff;
border: 1px solid #fff;
}
It works, but .myMixin would also show up in your style sheet in this case.
But, like I said, in my original example, it would not.