How to override scss variables correctly? - sass

I have the following scss which sets tooltip arrow direction. The size of the tooltip is a variable that I would like to override when the .tooltip-large class is present. For whatever reason the 12px value is being used regardless of the class. What might I be doing wrong here?
<div class="tooltip-arrow tooltip-arrow-up">This tooltip arrow should be 6px</div>
<div class="tooltip-arrow tooltip-arrow-up tooltip-large">This tooltip arrow should be 12px</div>
.tooltip-arrow {
$triangleSize: 6px;
&.tooltip-large {
$triangleSize: 12px;
}
&::after {
content: '';
display: block;
height: 0;
width: 0;
position: absolute;
}
&-down::after {
border-left: $triangleSize solid transparent;
border-right: $triangleSize solid transparent;
border-top: $triangleSize solid mat-color($background, tooltip);
bottom: 0;
left: 50%;
transform: translate(-50%, 100%);
}
&-up::after {
border-left: $triangleSize solid transparent;
border-right: $triangleSize solid transparent;
border-bottom: $triangleSize solid mat-color($background, tooltip);
top: 0;
left: 50%;
transform: translate(-50%, -100%);
}
&-left::after {
border-top: $triangleSize solid transparent;
border-bottom: $triangleSize solid transparent;
border-right: $triangleSize solid mat-color($background, tooltip);
left: 0;
top: 50%;
transform: translate(-100%, -50%);
}
&-right::after {
border-top: $triangleSize solid transparent;
border-bottom: $triangleSize solid transparent;
border-left: $triangleSize solid mat-color($background, tooltip);
right: 0;
top: 50%;
transform: translate(100%, -50%);
}
}

There is a fundamental difference between SCSS and CSS variables.
SCSS variables ($xxx) are imperative, meaning that values overwritten in a different scope remain saved in the reference.
CSS variables (var(--xxx, <potential-fallback-value>)) are declarative, which means their value stays the same for all calls, but a selector may hold a changed value, which will only stay as long as that selector matches.
Here's a comparison I made. SCSS variables:
Refs:
$x: 1
$y: 2
$z: 3
...
CSS vars:
Refs:
--x:
':root': 1
.some-class: 2
--y:
':root': 2
.some-class: 3
...
So, here you should be using CSS var()s, not SCSS $variables. The former one also has good browser support, so you shouldn't worry.

Not sure how to override the variable correctly... but here's the solution I went with:
&.tooltip-large::after {
border-width: 12px;
}

Related

Getting the checked value of a checkbox - Material Design

I have a page that uses a basic bootstrap based Admin BSB Material Design layout
I am having difficulty getting a value from the checkboxes in this design.
Example checkbox that is 'checked':
I am seeing cypress having no luck finding the checkbox control even if i add a data-cypress="mycheckbx" attribute.
So my questions is: how do I obtain the 'checked' property in this scenario?
Styles Used:
[type="checkbox"].filled-in:not(:checked)+label:before {
width: 0;
height: 0;
border: 3px solid transparent;
left: 6px;
top: 10px;
-webkit-transform: rotateZ(37deg);
transform: rotateZ(37deg);
-webkit-transform-origin: 20% 40%;
transform-origin: 100% 100%
}
[type="checkbox"].filled-in:not(:checked)+label:after {
height: 20px;
width: 20px;
background-color: transparent;
border: 2px solid #5a5a5a;
top: 0;
z-index: 0
}
[type="checkbox"].filled-in:checked+label:before {
top: 0;
left: 1px;
width: 8px;
height: 13px;
border-top: 2px solid transparent;
border-left: 2px solid transparent;
border-right: 2px solid #fff;
border-bottom: 2px solid #fff;
-webkit-transform: rotateZ(37deg);
transform: rotateZ(37deg);
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%
}
[type="checkbox"].filled-in:checked+label:after {
top: 0;
width: 20px;
height: 20px;
border: 2px solid #26a69a;
background-color: #26a69a;
z-index: 0
}
Since none of the solutions above worked for me, I did this :
cy.get('#element').should('be.checked')
source : cypress documentation
The opposite (unchecked) assertion would be (see the official docs):
cy.get('#element').should('not.be.checked')
It seems all I needed to do was:
cy.get('#pract-haspen').should('have.attr', 'checked')
and that Assertion worked!
Thanks
This answers ask the question with an assert test in mind.
If you want to get the value and use it somewhere, you can simply:
cy.get('#elementQuery').then(elem => {
var value = elem.val()
...do anything you want, like if(value == 'on')...
})
If attr doesn't work for you, try prop:
cy.get('#pract-haspen').should('have.prop', 'checked')

