SCSS boolean property not working on :active property - sass

I have set boolean variable to false and on click of button I want to change its background color in scss file. But it looks like display variable is not set to true on :active, how can I achieve this functionality?
Here is my scss file
$display : false;
.bot {
&:active {
$display: true;
display: none;
}
}
#if $display {
.bot {
background-color: brown;
}
}
Here is my html file
<button class="bot" (click)="xy()">Table
</button>

The proper way to implement what you want to achieve is simply toggling the .active CSS selector using JavaScript:
HTML
<button class="bot" onclick="xy()">Table</button>
Scss
.bot {
background-color: brown;
&:active {
display: none;
}
}
JavaScript function
const xy = () => {
let btn = document.querySelector("button");
btn.classList.toggle(":active");
}
See it working in this fiddle: https://jsfiddle.net/ezpvc16m/2/
It makes no sense toggling a CSS selector like :active using Sass variables and booleans; :active already works like true or false. It is activated whenever an element (in this case, a button) is activated by a user. Otherwise, it's not activated.
--
Also, keep in mind that Sass is compiled to CSS and CSS doesn't have access to Sass variables and booleans.

Related

Looping and assigning values through SASS

Before judging my situation, I am not using a typical Bootstrap approach to assign custom colors to variables. I am in a unique situation of depending on the Bootstrap CDN, and re-creating custom SASS variables that look like BS4 variables. Read on!
I feel like I am so close on the the following process. All I want to do is assign my array values to a class property name like so, (i.e. background-color: $theme-primary!important;)
//ORIGINAL THEME VARIABLES
$theme-colors: (primary:$m-color-blue, secondary: $m-color-off-white, success: $m-color-grey, info: $m-color-grey-light, warning: $m-color-gold, light: $m-color-white, dark: $m-color-grey-dark);
$theme-primary: map-get($theme-colors, "primary");
$theme-secondary: map-get($theme-colors, "secondary");
$theme-success: map-get($theme-colors, "success");
$theme-info: map-get($theme-colors, "info");
$theme-warning: map-get($theme-colors, "warning");
$theme-light: map-get($theme-colors, "light");
$theme-dark: map-get($theme-colors, "dark");
//MY LOOP TO ASSIGN BS4 BG COLORS TO MY CUSTOM COLORS.
$classes: primary secondary success warning danger light;
#each $class in $classes {
html body .bg-#{$class} {
//MY ISSUE IS HERE...IT DOES NOT LIKE HOW I AM FORMING THIS PROPERTY. SYNTAX ISSUE???
background-color: $theme-#{class} !important;
}
}
But when I attempt to compile it, I get the following error:
messageOriginal: Undefined variable: "$theme-".
I think I get the error, but how do I resolve?
I'm not sure why this would be necessary since there's already utility classes available for this; https://getbootstrap.com/docs/4.0/utilities/colors/#background-color
You can also feed the bootstrap sass straight into your build pipeline to use all their vars, mixins, functions already;
https://getbootstrap.com/docs/4.0/getting-started/theming/
However, I think you're looking for something more like this amigo; Cheers
$classes: (
primary: "#f00",
secondary: "#ddd",
success: "#00f",
warning: "#0f0",
danger: "#f00",
light: "#eee"
);
#each $key, $val in $classes {
.bg-#{$key} {
background-color: #{$val} !important;
}
}
If you're not importing the $theme variable from your _base / other directory then how do you expect the script to know what to fill it in with?
Your syntax is wrong, you need to wrap $theme with #{} as well so it's #{$theme}-#{class}
working example:
$classes: primary secondary success warning danger light;
$theme: 'blue'; // switch this with import theme.
#each $class in $classes {
html body .bg-#{$class} {
background-color: #{$theme}-#{$class} !important;
}
}
generated css:
html body .bg-primary {
background-color: blue-primary !important;
}
html body .bg-secondary {
background-color: blue-secondary !important;
}
html body .bg-success {
background-color: blue-success !important;
}
html body .bg-warning {
background-color: blue-warning !important;
}
html body .bg-danger {
background-color: blue-danger !important;
}
html body .bg-light {
background-color: blue-light !important;
}
If you are using Bootstrap4, you can directly add a new color to $theme-colors, add the new key and value
$theme-colors: (
"custom-color": #900
);

What is the best SASS practice of writing child selector while parent has hover

