CSS LESS Placeholder Mixin - css

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

Related

How to disable SCSS property by overwriting it?

How could I disable background-color in .button.search so it would fallback to $red value? I can't remove it; I can only overwrite it.
I have
.button {
background-color: {$red};
}
and
.button.search {
background-color: #000;
}
Don't need for any additional setting in search.
.button {
background-color: $red;
}
.button.search {
/* no background-color setting would fallback to $red*/
}
I would do it like this so you can extend the style from .search and it will always fallback with whatever you define and incase you want to have new value for the .active class you can just write background-color: green; after #extend .search;
.search {
background-color: red;
&.active {
#extend .search;
// background-color: green;
}
}
result will be like that
.search, .search.active {
background-color: red;
}
and if you will do that
.search {
background-color: red;
&.active {
#extend .search;
background-color: green;
}
}
and result will be like that
.search, .search.active {
background-color: red;
}
.search.active {
background-color: green;
}

Copy styles to other class in SCSS without #extend?

I'm trying to create a helper mixin in my SCSS file for easily styling form input placeholder texts. For a while, I only needed to change the text's color, so I had this mixin:
#mixin input-placeholder($color, $opacity, $focusColor: null, $focusOpacity: null) {
&:-moz-placeholder {
color: $color;
opacity: $opacity;
}
&::-moz-placeholder {
color: $color;
opacity: $opacity;
}
&:-ms-input-placeholder {
color: $color;
opacity: $opacity;
}
&::-webkit-input-placeholder {
color: $color;
opacity: $opacity;
}
&:placeholder {
color: $color;
opacity: $opacity;
}
&:invalid {
color: $color;
}
&:focus {
#if($focusColor==null) {
$focusColor: transparent;
}
#if($focusOpacity==null) {
$focusOpacity: 0;
}
&::-webkit-input-placeholder {
color: $focusColor !important;
opacity: $focusOpacity !important;
}
&:-moz-placeholder {
color: $focusColor !important;
opacity: $focusOpacity !important;
}
&::-moz-placeholder {
color: $focusColor !important;
opacity: $focusOpacity !important;
}
&:-ms-input-placeholder {
color: $focusColor !important;
opacity: $focusOpacity !important;
}
&::-webkit-input-placeholder {
color: $focusColor !important;
opacity: $focusOpacity !important;
}
&:placeholder {
color: $focusColor !important;
opacity: $focusOpacity !important;
}
}
}
This purposely adds each selector separately and not in a comma separated list due to the fact that some browsers will ignore the entire entry if one is invalid.
I wanted to use #extend so that I could create a mixin like this:
#mixin style-input-placeholder($module) {
&:-moz-placeholder {
#extend #{$module};
}
&::-moz-placeholder {
#extend #{$module};
}
&:-ms-input-placeholder {
#extend #{$module};
}
&::-webkit-input-placeholder {
#extend #{$module};
}
&:placeholder {
#extend #{$module};
}
&:invalid {
#extend #{$module};
}
}
Where $module is the selector I pass to the mixin to extend the styles of, and I'd be able to use it like this:
.some-special-placeholder-styles {
color: purple;
opacity: 0;
text-transform: uppercase;
font-family: 'Open Sans', Arial, sans-serif;
}
input {
#include style-input-placeholder('.some-special-placeholder-styles');
}
It would allow me to modify more than just the color and opacity without having to annoyingly specify each attribute as a mixin parameter. But because of the nature of #extend, it combines all of those selectors into one comma separated list. So is there something else I can do or any workarounds that you've come across?
You can use #content directive to pass arbitrary content inside mixins (was added into sass 3.2). So your code may look like:
#mixin style-input-placeholder() {
&:-moz-placeholder {
#content;
}
&::-moz-placeholder {
#content;
}
&:-ms-input-placeholder {
#content;
}
&::-webkit-input-placeholder {
#content;
}
&:placeholder {
#content;
}
&:invalid {
#content;
}
}
input {
#include style-input-placeholder() {
color: purple;
opacity: 0;
text-transform: uppercase;
font-family: 'Open Sans', Arial, sans-serif;
}
}
Also you can try to wire your sass compilation with PostCSS and use excellent Autoprefixer plugin that will free you from defining all these vendor-specific prefixes.

Passing an extend as a mixin argument in SASS [duplicate]

My idea is that I would like to write silent classes for input[type=text], input[type="password"] and input[type=submit]. I would then #extend them in a mixin by passing hem through as a variable.
My parser is throwing this error;
Syntax error: Invalid CSS after " #extend ": expected selector_sequence, was "$type;"
Here is my code;
%text {
(text styling)
}
%password {
#extend %text;
}
%submit {
padding: .5em;
background-color: $button-color;
border: none;
cursor: pointer;
color: white;
border: 1px solid darken($button-color, 20%);
&:hover {
#include transition;
background-color: darken($button-color, 10%);
}
}
#mixin input($type) {
margin-bottom: 1.5em;
margin-left: 0;
outline: none;
#extend $type;
}
Any help would be appreciated
try using variables interpolation
#extend #{$type};
Further information on SASS Reference
While Fabrizio's answer is formally correct, consider not going that way.
There's a great rule in programming of any kind: "keep it simple, stupid!" aka KISS.
Though SASS provides such advanced facilities as extends and mixins, it doesn't mean that you should use them as much as possible. Don't make your code complicated when you don't have to!
This code does exactly what you want: applying styles to input[...] selectors:
input {
margin-bottom: 1.5em;
margin-left: 0;
outline: none;
}
input[type=text], input[type=password] {
font-family: Verdana; // Text styles
}
input[type=submit] {
padding: .5em;
background-color: $button-color;
border: none;
cursor: pointer;
color: white;
border: 1px solid darken($button-color, 20%);
&:hover {
#include transition;
background-color: darken($button-color, 10%);
}
}
If you want to apply styles to custom classes/ids, consider this approach:
/////////////////
// Silent classes
/////////////////
%input {
margin-bottom: 1.5em;
margin-left: 0;
outline: none;
}
%text {
#extend %input;
font-family: Verdana;
}
%password {
#extend %text;
}
%submit {
#extend %input;
padding: .5em;
background-color: $button-color;
border: none;
cursor: pointer;
color: white;
border: 1px solid darken($button-color, 20%);
&:hover {
#include transition;
background-color: darken($button-color, 10%);
}
}
///////////////////////////
// Applying silent classes:
///////////////////////////
.some .weirdly .nested input[type=text] {
#extend %text;
}
.password {
#extend %password;
}
#the-submit-button {
#extend %submit;
}
Demo: http://sassbin.com/gist/5956909/

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

Mixin for Group Pseudo Classes with SASS

Ideally I want to create a mixin to style all the placeholder pseudo classes. I'm not sure if this is even possible. Here's what I have:
#mixin placeholder($color) {
::-webkit-input-placeholder{
color: $color;
}
:-moz-placeholder {
color: $color;
}
::-moz-placeholder {
color: $color;
}
:-ms-input-placeholder {
color: $color;
}
}
Which ideally would be used like this:
input {
&#placeholder(red);
}
And would result in this CSS:
input::-webkit-input-placeholder{
color: red;
}
input:-moz-placeholder {
color: red;
}

Resources