[css] Can you use if/else conditions in CSS?

I would like to use conditions in my CSS.

The idea is that I have a variable that I replace when the site is run to generate the right style-sheet.

I want it so that according to this variable the style-sheet changes!

It looks like:

[if {var} eq 2 ]
    background-position : 150px 8px;
[else]
    background-position : 4px 8px; 

Can this be done? How do you do this?

This question is related to css stylesheet conditional-statements

The answer is


Below is my old answer which is still valid but I have a more opinionated approach today:

One of the reasons why CSS sucks so much is exactly that it doesn't have conditional syntax. CSS is per se completely unusable in the modern web stack. Use SASS for just a little while and you'll know why I say that. SASS has conditional syntax... and a LOT of other advantages over primitive CSS too.


Old answer (still valid):

It cannot be done in CSS in general!

You have the browser conditionals like:

/*[if IE]*/ 
body {height:100%;} 
/*[endif]*/

But nobody keeps you from using Javascript to alter the DOM or assigning classes dynamically or even concatenating styles in your respective programming language.

I sometimes send css classes as strings to the view and echo them into the code like that (php):

<div id="myid" class="<?php echo $this->cssClass; ?>">content</div>

You could create two separate stylesheets and include one of them based on the comparison result

In one of the you can put

background-position : 150px 8px;

In the other one

background-position : 4px 8px;

I think that the only check you can perform in CSS is browser recognition:

Conditional-CSS


You can use php if you write css in the Tag

<style>
    section {
        position: fixed;
        top: <?php if ($test == $tset) { echo '10px' }; ?>;
    }
</style

You can use not instead of if like

.Container *:not(a)
{
    color: #fff;
}

As far as i know, there is no if/then/else in css. Alternatively, you can use javascript function to alter the background-position property of an element.


CSS has a feature: Conditional Rules. This feature of CSS is applied based on a specific condition. Conditional Rules are:

  • @supports
  • @media
  • @document

Syntax:

@supports ("condition") {

   /* your css style */

}

Example code snippet:

_x000D_
_x000D_
<!DOCTYPE html> 
<html> 
<head> 
    <title>Supports Rule</title> 
    <style>      
        @supports (display: block) { 
            section h1 { 
                background-color: pink; 
                color: white; 
            } 
            section h2 { 
                background-color: pink; 
                color: black; 
            } 
        } 
    </style> 
</head> 
<body> 
    <section> 
        <h1>Stackoverflow</h1> 
        <h2>Stackoverflow</h2> 
    </section> 
</body> 
</html> 
_x000D_
_x000D_
_x000D_


You can use javascript for this purpose, this way:

  1. first you set the CSS for the 'normal' class and for the 'active' class
  2. then you give to your element the id 'MyElement'
  3. and now you make your condition in JavaScript, something like the example below... (you can run it, change the value of myVar to 5 and you will see how it works)

_x000D_
_x000D_
var myVar = 4;_x000D_
_x000D_
if(myVar == 5){_x000D_
  document.getElementById("MyElement").className = "active";_x000D_
}_x000D_
else{_x000D_
  document.getElementById("MyElement").className = "normal";_x000D_
}
_x000D_
.active{_x000D_
  background-position : 150px 8px;_x000D_
  background-color: black;_x000D_
}_x000D_
.normal{_x000D_
  background-position : 4px 8px; _x000D_
  background-color: green;_x000D_
}_x000D_
div{_x000D_
  width: 100px;_x000D_
  height: 100px;_x000D_
  }
_x000D_
<div id="MyElement">_x000D_
  _x000D_
  </div>
_x000D_
_x000D_
_x000D_


You can use calc() in combination with var() to sort of mimic conditionals:

:root {
--var-eq-two: 0;
}

.var-eq-two {
    --var-eq-two: 1;
}

.block {
    background-position: calc(
        150px * var(--var-eq-two) +
        4px * (1 - var(--var-eq-two))
    ) 8px;
}

concept


Set the server up to parse css files as PHP and then define the variable variable with a simple PHP statement.

Of course this assumes you are using PHP...


(Yes, old thread. But it turned up on top of a Google-search so others might be interested as well)

I guess the if/else-logic could be done with javascript, which in turn can dynamically load/unload stylesheets. I haven't tested this across browsers etc. but it should work. This will get you started:

http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml


I am surprised that nobody has mentioned CSS pseudo-classes, which are also a sort-of conditionals in CSS. You can do some pretty advanced things with this, without a single line of JavaScript.

Some pseudo-classes:

  • :active - Is the element being clicked?
  • :checked - Is the radio/checkbox/option checked? (This allows for conditional styling through the use of a checkbox!)
  • :empty - Is the element empty?
  • :fullscreen - Is the document in full-screen mode?
  • :focus - Does the element have keyboard focus?
  • :focus-within - Does the element, or any of its children, have keyboard focus?
  • :has([selector]) - Does the element contain a child that matches [selector]? (Sadly, not supported by any of the major browsers.)
  • :hover - Does the mouse hover over this element?
  • :in-range/:out-of-range - Is the input value between/outside min and max limits?
  • :invalid/:valid - Does the form element have invalid/valid contents?
  • :link - Is this an unvisited link?
  • :not() - Invert the selector.
  • :target - Is this element the target of the URL fragment?
  • :visited - Has the user visited this link before?