Using scss/sass trailing ampersand to target one level back

I have two types of circles, one inside of .poi.licensed and one inside of .poi.unlicensed. I am trying to make it so that the .circle inside of .poi.unlicensed has a $tangerine border instead of $turqoise. How can I used the trailing amerpsand to do so in this situation. Keep in mind that there is a lot of other scss that I am excluding that is unrelated, so it has to stay in this general structure.
I was trying something along the lines of the following, but it compiles to .unlicensed #licensed-v-unlicensed .poi .circle {}
$turqoise: #40e8e3;
$tangerine: #ffa975;
#licensed-v-unlicensed {
.poi {
.circle {
border: 5px solid transparentize($turqoise, 0.1);
.unlicensed & {
border: 5px solid transparentize($tangerine, 0.1);
}
#include breakpoint(medium up) {
border-width: 10px;
}
border-radius: 50%;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.4);
width: 100%;
height: 100%;
position: relative;
cursor: pointer;
}
}
}
I ended up using a trick I found on this blog, which was to use #at-root in order to start at the root and target the .unlicensed class. It's a lot more work than I had hoped to do, but the only solution discovered thus far.
$turqoise: #40e8e3;
$tangerine: #ffa975;
#licensed-v-unlicensed {
.poi {
.circle {
border: 5px solid transparentize($turqoise, 0.1);
#at-root #licensed-v-unlicensed .poi.unlicensed .circle {
border: 5px solid transparentize($tangerine, 0.1);
}
#include breakpoint(medium up) {
border-width: 10px;
}
border-radius: 50%;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.4);
width: 100%;
height: 100%;
position: relative;
cursor: pointer;
}
}
}

compass (scss) variables & media queries [duplicate]

This question already has answers here:
Using Sass Variables with CSS3 Media Queries
(8 answers)
Closed 7 years ago.
I'm trying to do something like this:
$arrow-size: 30px;
#media only screen and (max-width: 449px) {
$arrow-size: 15px;
}
div.selector {
height: 0px;
width: 0px;
position: absolute;
bottom: 0px;
left: 50%;
border-bottom: $arrow-size solid white;
border-left: $arrow-size solid transparent;
border-right: $arrow-size solid transparent;
}
Unfortunately, $arrow-size does not change according to the media query (my arrow is always 15px, even if my window is wider than 449px).
Any idea ? Or am I taking the problem the wrong way ?
As an alternative, try using the power of em's:
$arrow-size: 1.875em; // 30px, use pxtoem.com for conversion
div.selector {
height: 0px; width: 0px;
position: absolute;
bottom: 0px; left: 50%;
border-bottom: $arrow-size solid white;
border-left: $arrow-size solid transparent;
border-right: $arrow-size solid transparent;
}
#media only screen and (max-width: 449px) {
div.selector { font-size: 50%; }
}
Since the em is relative to the font-size, all you gotta do is play with that value to change the size of the arrow across different responsive states.
I would use a mixin:
#mixin arrow($size) {
border: $size;
}
Then you can use it in your media query like this (combined with a variable):
$arrowSize: 30px;
#media only screen and (max-width: 449px) {
div.selector {
#include arrow($arrowSize / 2);
}
}
div.selector {
#include arrow($arrowSize);
}
I think you did not understand how works SASS / Compass and media queries.
Variables are transformed by the compiler before being sent to the client as opposed to media queries that are interpreted by the browser's CSS engine as well as conventional selectors (id, class, tag)
The compiler does not interpret the media query as a condition, simply because at the time of compilation, the screen size is not defined, and especially because it is not his job.
Here is a simplified version of what happens:
1 $arrow-size: 30px; "ok, I set a new variable arrow-size to 30px"
3 #media only screen and (max-width: 449px) { "ok, a new selector...
syntax is correct, I'll look later if the brace is closed."
4 $arrow-size: 15px; "ok, I set the arrow-size variable to 15px"
5 } "ok, brace is closed"
...
13 border-bottom: $arrow-size solid white; "A new css rule, syntax ok... oh, I have to replace a variable ! How much for $arrow-size ? Oh yes, 15px, I change it."
In result, the compiled CSS file will be :
screen.css
#media only screen and (max-width: 449px) {
}
div.selector {
height: 0px;
width: 0px;
position: absolute;
bottom: 0px;
left: 50%;
border-bottom: 15px solid white;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
}
you can also put your media queries into selectors :
$arrow-normal-size: 30px;
$arrow-small-size: 15px;
div.selector {
height: 0px;
width: 0px;
position: absolute;
bottom: 0px;
left: 50%;
border-bottom: solid white;
border-left: solid transparent;
border-right: solid transparent;
border-width: $arrow-normal-size;
#media only screen and (max-width: 449px) {
border-width: $arrow-small-size;
}
}
or use a mixin :
a little bit useless in this specific case
#mixin responsive-border($max-screen-width, $border-width){
#media only screen and (max-width: #{$max-screen-width}) {
border-width: $border-width;
}
}
div.selector {
height: 0px;
width: 0px;
position: absolute;
bottom: 0px;
left: 50%;
border-bottom: solid white;
border-left: solid transparent;
border-right: solid transparent;
border-width: 30px;
#include responsive-border(449px,15px);
}

