Reputation: 206
I'd like to have a mixin function that returns a list of the HTML5 input types. I'd like to manage this in one place, and as new types come up, change the function, not all the places elsewhere in the code.
The problem seems to be that mixins were not designed to return strings that can be used outside of the curly braces in CSS. Here is an example of my mixin (currently returning errors) and how I'd use it:
/*
* Set all the up-and-coming input text types here for easier reference
* Does not include types that are not meant to be displayed full width, such as:
type=number, type=range, type=date, type=color
*/
@mixin input_text_types( $focus:false ) {
@if $focus {
@return #{input[type=text]:focus, input[type=password]:focus, input[type=search]:focus, input[type=email]:focus, input[type=url]:focus, input[type=tel]:focus};
} @else {
@return #{input[type=text], input[type=password], input[type=search], input[type=email], input[type=url], input[type=tel]};
}
}
In use:
@include input_text_types() {
width: 80%;
}
The errors I get are like error sass/style.scss (Line 134 of sass/_functions.scss: Invalid CSS after "...@return #{input": expected "}", was "[type=text]:foc...")
I've tried to format the output with and without the @return
directive, and with different ways I have seen to enclose string values (in quotes, in single quote, in the curly braces with the hash). Anyone ever try to do something like this before?
Upvotes: 4
Views: 3688
Reputation: 68349
Your problem might better be solved by using variables to contain your selectors. By using a mixin, you're losing the ability to chain it with similar elements.
$form-input-text: 'input[type="text"], input[type="password"], input[type="search"], input[type="email"], input[type="tel"], input[type="url"]';
$form-input-buttons: 'input[type="submit"], input[type="reset"], input[type="button"], button';
$form-input-dates: 'input[type^="date"], input[type="month"], input[type="week"], input[type="time"]';
$form-input-not-radio: 'input:not([type="radio"]):not([type="checkbox"])';
#{$form-input-text}, textarea {
@include border-radius(.25em);
border: $form-input-border;
}
#{$form-input-text}, textarea, input[type="file"] {
width: $form-input-width;
max-width: 100%;
-webkit-appearance: textfield
}
#{$form-input-buttons} {
padding: .25em .5em;
}
Upvotes: 4
Reputation: 206
Thanks to Chris Eppstein on GitHub and @compass on Twitter, he cleared up with a gist that I am confusing the way a function works vs. a mixin. With the @content
directive, I can achieve what I want thusly:
@mixin input_text_types( $focus:false ) {
@if $focus {
input[type=text]:focus, input[type=password]:focus, input[type=search]:focus, input[type=email]:focus, input[type=url]:focus, input[type=tel]:focus {
@content;
}
} @else {
input[type=text], input[type=password], input[type=search], input[type=email], input[type=url], input[type=tel] {
@content;
}
}
}
It would still be used in the same way, with the @include
directive.
For more about the slight differences between @mixin
and @function
, read Pure SASS Functions.
Upvotes: 1