How to simplify this less css code? - string

I currently have this code :
input[type=text] {
background:transparent top center no-repeat;
height:30px;
font-size:13px;
color:#greyBlue;
padding:0 10px;
border:none;
&.long {
background-image:url("/img/input_long.png");
width:214px;
}
&.medium {
background-image:url("/img/input_medium.png");
width:96px;
}
&.short {
background-image:url("/img/input_short.png");
width:55px;
}
}
Do you know if I can simplify that by just changing the filename part with a variable?
Something like this :
input[type=text] {
#input = "";
background-image:url("/img/input_#{input}.png");
&.long {
#input = "long";
}
}
If course this doesn't work, but if you have any idea about a functionnal way... Thanks a lot!

create a mixin
.bgImg(#input) {
background-image:url("/img/input_#{input}.png");
}
and call it accordingly:
&.long {
.bgImg("long");
}

Related

Use switch case in Blazor for attribute

I would like to set the css class in blazor using property enum. Programmatically, a switch case would make sense.
How do I write a switch case for a attribute in Blazor?
at cs file:
public enum PastPresentFuture
{
PAST,
PRESENT,
FUTURE
}
public MyObject
{
public PastPresentFuture PastPresentFuture { get; set; }
}
at css file:
.past{
color: grey;
font-weight: 100;
}
.present {
color: black;
font-weight: 700;
}
.future {
color: black;
font-weight: 100;
}
at razor - file I tried: (NOT WORKING!)
<div class="
#switch(myObject.PastPresentFuture)
{
case PastPresentFuture.PAST: past break;
case PastPresentFuture.PRESENT: present break;
case PastPresentFuture.FUTURE: future break;
}
one-more-class">
also I tried using a span: (NOT WORKING!)
case PastPresentFuture.PAST: <span>past</span> break;
I get the error:
RZ9979 Code blocks delimited by '#{...}' like '#{ switch(currentSitzungsAndUvsDays[i].PastPresentFuture){case PastPresentFuture.PAST:break; case PastPresentFuture.PRESENT:break;case PastPresentFuture.FUTURE:break;} }' for attributes are no longer supported These features have been changed to use attribute syntax. Use 'attr="#(x => {... }"'.
I can't find the right syntax for the switch case inside a Blazor class attribute.
You know how to do?
My current workaround: (works)
<div class="
#(myObject[i].PastPresentFuture == PastPresentFuture.PAST ? "past" :
myObject[i].PastPresentFuture == PastPresentFuture.PRESENT ? "present" : "future")
day">
Create a method that returns the css class:
<div class="#GetCssClass(currentSitzungsAndUvsDays[i])">
...
</div>
string GetCssClass(MyObject myObject)
{
return myObject.PastPresentFuture switch
{
PastPresentFuture.PAST => "past",
PastPresentFuture.PRESENT => "present",
PastPresentFuture.FUTURE => "future"
};
}

Generate SASS mixins with gulp-svg-sprite?