I have a doubt of writing child selector when I have a hover event in parent.
say I have HTML like this,
<div class="root">
<div class="root__element">
<div class="root__sub-element" />
</div>
</div>
In sass,
.root {
$root: &;
&__element {
&:hover {
#{$root}__sub-element {color: red;} // question comes here, why
// not using .root_sub-
// element?
}
}
}
what I want is hover event happens in root__element, color change in root__sub-element.
Should I use ampersand to keep SASS or I would directly use '.root__sub-element'?
You should Keep SASS.
I noticed you tagged 'bem' in your question.
As per BEM, your block element class to continue with your prefix of last child class. http://getbem.com/naming/
POINT 1:
If you have another element with the same behavior. the hardcoded class .root__sub-element will break. please consider the following sass code with multiple root classes.
SASS Code :
$roots: root, newroot;
#each $r in $roots {
.#{$r}{
$root: &;
&__element {
&:hover {
#{$root}__sub-element {color: red;}
}
}
}
}
POINT 2:
This is very rare or not suggested practice, but suppose in case your root block class .root changed to .newroot. as per bem, your child classes will change with new prefix.
Here, hardcoded class .root__sub-element will break, you need to changes it to all area manually.
Otherwise:
CSS is:
.newroot__element:hover .root__sub-element {
color: red;
}
Expected CSS:
.newroot__element:hover .newroot__sub-element {
color: red;
}

How to detect css blur support with Modernizr?

How can I detect if browser supports css blur?
Can I use any of these default classes Modernizr puts to html tag?
borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients no-cssreflections csstransforms csstransforms3d csstransitions
I'd need to disable all blurs (or enable) css blurs to only supported browsers in css. Thank you
If you go to: https://modernizr.com/download?setclasses, and then select the CSS Filters you will see the following example:
CSS
.no-cssfilters .box { color: red; }
.cssfilters .box { color: green; }
JS
if (Modernizr.cssfilters) {
// supported
} else {
// not-supported
}
I believe that this is what you need.

Customizing the output of Compass sprites

I have a top bar menu (that's based on Zurb's Foundation):
This is the SCSS:
.top-bar {
.top-bar-section {
ul {
#import "menu-icons/*.png";
#include all-menu-icons-sprites;
}
}
}
Now, this does what expected, but the problem is that I want to style the a element inside each li elements (actually, I'd like to apply it to .top-bar.topbar-section.ul.li.a:before).
However, since the site is build in WordPress, and so the menu, I can only assign the class to the li element and I have no idea how to make the Compass's spriting work.
I know, I could customize the way the menu is rendered by WordPress using a walker class, but I'd prefer to try finding a solution simply writing the right SCSS, providing that is possible.
There are a few sprite helper functions to be aware of when the default output isn't exactly what you want:
sprite-url
sprite-position
sprite-names (undocumented)
Using these you can apply the sprite styles to the children of the li elements:
.top-bar .top-bar-section ul > li {
// Generate the sprite map.
$menu-icons-sprite-map: sprite-map("menu-icons/*.png", $layout: smart);
// Set the background image.
> a:before {
background: sprite-url($menu-icons-sprite-map) 0 0 no-repeat;
}
// Set the background position for each sprite.
$menu-icons-sprite-names: sprite-names($menu-icons-sprite-map);
#each $name in $menu-icons-sprite-names {
&.menu-icons-#{$name} > a:before {
background-position: sprite-position($menu-icons-sprite-map, $name);
}
}
}

Is it possible to select the parent of the parent with SCSS

I have a SCSS file with the following
input{
&[type="text"],
&[type="search"]{
margin: 0 0.5em;
}
}
which works as expected. I would also like a textarea to have the same CSS. Does SCSS have a selector that will allow me to place textarea with the
&[type="text"], &[type="search"]
in the SCSS file but not place the 'input' parent before textarea. The output I'm trying to achieve is as follows
input[type="text"], input[type="search"], textarea {
margin: 0 0.5em;
}
I know I could do this with a mixin however I was thought this feature was added to SCSS.
#extend works really great in these situations. % is good as a way of implying that this class will only ever be extended.
%baseClass{
margin: 0 0.5em;
}
input{
&[type="text"],
&[type="search"]{
#extend %baseClass;
}
}
textarea{
#extend %baseClass;
}
No, you cannot. For a lengthy selector, The best you can do is set it as a variable and use that.
$form-input-text: unquote('input[type="text"], input[type="password"], input[type="search"], input[type="email"], input[type="tel"], input[type="url"]');
#{$form-input-text} {
// styles;
}
#{$form-input-text}, textarea {
// styles
}

Resources