Czy możesz użyć warunków if / else w CSS?

Chciałbym użyć warunków w moim CSS.

Chodzi o to, że mam zmienną, którą zastępuję, gdy strona jest uruchomiona, aby wygenerować odpowiedni arkusz stylów.

Chcę, aby zgodnie z tą zmienną zmieniał się arkusz stylów!

Wygląda tak:

[if {var} eq 2 ]
    background-position : 150px 8px;
[else]
    background-position : 4px 8px; 
Czy Można to zrobić? Jak ty to robisz?
Author: Matthew Strawbridge, 2009-07-15

18 answers

Nie w tradycyjnym sensie, ale możesz użyć klas do tego, jeśli masz dostęp do HTML. Rozważ to:

<p class="normal">Text</p>

<p class="active">Text</p>

I w pliku CSS:

p.normal {
  background-position : 150px 8px;
}
p.active {
  background-position : 4px 8px;
}

To jest CSS sposób, aby to zrobić.


Następnie są preprocesory CSS, takie jak Sass. Możesz tam użyć conditionals , które wyglądałyby tak:

$type: monster;
p {
  @if $type == ocean {
    color: blue;
  } @else if $type == matador {
    color: red;
  } @else if $type == monster {
    color: green;
  } @else {
    color: black;
  }
}

Wady są takie, że musisz wstępnie przetworzyć arkusze stylów i że warunek jest oceniany podczas kompilacji czas, nie czas biegu.


Nowszymi cechami CSS proper są właściwości niestandardowe (vel zmienne CSS). Są one oceniane w czasie wykonywania (w przeglądarkach je obsługujących).

Z nimi możesz zrobić coś wzdłuż linii:

:root {
  --main-bg-color: brown;
}

.one {
  background-color: var(--main-bg-color);
}

.two {
  background-color: black;
}

Wreszcie, możesz preprocesować swój arkusz stylów za pomocą ulubionego języka po stronie serwera. Jeśli używasz PHP, podaj plik style.css.php, który wygląda mniej więcej tak:

p {
  background-position: <?php echo (@$_GET['foo'] == 'bar')? "150" : "4"; ?>px 8px;
}

W tym przypadku, będziesz jednak mieć wpływ na wydajność, ponieważ buforowanie takiego arkusza stylów będzie trudne.

 146
Author: Boldewyn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-29 19:13:04

Poniżej moja stara odpowiedź, która jest nadal aktualna, ale mam bardziej opiniotwórcze podejście dzisiaj:

Jednym z powodów, dla których CSS tak bardzo jest do bani, jest to, że nie ma składni warunkowej. CSS jest sam w sobie całkowicie bezużyteczny we współczesnym stosie internetowym. Użyj SASS przez chwilę, a będziesz wiedział, dlaczego to mówię. SASS ma składnię warunkową... i wiele innych zalet w stosunku do prymitywnych CSS zbyt.


Stara odpowiedź (nadal ważna):

Nie można tego zrobić w CSS w Generale!

Masz Warunki przeglądarki takie jak:

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

Ale nikt nie zabrania ci używać Javascript do zmiany DOM lub przypisywania klas dynamicznie lub nawet łączenia stylów w danym języku programowania.

Czasami wysyłam klasy css jako ciągi znaków do widoku i echo ich do kodu w ten sposób (php):

<div id="myid" class="<?php echo $this->cssClass; ?>">content</div>
 14
Author: markus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 20:33:11

Możesz użyć calc() w połączeniu z var() do pewnego rodzaju naśladowania uwarunkowań:

: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

 13
Author: yeedle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-20 16:08:45

Dziwię się, że nikt nie wspomniał o pseudoklasach CSS, które są również rodzajem warunków w CSS. Możesz zrobić kilka bardzo zaawansowanych rzeczy z tym, bez jednej linii JavaScript.