Can i remove bottom scroller on overflow:scroll?

So i have a popup window with a scroller. For scroller i used basic css element overflow: scroll. But the problem is scroller appears on the side and on the bottom. Now i want to know if there is anyway to remove the bottom scroller, because even though its locked its useless to me and it would look better without it. Ive googled it and havent found anything so if you have a solution please share it. If you need any of the code tell me and i will post it.
This is "my" css for popup (i got the code from http://www.zurb.com/playground/reveal-modal-plugin):
.reveal-modal-bg {
position: fixed;
height: 100%;
width: 100%;
background: #000;
background: rgba(0,0,0,.8);
z-index: 100;
display: none;
top: 0;
left: 0;
}
.reveal-modal {
visibility: hidden;
top: 100px;
left: 50%;
margin-left: -300px;
width: 520px;
height: 400px;
background: #eee url(modal-gloss.png) no-repeat -200px -80px;
position: absolute;
z-index: 101;
padding: 30px 40px 34px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0 0 10px rgba(0,0,0,.4);
-webkit-box-shadow: 0 0 10px rgba(0,0,0,.4);
-box-shadow: 0 0 10px rgba(0,0,0,.4);
overflow:scroll;
}
.reveal-modal h1{
color: green;
font-size: 40px;
}
.reveal-modal strong{
font-style: inherit;
}
.reveal-modal.small { width: 200px; margin-left: -140px;}
.reveal-modal.medium { width: 400px; margin-left: -240px;}
.reveal-modal.large { width: 600px; margin-left: -340px;}
.reveal-modal.xlarge { width: 800px; margin-left: -440px;}
.reveal-modal .close-reveal-modal {
font-size: 22px;
line-height: .5;
position: absolute;
top: 8px;
right: 11px;
color: #aaa;
text-shadow: 0 -1px 1px rbga(0,0,0,.6);
font-weight: bold;
cursor: pointer;
}
a better way of doing it would be
overflow-x:hidden;
overflow-y:auto;
That way it means that if a page gets bigger with jquery and then you need to scroll the view won't get smaller and affect your measurements
This should work:
overflow-x:hidden;
overflow-y:auto;

Disable dropdown on hover for bootstrap when navbar is collapsed

I have implemented the css as shown here: How to make twitter bootstrap menu dropdown on hover rather than click
However want to disable the dropdown on hover when the navbar collapses as it acts a bit buggy.
How can I do it?
You could try wrapping the CSS to disable the dropdown in a media query so that it is only disabling it at a certain page width... Reading up on media queries and trying to understand how bootstrap implements them is going to be one the keys to debugging this. Here's what I tried with the previous answer's fiddle.
http://jsfiddle.net/2Smgv/5544/
#media (min-width: 767px) {
.sidebar-nav {
padding: 9px 0;
}
.dropdown-menu .sub-menu {
left: 100%;
position: absolute;
top: 0;
visibility: hidden;
margin-top: -1px;
}
.dropdown-menu li:hover .sub-menu {
visibility: visible;
}
.dropdown:hover .dropdown-menu {
display: block;
}
.nav-tabs .dropdown-menu, .nav-pills .dropdown-menu, .navbar .dropdown-menu {
margin-top: 0;
}
.navbar .sub-menu:before {
border-bottom: 7px solid transparent;
border-left: none;
border-right: 7px solid rgba(0, 0, 0, 0.2);
border-top: 7px solid transparent;
left: -7px;
top: 10px;
}
.navbar .sub-menu:after {
border-top: 6px solid transparent;
}
}

Resources