Im using the gulp-svg-sprite plugin.
https://github.com/jkphl/gulp-svg-sprite
https://github.com/jkphl/svg-sprite
I already have my classes and styles which I would like to sprite:
.header {
background: grey;
&:after {
content: "";
display: block;
height: 30px;
width: 30px;
background: url(images/icon1.svg);
}
}
This is my gulp task:
spriteConfig = {
mode : {
css : {
bust : true,
render : {
scss : true
}
}
}
};
gulp.task('sprite', function() {
gulp.src('images/svg/*.svg')
.pipe(svgSprite(spriteConfig))
.pipe(gulp.dest('dest/'));
});
The task generates this type of SASS:
%svg-common {
background: url("svg/sprite.css-c3700f6a.svg") no-repeat;
}
.svg-icon1 {
#extend %svg-common;
background-position: 50% 0;
}
.svg-icon1-dims {
width: 1024px;
height: 348px;
}
This isnt ideal as I need to import these svg- classes which I wont use on there own, and I then need to use 2 extends:
.header {
background: grey;
&:after {
content: "";
display: block;
#extend .svg-icon1;
#extend .svg-icon1-dims;
}
}
Is there a way of generating mixins instead so I could jsut have something like:
.header {
background: grey;
&:after {
content: "";
display: block;
#include svg-icon1;
}
}
As per the docs:
It comes with a set of Mustache templates for creating stylesheets in
good ol' CSS or one of the major pre-processor formats (Sass, Less and
Stylus). Tweaking the templates or even adding your own custom output
format is really easy, just as switching on the generation of an HTML
example document along with your sprite.
Have a look and customize the following file:
https://github.com/jkphl/svg-sprite/blob/master/tmpl/css/sprite.scss
Danny H was correct. Here is my code. Notice that ive also used a prefix in my spriteConfig.
spriteConfig = {
mode : {
css : {
bust : true,
prefix : "#mixin sprite-%s",
render : {
scss: {
template: 'sprite.scss.handlebars'
}
}
}
}
};
In sprite.scss.handlebars:
{{#hasMixin}}#mixin {{mixinName}} {
background: url("{{{sprite}}}") no-repeat;
}
{{#hasCommon}}.{{commonName}} {
#include {{mixinName}};
}
{{/hasCommon}}{{/hasMixin}}{{^hasMixin}}{{#hasCommon}}.{{/hasCommon}}{{^hasCommon}}#mixin {{/hasCommon}}{{commonName}} {
background: url("{{{sprite}}}") no-repeat;
}
{{/hasMixin}}{{#shapes}}{{#selector.shape}}{{expression}}{{^last}},
{{/last}}{{/selector.shape}} {
{{^hasCommon}}{{#hasMixin}}#include {{mixinName}};{{/hasMixin}}{{^hasMixin}}#include {{commonName}};{{/hasMixin}}
{{/hasCommon}}background-position: {{position.relative.xy}};{{#dimensions.inline}}
width: {{width.outer}}px;
height: {{height.outer}}px;{{/dimensions.inline}}
width: {{width.outer}}px;
height: {{height.outer}}px;
}
{{/shapes}}

Less String Interpolation not working

Hello I have some less code and I'm trying to leverage less to get the following:
What I'm expecting:
#media only screen {
#testphone {
display: block;
background-color: blue;
}
}
My code:
#testPhone {
.testPhone({
& {
display: block;
background-color: blue;
}
});
}
.testPhone( #rules ){
.startQuery();
.screenOnly( #myQuery );
.create( #newQuery; #rules );
}
.create( #newQuery; #rules ){
#{newQuery} {
#rules();
}
}
.screenOnly( #myQuery ){
#newQuery: "#{myQuery} only screen";
}
.startQuery(){
#myQuery: "#media";
}
What I'm getting:
#testPhone "#media only screen" {
display: block;
background-color: blue;
}
What I think is going wrong:
In the .create mixin when I call #{newQuery} to interpolate #newQuery variable, it isn't removing the string off of that variable.

LESS mixin as function parameter

..................................................
Existing mixins:
.mixin_1 {
height: 1px;
}
.mixin_2 {
height: 2px;
}
.mixin_3 {
height: 3px;
}
.function(#get) {
#get();
}
CALL:
.a{
.function(mixin_1);
}
.b{
.function(mixin_2);
}
.c{
.function(mixin_3);
}
RESULT:
.a{
height: 1px;
}
.b{
height: 2px;
}
.c{
height: 3px;
}
Question: how to do this? It's possible with current language specifications?
You cannot currently do a dynamic call to a mixin based off a variable directly. You can make your function() mixin into a "caller" or "getter" mixin in which you register the mixins that can be called by your function() mixin, like so (which utilizes pattern matching):
LESS
.function(#get) {
.-(#get); //call for mixin
//register mixins you want to call with function
.-(mixin_1) { .mixin_1; }
.-(mixin_2) { .mixin_2; }
}
.mixin_1 {
height: 1px;
}
.mixin_2 {
height: 2px;
}
#block {
.function(mixin_1);
}
Outputs
.mixin_1 {
height: 1px;
}
.mixin_2 {
height: 2px;
}
#block {
height: 1px;
}
Of course, if you want the mixins invisible to the css, then change them to this:
LESS change (added parenthesis)
.mixin_1() {
height: 1px;
}
.mixin_2() {
height: 2px;
}
New Output
#block {
height: 1px;
}
Do you need it?
That level of abstraction can be useful at times, but often simply a pattern matching on the mixins will suffice. You would have to determine that. So with this simple example, it would be better to reduce to something like this:
.setHeight(1) {
height: 1px;
}
.setHeight(2) {
height: 2px;
}
#block {
.setHeight(1);
}
More complex examples of mixins may not be so easily reduced, and then a mixin like what you want may be useful.
I think your code do same thing like this:
.mixin_1() {
height: 1px;
}
.mixin_2() {
height: 2px;
}
#block {
.mixin_1();
}
And output will be:
#block {
height: 1px;
}
I was asking about little different thing. However I found solution:
.function(#get) {
.-(#get); //call for mixin
//register mixins you want to call with function
.-(mixin) { .mixin; }
}
#block {
.mixin() {
height: 1px;
}
.function(mixin);
}
#block {
.mixin() {
height: 2px;
}
.function(mixin);
}
It outputs exactly what i wanted:
#block {
height: 1px;
}
#block {
height: 2px;
}
Overall, thanks for help.