Niektóre pseudoklasy:

  • :aktywny-czy Element jest klikany?
  • :checked - czy radio/checkbox / opcja jest zaznaczona? (Pozwala to na warunkową stylizację poprzez użycie checkboxa!)
  • :empty - czy element jest pusty?
  • :fullscreen - jest dokumentem w trybie pełnoekranowym?
  • : focus - czy element ma klawiaturę focus?
  • : focus-within - czy element, lub któreś z jego dzieci, ma klawiaturę focus?
  • : has ([selektor]) - czy element zawiera potomek pasujący do [selektor]? (Niestety, nie jest obsługiwana przez żadną z głównych przeglądarek.)
  • :hover-czy mysz unosi się nad tym elementem?
  • : in-range/: out-of-range - czy wartość wejściowa mieści się pomiędzy / poza limitem min i max?
  • : invalid/: valid-Does the element formularza ma nieprawidłową / prawidłową zawartość?
  • :link-Czy to link nie odwiedzony?
  • : not () - Odwróć selektor.
  • :target - czy ten element jest celem fragmentu URL?
  • :visited - czy użytkownik odwiedził ten link wcześniej?

Przykład:

div { color: white; background: red }
input:checked + div { background: green }
<input type=checkbox>Click me!
<div>Red or green?</div>
 12
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-20 19:34:53

Możesz utworzyć dwa oddzielne arkusze stylów i dołączyć jeden z nich na podstawie wyniku porównania

W jednym z można umieścić

background-position : 150px 8px;

W drugim

background-position : 4px 8px;

Myślę, że jedynym sprawdzeniem, które można wykonać w CSS, jest rozpoznawanie przeglądarki:

Conditional-CSS

 7
Author: RaYell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-15 06:33:23

Możesz użyć not zamiast if like

.Container *:not(a)
{
    color: #fff;
}
 6
Author: Kurkula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-24 23:56:38

Ustaw serwer do parsowania plików css jako PHP, a następnie zdefiniuj zmienną zmienną za pomocą prostej instrukcji PHP.

Oczywiście zakłada się, że używasz PHP...

 5
Author: beggs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-15 06:26:39

To jest trochę dodatkowych informacji do Boldewyn odpowiedzi powyżej.

Dodaj kod php do if / else

if($x==1){
  print "<p class=\"normal\">Text</p>\n";
} else {
  print "<p class=\"active\">Text</p>\n";
}
 3
Author: Johan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-23 23:17:38

Opracowałem poniższe demo używając kombinacji trików, które pozwalają symulować if/else scenariusze dla niektóre właściwości. Każda właściwość, która jest liczbowa w swej istocie, jest łatwym celem dla tej metody, ale właściwości z wartościami tekstowymi są.

Ten kod ma 3 if/else scenariusze, dla opacity, background color & width. Wszystkie 3 są regulowane przez dwie zmienne logiczne bool i jej przeciwieństwo notBool.

Te dwa Booleany są kluczem do tej metody, a do osiągnąć wartość logiczną z wartości dynamicznej none-boolean, wymaga pewnej matematyki, która na szczęście CSS pozwala na użycie min & max funkcje.

oczywiście te funkcje (min / max) są obsługiwane w najnowszych wersjach przeglądarek, które również obsługują niestandardowe właściwości CSS (zmienne).

var elm = document.querySelector('div')

setInterval(()=>{
  elm.style.setProperty('--width', Math.round(Math.random()*80 + 20))
}, 1000)
: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);
}
<div></div>

Inny prosty sposób użycia clamp:

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;
}
<label>
<input type='checkbox' hidden> 
<div>Click to toggle width</div>
</label>

Najlepsze do tej pory:

Wymyśliłem całkowicie unikalna metoda, która jest jeszcze prostsza!

Ta metoda jest tak fajna, ponieważ jest tak łatwa do wdrożenia, a także do zrozumienia. opiera się ona na animation step() funkcja.

Ponieważ {[13] } można łatwo obliczyć jako 0 lub 1, wartość ta może być użyta w step! jeśli zdefiniowany jest tylko jeden krok, to problem if/else zostanie rozwiązany.

Używając słowa kluczowego forwards persist the zmiany.

var elm = document.querySelector('div')

setInterval(()=>{
  elm.style.setProperty('--width', Math.round(Math.random()*80 + 20))
}, 1000)
: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)) ;
}
<div></div>

Znalazłem błąd Chrome, który zgłosiłem, który może mieć wpływ na tę metodę w niektórych sytuacjach, gdy wymagany jest określony rodzaj obliczeń, ale istnieje sposób na obejście tego.

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

 3
Author: vsync,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-14 10:59:41

Z tego co wiem, w css nie ma if/then/else. Alternatywnie można użyć funkcji javascript, aby zmienić właściwość background-position elementu.

 2
Author: hadi teo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-15 06:24:14

