SCSS multiple properties in mixin - css

Take a look at the following example:
#mixin placeholder ($color) {
&.-moz-placeholder {
color: $color;
}
&:-ms-placeholder {
color: $color;
}
}
#include placeholder(#999);
But instead I want to insert multiple properties not just the color in the placeholder style. Like this:
#mixin placeholder ($properties) {
&.-moz-placeholder {
$properties;
}
&:-ms-placeholder {
$properties;
}
}
#include placeholder(color: #999, text-shadow: 1px 0px 0px #000);
Is this possible, and if so how?

As #dave suggests, you can accomplish this using Sass's #content directive. Here's what your example would look like using that syntax:
#mixin placeholder {
&.-moz-placeholder {
#content;
}
&:-ms-placeholder {
#content;
}
}
#include placeholder {
color: #999;
text-shadow: 1px 0px 0px #000;
};
Note that to pass a content block, you use curly braces rather than parentheses. You can read more in the SASS documentation.

Are you looking for "Passing Content Blocks to a Mixin"?
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content

Related

CSS: Can you refer to a class within a class?

Let's say I have this class:
.dark-theme {
background-color: black;
}
Can I refer to it within my css file? Something like ...
.some-class {
dark-theme;
padding: 5px;
}
a {
dark-theme;
color: white;
}
I have two solutions to accomplish this.
Solution 1:
Use css variables.
(Not really doing what you asked for but good to know if you're not using any preprocessors)
:root {
--color-bg-dark: black;
}
.some-class {
background-color: var(--color-bg-dark);
}
Solution 2:
Use sass which is a css preprocessor and put your reusable rules in a mixin.
#mixin applyDarkTheme {
background-color: black;
color: white;
// Some other rules
}
.some-class {
#include applyDarkTheme;
}

CSS placeholder attribute: How to set it's width in Chrome

https://codepen.io/stoplion/pen/bWoPLP
I've tried a number of ways to get this placeholder's background to not look like a display block (setting it's position to absolute, setting it's width) but nothing seems to work.
Any idea how to make the background 'hug' the text as it would in an inline element?
#mixin optional-at-root($sel) {
#at-root #{if(not &, $sel, selector-append(&, $sel))} {
#content;
}
}
#mixin placeholder {
#include optional-at-root('::-webkit-input-placeholder') {
#content;
}
#include optional-at-root(':-moz-placeholder') {
#content;
}
#include optional-at-root('::-moz-placeholder') {
#content;
}
#include optional-at-root(':-ms-input-placeholder') {
#content;
}
}
input {
padding: 10px;
width: 400px;
}
input {
#include placeholder {
transform: translateX(-9px);
background-color: rgba(29, 146, 237, 0.15);
padding: 5px 5px;
color: #333;
float: left;
width: 20px;
}
}
Edit
Inspecting the shadow dom element.. the input::-webkit-input-placeholder appears to get a display: block !important;
Better question is..
How to change the -webkit-input-placeholder to an inline element?
Removing the transform: translateX(-9px); line makes the input text and background line up flush with the cursor.
https://codepen.io/anon/pen/oWGrad
Removing the padding could take out the whitespace as needed too.
Increase your specificity. try label + input {
https://codepen.io/anon/pen/JNrgjZ

#content VS normal additional rules

What is the difference between doing:
#mixin test($color: #000) {
border: 1px solid red;
color: $color;
}
#mixin extension($color: #000) {
#include test($color);
background-color: #eee;
}
or doing the following?
#mixin test($color: #000) {
border: 1px solid red;
color: $color;
#content
}
#mixin extension($color: #000) {
#include test($color) {
background-color: #eee;
}
}
is there any difference in the resulting CSS?
I cannot see the convenience of the #content directive.
The #content directive allows you to have a selector inside of your mixin and inject specific styles within that selector. The most common use case is a media query:
#mixin bp($i) {
#media (min-width: $i) {
#content;
}
}
.foo {
color: red;
#include bp(30em) {
color: green;
}
}
Other popular uses include abstracting keyframes declarations, placeholder selectors, or other selectors that require prefixes.

Creating a mixin for color themes with SASS

I would like to create various themes in my project (I work with SASS 3.2) :
I defined a variable:
$themeName: Z;
I tried to create a mixin like :
#mixin theme($themeName) {
#if $themeName == Z {
#content;
}
#if $themeName == Y {
#content;
}
}
To be able to use like that:
.wrapper {
#include theme(Y) {
border-top: 5px solid blue;
}
#include theme(Z) {
border-top: 10px solid red;
}
}
But in my CSS file, I have something like that :
.wrapper {
border-top: 10px solid red;
border-top: 5px solid blue;
}
I'll appreciate a lot some help, I spend hours trying to find a solution to easily develop various themes for my platform.
You are calling mixin two times, each time for a different theme. Mixin remaining unchanged, try this:
$currentTheme: Z;
.wrapper {
#include theme($currentTheme) {
border-top: 10px solid red;
}
}
And alter $currentTheme at the beginning of .scss file to which theme you are currently using (Y, Z, A, B, X...), meaning: which theme do you want to see in generated .css file.
EDIT: Thanks for clearing everything up in the comment, now the solution:
$currentTheme: "Z";
#mixin isTheme($theme) {
#if $theme == $currentTheme {
#content;
}
}
.wrapper {
#include isTheme("Z") {
border-top: 10px solid green;
}
#include isTheme("Y") {
border-top: 10px solid blue;
}
}
Just change $currentTheme variable as you see fit (in this case to "Y", just to see that it actually works).

CSS LESS Placeholder Mixin

I want to create a placeholder mixin as follows. However, this fails to compile in LESS version 1.7.0.
.placeholder(...) {
::-webkit-input-placeholder: #arguments;
:-moz-placeholder: #arguments;
::-moz-placeholder: #arguments;
:-ms-input-placeholder: #arguments;
}
Mixin allows for any placeholder css rules.
.placeholder(#rules) {
&::-webkit-input-placeholder {
#rules();
}
&:-moz-placeholder {
#rules();
}
&::-moz-placeholder {
#rules();
}
&:-ms-input-placeholder {
#rules();
}
}
Example usage:
.placeholder({
color: #0000FF;
text-transform: uppercase;
});
Input placeholders are selectors, not properties, and so their CSS syntax is placeholder { ... }, not placeholder: ... which you are trying to generate.
If you fix that:
.placeholder(...) {
::-webkit-input-placeholder {border:#arguments}
::-moz-placeholder {border:#arguments}
:-ms-input-placeholder {border:#arguments}
}
It will compile, and when you call it:
.placeholder(solid; 1px; blue;);
it will generate this CSS:
::-webkit-input-placeholder {
border: solid 1px #0000ff;
}
::-moz-placeholder {
border: solid 1px #0000ff;
}
:-ms-input-placeholder {
border: solid 1px #0000ff;
}
(I just included border: as an example of a generic CSS property, independent of its actual effect on an input object)
You are missing the curly brackets around the placeholder selectors.
The styles should be as follows:
.placeholder(#color) {
::-webkit-input-placeholder {
color: #color;
}
:-moz-placeholder {
color: #color;
}
::-moz-placeholder {
color: #color;
}
}

Resources