Example:

_x000D_
_x000D_
div { color: white; background: red }_x000D_
input:checked + div { background: green }
_x000D_
<input type=checkbox>Click me!_x000D_
<div>Red or green?</div>
_x000D_
_x000D_
_x000D_


You can add container div for all your condition scope.

Add the condition value as a class to the container div. (you can set it by server side programming - php/asp...)

<!--container div-->
<div class="true-value">
   <!-- your content -->
   <p>my content</p>
   <p>my content</p>
   <p>my content</p>
</div>

Now you can use the container class as a global variable for all elements in the div using a nested selector, without adding the class to each element.

.true-value p{
   background-color:green;
}
.false-value p{
   background-color:red;
}

This is a little extra info to the Boldewyn answer above.

Add some php code to do the if/else

if($x==1){
  print "<p class=\"normal\">Text</p>\n";
} else {
  print "<p class=\"active\">Text</p>\n";
}

If you're open to using jquery, you can set conditional statements using javascript within the html:

$('.class').css("color",((Variable > 0) ? "#009933":"#000"));

This will change the text color of .class to green if the value of Variable is greater than 0.


CSS is a nicely designed paradigm, and many of it's features are not much used.

If by a condition and variable you mean a mechanism to distribute a change of some value to the whole document, or under a scope of some element, then this is how to do it:

_x000D_
_x000D_
var myVar = 4;_x000D_
document.body.className = (myVar == 5 ? "active" : "normal");
_x000D_
body.active .menuItem {_x000D_
  background-position : 150px 8px;_x000D_
  background-color: black;_x000D_
}_x000D_
body.normal .menuItem {_x000D_
  background-position : 4px 8px; _x000D_
  background-color: green;_x000D_
}
_x000D_
<body>_x000D_
<div class="menuItem"></div>_x000D_
</body>
_x000D_
_x000D_
_x000D_

This way, you distribute the impact of the variable throughout the CSS styles. This is similar to what @amichai and @SeReGa propose, but more versatile.

Another such trick is to distribute the ID of some active item throughout the document, e.g. again when highlighting a menu: (Freemarker syntax used)

_x000D_
_x000D_
var chosenCategory = 15;_x000D_
document.body.className = "category" + chosenCategory;
_x000D_
<#list categories as cat >_x000D_
    body.category${cat.id} .menuItem { font-weight: bold; }_x000D_
</#list>
_x000D_
<body>_x000D_
<div class="menuItem"></div>_x000D_
</body>
_x000D_
_x000D_
_x000D_

Sure,this is only practical with a limited set of items, like categories or states, and not unlimited sets like e-shop goods, otherwise the generated CSS would be too big. But it is especially convenient when generating static offline documents.

One more trick to do "conditions" with CSS in combination with the generating platform is this:

_x000D_
_x000D_
.myList {_x000D_
   /* Default list formatting */_x000D_
}_x000D_
.myList.count0 {_x000D_
   /* Hide the list when there is no item. */_x000D_
   display: none;_x000D_
}_x000D_
.myList.count1 {_x000D_
   /* Special treatment if there is just 1 item */_x000D_
   color: gray;_x000D_
}
_x000D_
<ul class="myList count${items.size()}">_x000D_
<!-- Iterate list's items here -->_x000D_
<li>Something...</div>_x000D_
</ul>
_x000D_
_x000D_
_x000D_


Yet another option (based on whether you want that if statement to be dynamically evaluated or not) is to use the C preprocessor, as described here.


I've devised the below demo using a mix of tricks which allows simulating if/else scenarios for some properties. Any property which is numerical in its essence is easy target for this method, but properties with text values are.

This code has 3 if/else scenarios, for opacity, background color & width. All 3 are governed by two Boolean variables bool and its opposite notBool.

Those two Booleans are the key to this method, and to achieve a Boolean out of a none-boolean dynamic value, requires some math which luckily CSS allows using min & max functions.

Obviously those functions (min/max) are supported in recent browsers' versions which also supports CSS custom properties (variables).

_x000D_
_x000D_
var elm = document.querySelector('div')

setInterval(()=>{
  elm.style.setProperty('--width', Math.round(Math.random()*80 + 20))
}, 1000)
_x000D_
:root{
   --color1: lightgreen;
   --color2: salmon;
   --width: 70;  /* starting value, randomly changed by javascript every 1 second */
}

