Modify CSS variable in media query - css

Is there a way to modify a previously-declared CSS variable inside a media query with just vanilla CSS? What I'm after would look like this (which of course doesn't work as the variables all get computed in the end):
#container {
--elem-size: 20px;
}
#media only screen and (min-width: 800px) {
#container {
--elem-size: calc(var(--elem-size) * 2);
}
}
I'm aware that it would be possible to declare a "base variable" (e.g. --base-elem-size) and then use it to generate new variable values for different viewports. However, I'm working with a very large number of CSS variables which makes it undesirable to create a duplicate base set out of them. The ideal solution would be able to "modify" a previously-declared value.

This might be far from ideal but to some degrees does define the style in one line. It uses fallback values of CSS variables.
Open full screen and change window size to see the result:
:root {
--elem-size-base: 50px;
}
#container {
/* 👇 Fallback for base value, optional 2nd fallback for no variable value */
width: var(--elem-size, var(--elem-size-base, 50px));
height: var(--elem-size, var(--elem-size-base, 50px));
outline: 2px solid #000;
background-color: pink;
}
#media only screen and (min-width: 768px) {
#container {
/* 👇 This variable for various #media */
--elem-size: calc(var(--elem-size-base) * 2);
background-color: lightblue;
}
}
#media only screen and (min-width: 1024px) {
#container {
/* 👇 This variable for various #media */
--elem-size: calc(var(--elem-size-base) * 4);
background-color: lightgreen;
}
}
<div id="container"></div>

I think having base CSS variables would make your CSS much more readable and easier to maintain, specially if you are working with a big codebase.
May be something like this:
:root {
/* Define you base variables */
--font-size-default: 16px;
--font-size--large: calc(var(--font-size-default) * 1.25);
/* Assign the base variable to the element variables */
--elem-size: var(--font-size-default);
}
#media screen and (min-width: 840px) {
:root {
/* Change base variable used for element variable */
--elem-size: var(--font-size--large);
}
}
This allows you to set a base font-size variable and one (or more) "variants" of that variable, which you can then use on your whole project
I would suggest you look into something like the Open Props (which has some really great ideas for what base variables can be and how to use them)

Related

Why SCSS variable is not changing value on media query?

Want to change my variable value on media queries but the value doesn't change at all. Why is that?
I tried to simple change the value on the media query but nothing happens.
// My variables
// All these variables works outside the media queries
$marq-width: 80vw; // using this one
$marq-height: 20vh;
$marq-elm-displayed: 5;
$marq-elements: 9;
$marq-elm-width: calc( #{$marq-width} / #{$marq-elm-displayed} );
$marq-animation-duration: calc(#{$marq-elements} * 3s);
$color: black;
$break-md: 600px;
// Here is my problem
#media(max-width: 600px) {
body {
background: red; // this works
}
$marq-width: 100vw; // this not work
}
Here is my codepen link: https://codepen.io/G-ROS/pen/JjPzovR?editors=0100
You can shrink the viewport on <= 600px and see the background changing to red but the variable did not changes at all. I expect the variable changes has the value "100vw", but it remains with the original value of "80vw".
You are missing to define width you define the variable but not width.
chnaging only variable will not impact on css you will use that variable to such css like below.
#media(max-width: 600px) {
body {
background: red; // this works
}
$marq-width: 100vw; // this will not work
.marquee{width:$marq-width;} // this works
}
Check the codepen

how to override #media (max-width) using stylish

Intro
this is similar to this question but unfortunately the answer only applies to greasmonkey (which only works on firefox). Further, this was asked on the stylish forum but the answer was ambiguous.
Question
I want to remove the left column in the azure help page and
expand the main body to make it cover the widht of the screen.
The first part can easily be done by this
#sidebarContent {display:none}
How ever the second part must conver this
media (max-width: 1199.99999px)
to this
media (max-width: 100%)
But I have no idea how to do that using stylish.. ideas?
To override a media query you just need to load another media query - that also applies to your device - after it.
Well...you want a blunt media query that applies to everything. The best way is to use #media (min-width: 1px) since that includes all devices.
Now, put it all together - along with some other CSS cleanups like padding and margin removal and setting a new width for .mainContainer and you get this
#sidebar {
display: none;
}
#media (min-width: 1px) {
.mainContainer {
margin: 0 auto;
width: 100vw;
padding: 0;
}
body>.container {
padding: 0;
}
}
New code: (with different selector for width)
#sidebar {
display: none;
}
#media (min-width: 1px) {
.mainContainer { /*example styles*/
margin: 0 auto;
width: 100vw;
}
body>.container {
padding: 0;
}
body>.mainContainer>main {
max-width: 100vw!important;
}
}
You still have to adjust the padding to your preference as setting the padding to 0 breaks the design a little bit but this should be good starting point.
Before:
After:

