Just a (hopefully) quick question about LESS Mixins:
Could these two mixins be combined somehow?, since they share a lot of the same information, just one adds an extra color.
.gradient-top(#color-1, #color-2){
background-color: #color-2;
background: -webkit-linear-gradient(top, #color-1, #color-2);
background: -moz-linear-gradient(top, #color-1, #color-2);
background: -ms-linear-gradient(top, #color-1, #color-2);
background: -o-linear-gradient(top, #color-1, #color-2);
background: linear-gradient(top, #color-1, #color-2);
}
.gradient-middle(#color-1, #color-2, #color-3){
background-color: #color-2;
background: -webkit-linear-gradient(top, #color-1, #color-2, #color-3);
background: -moz-linear-gradient(top, #color-1, #color-2, #color-3);
background: -ms-linear-gradient(top, #color-1, #color-2, #color-3);
background: -o-linear-gradient(top, #color-1, #color-2, #color-3);
background: linear-gradient(top, #color-1, #color-2, #color-3);
}
LESS supports accessing all the arguments passed to a mixin via the #arguments variable:
.gradient(#color-1, #color-2, ...) {
#gradient-stops: ~`"#{arguments}".slice(1, -1)`;
background-color: #color-2;
background: -webkit-linear-gradient(top, #gradient-stops);
background: -moz-linear-gradient(top, #gradient-stops);
background: -ms-linear-gradient(top, #gradient-stops);
background: -o-linear-gradient(top, #gradient-stops);
background: linear-gradient(top, #gradient-stops);
}
We need the selector interpolation (~) and the inline JavaScript evaluation (using backticks) to preserve the commas - otherwise, we would get background: linear-gradient(top, #color-1 #color-2 #color-n);, which is, of course, incorrect.
The other thing this mixin does is accept 2 or more arguments via the "rest" symbol (...) - this lets us call the mixing with three colors as well as two:
.gradient(#FFF, #CCC, #000) // A valid invocation of the mixin
Related
I am trying to disable my anchor tags from being underlined when hovered over. I have added text decoration: none; to my .scss file like so:
$font-family-serif: 'Nixie One';
$font-family-base: $font-family-serif;
#import "bootstrap";
//#import "bootstrap-sprockets";
//TB Navbar overrides to change the color scheme
$bgDefault : #ffffff;
$bgHighlight : #ffffff;
$colDefault : #8587f1;
$colHighlight : #4e5aff;
.navbar-default {
font-weight: bold;
font-size: 25px;
background-color: $bgDefault;
border-color: $bgHighlight;
text-decoration: none;
Also when I look at the web page, it seems to compute the rule correctly:
Where am I going wrong here?
.navbar-default {
font-weight: bold;
font-size: 25px;
background-color: $bgDefault;
border-color: $bgHighlight;
text-decoration: none;
a
{
text-decoration: none;
&:hover{
text-decoration: none;
}
}
So apparently the issue was that I just had to specify the the a tag: a {text-decoration: none;} within my scss file instead of just setting it for the class.
for some reason my body background gradients aren't showing up in IE10 except when the browswer is in quirks mode. IE9 and lower behave as expected. Code is below:
body {
font-family: 'Ubuntu', sans-serif;
background: rgb(252,254,252);
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMTAwJSIgeDI9IjEwMCUiIHkyPSIwJSI+CiAgICA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZmNmZWZjIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2RlZjZmZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
background: -moz-linear-gradient(45deg, rgba(252,254,252,1) 20%, rgba(222,246,254,1) 100%);
background: -webkit-gradient(linear, left bottom, right top, color-stop(20%,rgba(252,254,252,1)), color-stop(100%,rgba(222,246,254,1)));
background: -webkit-linear-gradient(45deg, rgba(252,254,252,1) 20%,rgba(222,246,254,1) 100%);
background: -o-linear-gradient(45deg, rgba(252,254,252,1) 20%,rgba(222,246,254,1) 100%);
background: -ms-linear-gradient(top, rgba(252,254,252,1) 20%,rgba(222,246,254,1) 100%);
background: linear-gradient(45deg, rgba(252,254,252,1) 20%,rgba(222,246,254,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfefc', endColorstr='#def6fe',GradientType=1 );
-webkit-font-smoothing: antialiased;
}
The site is built using Zurb Foundation 4. Any help would be appreciated! I'm stumped.
When using LESS, i found usefull to mix classes, in order to create a new class based on other class properties, but sometimes i need to override them.
like:
.btn {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn_warning {
.btn;
background-color: yellow;
font-size: 12px;
}
The output has duplicated properties:
.btn {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn_warning {
border-radius: 10px;
background-color: blue;
font-size:10px;
background-color: yellow;
font-size: 12px;
}
I know there are multiple aproaches for this, like multiple classes on dom, or even #extend to build multiple selectors, but navigator still overriding at runtime the properties.
Is there any reason to duplicate same properties when mixin? Seems a simple way for making "independent" groups of properties, but not nice if has duplicated values.
LESS does not account for removal of duplicate properties within a block, at least in part because of this reason stated here (quote slightly modified for grammar fix):
The trouble is that people frequently use multiple properties in order
to provide a fallback for older browsers. Removing the properties is
not something that it would be good to do generically.
It is left up to the programmer to not program it for duplication. You can set up a basic mixin like what Danny Kijkov noted in his answer, or...
Solution #1 (Complex, but Powerful to Fully Define)
You can get elaborate in building a master button maker mixin. Something like this:
LESS (Mixin)
.makeBtn(#ext: null; #rad: 10px; #color: blue; #size: 10px;) {
.set-extension() when (#ext = null) {
#class-extension: ~'';
}
.set-extension() when not (#ext = null) {
#class-extension: ~'_#{ext}';
}
.set-extension();
.btn#{class-extension} {
border-radius: #rad;
background-color: #color;
font-size: #size;
//define various addtions based on extensions here
.specialExtensionProps() when (#ext = danger) {
border: 3px solid red;
}
.specialExtensionProps() when (#ext = someExtName) {
my-special-prop: yep;
}
.specialExtensionProps();
}
}
LESS (Use the Mixin Various Ways)
.makeBtn(); //makes base button
.makeBtn(warning; #color: yellow; #size: 12px); //makes modified button
.makeBtn(danger; #color: red;); //makes modified button
.makeBtn(someExtName, 15px); //makes modified button
CSS Output
.btn {
border-radius: 10px;
background-color: #0000ff;
font-size: 10px;
}
.btn_warning {
border-radius: 10px;
background-color: #ffff00;
font-size: 12px;
}
.btn_danger {
border-radius: 10px;
background-color: #ff0000;
font-size: 10px;
border: 3px solid red;
}
.btn_someExtName {
border-radius: 15px;
background-color: #0000ff;
font-size: 10px;
my-special-prop: yep;
}
In case you did not know, note the above demonstrated LESS functionality of setting only some variables from the set of mixin variables. So for the first two specialized .makeBtn() calls, I only set a few variables, out of order from the mixin, by explicitly calling the variable name to set (e.g. #color: yellow). This allows me to "skip" over setting the #size. In the last example, I was only setting the first two values, so I did not need to put any variable names.
I don't know if the above helps you get what you want, but it does offer a different way of being able to reduce code size.
Solution #2
You mentioned :extend(), which could be well used here to avoid duplication:
LESS
.btn {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn_warning {
&:extend(.btn);
background-color: yellow;
font-size: 12px;
}
CSS Output
.btn,
.btn_warning {
border-radius: 10px;
background-color: blue;
font-size: 10px;
}
.btn_warning {
background-color: yellow;
font-size: 12px;
}
Solution #3
In your case, if all the buttons will be of either class .btn or a .btn_SOMETHING form, and you are not using .btn_ for anything else but buttons, then you might be able to just use the CSS cascade to apply styles and prevent duplication of CSS code like so (no special LESS required):
LESS and CSS Output
.btn, [class *= btn_] {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn_warning {
background-color: yellow;
font-size: 12px;
}
Any html with the class btn_warning will first get the base button styles from the attribute selector [class *= btn_] while the actual btn_warning class will override the things set to be overridden.
Solution #4
If you split the class names in the html (so class="btn warning" rather than class="btn_warning"), then this works to avoid duplication:
LESS and CSS Output
.btn {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn.warning {
background-color: yellow;
font-size: 12px;
}
What about this solution?
.btn(#size: 10px, #color:blue) {
border-radius: 10px;
background-color: #color;
font-size:#size;
}
.btn_warning {
.btn(12px, yellow);
}
I want my page to have a gradient color, going from dark on the left age to bright in the middle, and back to dark at the right edge. I've seen some examples for creating gradients, but I don't know see where in the CSS the size of the pattern is being set, and the pattern is repeating too quickly for my taste.
As an example, here's some CSS:
html {
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#2F2727), to(#1a82f7));
background-image: -webkit-linear-gradient(top, #2F2727, #1a82f7);
background-image: -moz-linear-gradient(top, #2F2727, #1a82f7);
background-image: -ms-linear-gradient(top, #2F2727, #1a82f7);
background-image: -o-linear-gradient(top, #2F2727, #1a82f7);
}
...that I found here: http://css-tricks.com/css3-gradients/
And here's a jsfiddle you can run that has that:
http://jsfiddle.net/clayshannon/VLXbu/
It can't be a fixed size, because of the variance is screen sizes, between phones and desktops, in particular. Is there a way to accomplish this using %s of screen width?
Try
html {
background: #2f2727; /* Old browsers */
background: -moz-linear-gradient(top, #2f2727 0%, #1a82f7 49%, #1a82f7 49%, #2f2727 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#2f2727), color-stop(49%,#1a82f7), color-stop(49%,#1a82f7), color-stop(100%,#2f2727)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #2f2727 0%,#1a82f7 49%,#1a82f7 49%,#2f2727 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #2f2727 0%,#1a82f7 49%,#1a82f7 49%,#2f2727 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #2f2727 0%,#1a82f7 49%,#1a82f7 49%,#2f2727 100%); /* IE10+ */
background: linear-gradient(to bottom, #2f2727 0%,#1a82f7 49%,#1a82f7 49%,#2f2727 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#2f2727', endColorstr='#2f2727',GradientType=0 ); /* IE6-9 */
min-height: 100%; height: auto !important; height: 100%;
}
http://jsfiddle.net/pepean/hSjdg/2/
On their site, they give an example of how to use #arguments:
.box-shadow (#x: 0, #y: 0, #blur: 1px, #color: #000) {
box-shadow: #arguments;
-moz-box-shadow: #arguments;
-webkit-box-shadow: #arguments;
}
.box-shadow(2px, 5px);
Which results in:
box-shadow: 2px 5px 1px #000;
-moz-box-shadow: 2px 5px 1px #000;
-webkit-box-shadow: 2px 5px 1px #000;
It appears it just takes all the arguments and separates them with spaces. I actually want the arguments separated by commas for use with linear-gradient:
background: linear-gradient(top, #arg1, #arg2, #arg3...);
Is this possible with less?
Inspired by #Allan's answer, I had to use the following to get #arguments passed to a linear gradient function:
.linear-gradient-multi( ... ) {
background-image: -webkit-linear-gradient( ~`"#{arguments}".slice(1,-1)` );
...
}
Only then could I call the mixin with percentages and variables:
.linear-gradient-multi(left, #CCC 0%, #DDD #percent, #FFF #percent + 1, #FFF 100%);
You can do something like this
.mixin(...) {
filter: gradient( ~`#{arguments}.join(",")` );
}
test {
.mixin("x1","x2","x3")
}
You should use back-ticks to be able to run some javascript. but that means that all elements inside the arguments array should be valid javascript variables, that's why when calling the mixin you should wrap all the arguments in quotes to make them javascript strings. the above code will be compiled to:
test {
filter: gradient(x1,2,3);
}