Sass, create css class dynamic depending on data - sass

I have this class:
.currency-flag-clp:before {
background-image: url('~currency-flags/dist/square-flags/clp.svg');
}
I want to add that class dynamically to an html element, so I need to add a class like:
.currency-flag-XXXXX:before {
background-image: url('~currency-flags/dist/square-flags/XXXXX.svg');
}
Is there a way with sass to do that? I don't want to define 270 class per value, I just want to create the class depending on my data.

As you want to set an individual class on the element it seems you have access to your currency data when building the page. In that case there may be an alternative more simple approach without SASS.
(1) ALTERNATIVE (NON SASS) SOLUTION - maybe a simpler approach
(a) Write a css variable 'actual-currency-flag-url' for your actual flag-image to a style block in the head of your file based on the actual user setting/currency.
(b) Then use that variable to build the url-path in css.
// add to <head> of page:
// based on your data maybe you can do it by php
// note: don't use slashes when building url(...)
<style>
:root {
--actual-currency-url: url(url-path/flag-[actualCurrency].jpg);
}
</style>
// change class off html element
// from <div class="currency-flag-XXXXX"> to:
<div class="currency-flag">
// now you can do in your separate stylesheet file:
.currency-flag:before {
background-image: var(--actual-currency-url);
}
Writing the style direct to the element is less elegant but works as well of course.
(2) POSSIBLE SASS SOLUTION - building 270 classes in SASS using a mixin
(a) Based on your data: generate a simple suffix-list and use it to build a SASS map with the suffixes of your flags.
(b) Use #each to build all 270 classes at once
// example code in SASS:
$flag-suffixes: (
USD,
AUD,
EUR,
//...
);
#each $suffix in $flag-suffixes {
.currency-flag-#{$suffix}:before {
background-image: url('~currency-flags/dist/square-flags/#{$suffix}.svg');
}
}

Related

SASS add ampersand to mixin output

I'm trying to use an Angular Material mixin with a custom scope. I want to generate my theme like this:
.material-green-theme.mat-mdc-<selector> {
// content
}
However my compiled CSS turns out to be this:
.material-green-theme .mat-mdc-<selector> {
// content
}
This is my code:
.material-green-theme {
#include mat.slide-toggle-color($green-theme);
}
I've tried adding #at-root among other things to make it connect however I can't get it work; nor can I modify the mixin since it's from the Angular Material package. Is there a way for me to somehow make this work?

Using nested scss rules in Gatsby scss modules

In React I have a component called GlobalFooter, that provides a website footer.
The component has nested HTML elements.
My scss module looks something like this:
.GlobalSiteFooter {
background-color: #1e6ed0 ;
a.footer-logo {
border: 2px solid #000 ;
img {
}
}
}
When Gatsby processes the component, it adds strings to class names, in order to keep the CSS scoped to the component.
However, it doesn't add a string to the element footer-logo.
It does add a string to the CSS rule 'a.footer-logo'.
As a result, nested rules within SCSS files cannot be applied to their target elements.
As far as the browser is concerned, the targeted elements don't exist.
Is there a way to nest SCSS rules, and have those rules applied to their corresponding DOM elements?

What is the right way to style an element with multiple selectors in SASS?

I have some elements as such:
<div class="logo">
LOGO HERE
</div>
Considering the a tag is the only element within .logo is it still appropriate to write the SASS as:
.logo {
a {
//STYLES
}
}
Or is normal css ok here? Eg:
.logo a {
//STYLES
}
Both ways work, of course, but is there a preferred way when working with SASS?
Both will work fine in SASS. Traditionally, for readability, it's better to nest the elements, as you've listed in the first example.

Nest a link within a class with SASS

How can I nest the following in SASS?
.class {
// First styles
}
a.class:visited {
// Second styles
}
I can nest the :visited pseudo class with this, but im not sure how to add the link element?
.class {
// First styles
&:visited {
// Second styles
}
}
I don’t know why you’d want that, adding the a probably just adds unnecesary specificity. If you really need that there’s probably a design flaw somewhere else.
That said, you can make it work using interpolation around the &. However that doesn’t really give you the expected result so you need #at-root as well to make it work.
.class {
// some styles...
#at-root a#{&}:visited {
// ...more styles!
}
}
I don’t think this is the best way of solving your problem though. Using Sass should result in easier maintainable code.

Is it possible with compass to loop through a folder and generate css classes of the files within? [duplicate]

I'm using sass and compass and I am trying to create css classes for images matching a given pattern.
The intended/resulting css mostly looks like this:
.class1 { background-image: url(class1.png); }
.class2 { background-image: url(class2.png); }
While it might be possible to use the compass sprite functionality ( http://compass-style.org/help/tutorials/spriting/ ) it is inconvenient (as it will generate new files) in my case as the images are already spritesheets themselves.
So being able to do something like
#each $clazz in listFiles("images/*") {
.#{$clazz} {
background-image: url('#{$clazz}.png');
}
}
would be great.
Is there a more or less easy way to do so?
You can accomplish this by supplementing the builtin SASS/Compass functions with your own custom Ruby function. (See the section titled "Adding Custom Functions" in the SASS reference here.) Just define a Ruby file (say, "list-files.rb") with your custom code like so:
module Sass::Script::Functions
def listFiles(path)
return Sass::Script::List.new(
Dir.glob(path.value).map! { |x| Sass::Script::String.new(x) },
:comma
)
end
end
Then, you can include this file from your compass configuration file (say, "config.rb"):
require File.join(File.dirname(__FILE__), 'list-files.rb')
And access it in your SASS stylesheet just like you want to:
#each $clazz in listFiles("images/*") {
.#{$clazz} {
background-image: url('#{$clazz}.png');
}
}
You can then compile using compass compile -c config.rb, as normal.

Resources