Pure CSS if/ else statement involving custom unit of size variables

I want to solve my issue only using pure CSS.
Here's the problematic code that I have:
#if (100vh > 830px) {:root { --cwv:100vh;}}
#else {:root { --cwv: 830px;}}
What I'm trying to do: if browser window size is smaller than 830px, the "- -cvw" (custom width variable/ unit) should be relative (another problem that my code probably has) to 830px rather than 100vw (built-in viewport "vertical width" unit), as the elements on the page get too small.
I know I can use multiple other ways to solve this problem using other languages, but I am just wondering how to make the CSS code work - as it is supposed to - according to the places that I have researched:
CSS custom properties (variables) - states that variables are declared in the following manner: :root{--variable-name: variable-value;}
CSS Conditionals (if/ else statements)
What am I doing wrong? I expect that I have multiple syntax errors in my code (that I've provided above) too... :/
Use media queries max-width.
Example:
Default --cwx set to viewport width:
:root{
--cwv: 100vw;
}
In case where viewport width is lesser or equal 830px, set --cwx to 830px:
#media all and (max-width: 830px){
:root{
--cwv: 830px;
}
}
Finally, example's black bar will be set to ½ of --cwx, thus ½ of viewport width, but not less than ½ of 830px (=415px):
:root{
--cwv: 100vw;
}
#media all and (max-width: 830px){
:root{
--cwv: 830px;
}
}
body{
margin: 0;
}
:root::after{
content: "";
display: block;
background: black;
height: 10px;
width: calc(var(--cwv) * .5);
}
use media queries for window size like this below
#media screen and (min-width : 830 px) {
/* your code */
}

Media queries in less with variables-need global variables

I am looking for a solution where I define 1 variable globally and than overwrite it inside a media query - without putting the entire code in it (like LESS CSS set variables in media query?).
I thought something like that(defining):
#media (min-width: 768px) {
#BWInputHeight: 40px;
}
#media (max-width: 768px) {
//responsive screens
#BWInputHeight: 20px;
}
And using it like that:
.dataTables_filter input {
.form-control;
max-width: 135px;
display: inline-block;
height: #BWInputHeight;
padding: 1px 6px;
margin-right: 15px;
}
The problem here, "#BWInputHeight" is a undeclared variable. How can I solve this with LESS ?
You can sort of achieve this by using list arrays for each property and screen-width (like the below sample):
#BWInputHeight: '20px','40px','60px'; // Height of the button for min-width=320 and min-width=768 respectively
#minwidths: '320px','768px','1024px'; // The widths for which you need the media queries to be created
.loop-column(#index) when (#index > 0) { // Loop to iterate through each value in #minwidths and form the corresponding output
.loop-column(#index - 1);
#width: extract(#minwidths, #index); // extracts width based on array index
#media (min-width: e(#width)){
.dataTables_filter input{
height: e(extract(#BWInputHeight,#index)); // extracts button height for the corresponding screen width
max-width: 135px;
display: inline-block;
padding: 1px 6px;
margin-right: 15px;
}
}
}
.loop-column(length(#minwidths)); // calling the function
Demo in Code-pen - Modify output area width to see difference and click the eye icon in CSS tab to see compiled CSS.
Note: As per this Stack Overflow thread, both dotless and less.js should be 99% compatible and hence I have given this answer. In case this doesn't work for you, I will happily have this answer removed.

Media Queries - In between two widths

I'm trying to use CSS3 media queries to make a class that only appears when the width is greater than 400px and less than 900px. I know this is probably extremely simple and I am missing something obvious, but I can't figure it out. What I have come up with is the below code, appreciate any help.
#media (max-width:400px) and (min-width:900px) {
.class {
display: none;
}
}
You need to switch your values:
/* No less than 400px, no greater than 900px */
#media (min-width:400px) and (max-width:900px) {
.foo {
display:none;
}
}​
Demo: http://jsfiddle.net/xf6gA/ (using background color, so it's easier to confirm)
#Jonathan Sampson i think your solution is wrong if you use multiple #media.
You should use (min-width first):
#media screen and (min-width:400px) and (max-width:900px){
...
}
just wanted to leave my .scss example here, I think its kinda best practice, especially I think if you do customization its nice to set the width only once! It is not clever to apply it everywhere, you will increase the human factor exponentially.
Im looking forward for your feedback!
// Set your parameters
$widthSmall: 768px;
$widthMedium: 992px;
// Prepare your "function"
#mixin in-between {
#media (min-width:$widthSmall) and (max-width:$widthMedium) {
#content;
}
}
// Apply your "function"
main {
#include in-between {
//Do something between two media queries
padding-bottom: 20px;
}
}
.class {
display: none;
}
#media (min-width:400px) and (max-width:900px) {
.class {
display: block; /* just an example display property */
}
}

Resources