div{
 --widthThreshold: 50;
 --is-width-above-limit: Min(1, Max(var(--width) - var(--widthThreshold), 0));
 --is-width-below-limit: calc(1 - var(--is-width-above-limit));
 
 --opacity-wide: .4;     /* if width is ABOVE 50 */
 --radius-narrow: 10px;  /* if width is BELOW 50 */
 --radius-wide: 60px;    /* if width is ABOVE 50 */
 --height-narrow: 80px;  /* if width is ABOVE 50 */
 --height-wide: 160px;   /* if width is ABOVE 50 */
 
 --radiusToggle: Max(var(--radius-narrow), var(--radius-wide) * var(--is-width-above-limit));
 --opacityToggle: calc(calc(1 + var(--opacity-wide)) - var(--is-width-above-limit));
 --colorsToggle: var(--color1) calc(100% * var(--is-width-above-limit)), 
                 var(--color2) calc(100% * var(--is-width-above-limit)), 
                 var(--color2) calc(100% * (1 - var(--is-width-above-limit)));
  
 --height: Max(var(--height-wide) * var(--is-width-above-limit), var(--height-narrow));
 
 height: var(--height);
 text-align: center;
 line-height: var(--height);

 width: calc(var(--width) * 1%);
 opacity: var(--opacityToggle);
 border-radius: var(--radiusToggle);
 background: linear-gradient(var(--colorsToggle));

 transition: .3s;
}

/* prints some variables */
div::before{
  counter-reset: aa var(--width);
  content: counter(aa)"%";
}

div::after{
  counter-reset: bb var(--is-width-above-limit);
  content: " is over 50% ? "counter(bb);
}
_x000D_
<div></div>
_x000D_
_x000D_
_x000D_

Another simply way using clamp:

_x000D_
_x000D_
label{ --width: 150 }
input:checked + div{ --width: 400 }

div{
  --isWide: Clamp(0,   (var(--width) - 150) * 99999  , 1);
  width: calc(var(--width) * 1px);
  height: 150px;
  border-radius: calc(var(--isWide) * 20px); /* if wide - add radius */
  background: lightgreen;
}
_x000D_
<label>
<input type='checkbox' hidden> 
<div>Click to toggle width</div>
</label>
_x000D_
_x000D_
_x000D_

Best so far:

I have come up with a totally unique method, which is even simpler!

This method is so cool because it is so easy to implement and also to understand. it is based on animation step() function.

Since bool can be easily calculated as either 0 or 1, this value can be used in the step! if only a single step is defined, then the if/else problem is solved.

Using the keyword forwards persist the changes.

_x000D_
_x000D_
var elm = document.querySelector('div')

setInterval(()=>{
  elm.style.setProperty('--width', Math.round(Math.random()*80 + 20))
}, 1000)
_x000D_
:root{
   --color1: salmon;
   --color2: lightgreen;
}

@keyframes if-over-threshold--container{
  to{ 
     --height: 160px;
     --radius: 30px;
     --color: var(--color2);
     opacity: .4; /* consider this as additional, never-before, style */
  }
}

@keyframes if-over-threshold--after{
  to{ 
    content: "true"; 
    color: green; 
  }
}

div{
 --width: 70;           /* must be unitless */
 --height: 80px;
 --radius: 10px;
 --color: var(--color1);
 --widthThreshold: 50;
 --is-width-over-threshold: Min(1, Max(var(--width) - var(--widthThreshold), 0));

 
 text-align: center;
 white-space: nowrap;
 transition: .3s;
 
 /* if element is narrower than --widthThreshold */
 width: calc(var(--width) * 1%);
 height: var(--height);
 line-height: var(--height);
 border-radius: var(--radius);
 background: var(--color);

 /* else */
 animation: if-over-threshold--container forwards steps(var(--is-width-over-threshold));
}

/* prints some variables */
div::before{
  counter-reset: aa var(--width);
  content: counter(aa)"% is over 50% width ? ";
}

div::after{
  content: 'false'; 
  font-weight: bold; 
  color: darkred;
  
  /* if element is wider than --widthThreshold */
  animation: if-over-threshold--after forwards steps(var(--is-width-over-threshold)) ;
}
_x000D_
<div></div>
_x000D_
_x000D_
_x000D_


I've found a Chrome bug which I have reported that can affect this method in some situations where specific type of calculations is necessary, but there's a way around it.

https://bugs.chromium.org/p/chromium/issues/detail?id=1138497


Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to stylesheet

How to display 3 buttons on the same line in css Vertical align middle with Bootstrap responsive grid How to style SVG with external CSS? Add a link to an image in a css style sheet background-image: url("images/plaid.jpg") no-repeat; wont show up How to play CSS3 transitions in a loop? Stylesheet not updating Make a table fill the entire window HTML not loading CSS file In which order do CSS stylesheets override?

Examples related to conditional-statements

How to have multiple conditions for one if statement in python Excel - programm cells to change colour based on another cell Using OR & AND in COUNTIFS C error: Expected expression before int Conditional Replace Pandas SELECT query with CASE condition and SUM() Simpler way to check if variable is not equal to multiple string values? Replace all elements of Python NumPy Array that are greater than some value How can I check if a string only contains letters in Python? Check if year is leap year in javascript