Is it possible to use a mixin for browser-specific CSS

I'm looking for a solution to use a mixin for browser-specific CSS hacks.
I'm using JavaScript to add the browser tag in the HTML class. Like .ie .ie7 .ie8 .ie9
I would like to use the mixin like:
.box-test {
margin: 10px;
#include browser(ie7) {
margin: 20px;
}
}
DESIRED OUTPUT:
.box-test {
margin: 10px;
}
.ie7 .box-test {
margin: 20px;
}
the mixin i tried to make:
#mixin browser($browserVar) {
#if $browserVar == ie7 {
.ie7 { #content }
}
#else if $browserVar == ie8 {
.ie8 { #content; }
}
#else if $browserVar == ie9 {
.ie9 { #content; }
}
}
the problem is the output is:
.box-test {
margin: 10px; }
.box-test .ie7 {
margin: 20px; }
The absolute simplest mixin would be like so:
#mixin legacy-ie($ver: 7) {
.ie#{$ver} & {
#content;
}
}
Output:
.baz {
background: #CCC;
#include legacy-ie {
background: black;
}
}
If you wanted to emit styles that work for multiple IE versions at once without duplication, then this would be one way to do it:
$default-legacy-ie: 7 8 9 !default;
#mixin legacy-ie($versions: $default-legacy-ie) {
$sel: ();
#each $v in $versions {
$sel: append($sel, unquote('.ie#{$v} &'), comma);
}
#{$sel} {
#content;
}
}
.foo {
background: red;
#include legacy-ie {
background: green;
}
}
.bar {
background: yellow;
#include legacy-ie(7 8) {
background: orange;
}
}
Output:
.foo {
background: red;
}
.ie7 .foo, .ie8 .foo, .ie9 .foo {
background: green;
}
.bar {
background: yellow;
}
.ie7 .bar, .ie8 .bar {
background: orange;
}
If you want to be able to suppress all of the IE kludges all you need to add is one variable and an #if block:
$enable-legacy-ie: true !default;
#mixin legacy-ie($ver: 7) {
#if $enable-legacy-ie {
.ie#{$ver} & {
#content;
}
}
}
Set $enable-legacy-ie to false at the top of the file you don't want to have the IE specific styles, set it to true if you do want the styles included. You could easily write a reverse mixin to hide styles that old IE can't make use of so that the IE specific file stays nice and small.
You're overcomplicating things. :) It could be as simple as that:
.box-test {
margin: 10px;
.ie-7 & {
margin: 20px; } }
Result:
.box-test {
margin: 10px;
}
.ie-7 .box-test {
margin: 20px;
}
I have tried adding mixin for "#-moz-document url-prefix()" FF hack but it was not recognized by SASS and SASS was throwing error. so I think better solution is to create _hack.sass file and add css hacks which will not be compiled by SASS. I include this file whenever required.
#import "hack";
I am adding answer this as I feel it will be useful to someone who is struggling to get mozilla/safari hack works.

Resources