Kolejną opcją (zależną od tego, czy instrukcja if ma być dynamicznie oceniana, czy nie) jest użycie preprocesora C, jak opisano tutaj .

 2
Author: Michiel Buddingh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-15 08:33:03

(tak, stary wątek. Ale okazało się na górze wyszukiwarki Google, więc inni mogą być zainteresowani, jak również)

Domyślam się, że logika if / else może być wykonana za pomocą javascript, który z kolei może dynamicznie ładować / rozładowywać arkusze stylów. Nie testowałem tego w przeglądarkach itp. ale powinno zadziałać. Na początek:

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

 2
Author: josteinaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-25 09:02:25

CSS jest ładnie zaprojektowanym paradygmatem, a wiele jego funkcji nie jest zbytnio używanych.

Jeśli przez warunek i zmienną masz na myśli mechanizm dystrybucji zmiany pewnej wartości na cały dokument, lub pod zakresem jakiegoś elementu, to tak to zrobić:

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

W ten sposób dzielisz wpływ zmiennej na style CSS. Jest to podobne do tego, co proponują @amichai i @ SeReGa, ale bardziej uniwersalne.

Inny taki trik polega na rozprowadzeniu ID jakiegoś aktywnego elementu w całym dokumencie, np. ponownie podczas podświetlania menu: (używana składnia Freemarker)

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

Jasne, jest to praktyczne tylko w przypadku ograniczonego zestawu elementów, takich jak Kategorie lub stany, a nie nieograniczonych zestawów, takich jak towary e-shop, w przeciwnym razie wygenerowany CSS byłby zbyt duży. Jest to jednak szczególnie wygodne podczas generowania statycznych dokumentów offline.

Jeszcze jedna sztuczka, aby zrobić "Warunki" z CSS w połączenie z platformą generującą jest takie:

.myList {
   /* Default list formatting */
}
.myList.count0 {
   /* Hide the list when there is no item. */
   display: none;
}
.myList.count1 {
   /* Special treatment if there is just 1 item */
   color: gray;
}
<ul class="myList count${items.size()}">
<!-- Iterate list's items here -->
<li>Something...</div>
</ul>
 2
Author: Ondra Žižka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-02 04:05:48

Możesz dodać kontener div dla całego zakresu warunków.

Dodaj wartość warunku jako klasę do kontenera div. (można go ustawić przez programowanie po stronie serwera-php / asp...)

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

Teraz możesz używać klasy kontenera jako zmiennej globalnej dla wszystkich elementów w div za pomocą zagnieżdżonego selektora, bez dodawania klasy do każdego elementu.

.true-value p{
   background-color:green;
}
.false-value p{
   background-color:red;
}
 2
Author: amichai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-25 12:00:09

Możesz użyć javascript w tym celu, w ten sposób:

  1. najpierw ustawiasz CSS dla klasy 'normal' i dla klasy' active '
  2. Następnie dajesz swojemu elementowi id 'MyElement'
  3. a teraz robisz swój stan w JavaScript, coś jak Poniższy przykład... (możesz go uruchomić, zmienić wartość myVar na 5 i zobaczysz, jak to działa)

var myVar = 4;

if(myVar == 5){
  document.getElementById("MyElement").className = "active";
}
else{
  document.getElementById("MyElement").className = "normal";
}
.active{
  background-position : 150px 8px;
  background-color: black;
}
.normal{
  background-position : 4px 8px; 
  background-color: green;
}
div{
  width: 100px;
  height: 100px;
  }
<div id="MyElement">
  
  </div>
 1
Author: SeReGa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-26 10:58:37

CSS posiada cechę: reguły warunkowe . Ta cecha CSS jest stosowana w oparciu o określony warunek. reguły warunkowe to:

  • @supports
  • @media
  • @document

Składnia:

@supports ("condition") {

   /* your css style */

}

Przykładowy fragment kodu:

<!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> 
 1
Author: yck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-13 12:21:31

Jeśli jesteś otwarty na używanie jquery, możesz ustawić instrukcje warunkowe za pomocą javascript w html:

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

Spowoduje to zmianę koloru tekstu .class na zielony, jeśli wartość zmiennej jest większa niż 0.

 0
Author: Kyle Lillie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-12 17:23:05

Możesz użyć php, jeśli napiszesz css w znaczniku

<style>
    section {
        position: fixed;
        top: <?php if ($test == $tset) { echo '10px' }; ?>;
    }
</style
 -2
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-09 19:40:10