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

120

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

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

Chcę, żeby zmienił się arkusz stylów zgodnie z tą zmienną!

To wygląda jak:

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

Czy można to zrobić? Jak Ty to robisz?

Haim Evgi
źródło
Co do cholery próbujesz zrobić, co wymagałoby warunków warunkowych CSS?
Sapphire_Brick

Odpowiedzi:

138

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

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

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

aw pliku CSS:

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

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


Są też preprocesory CSS, takie jak Sass . Możesz tam użyć warunków warunkowych , 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;
  }
}

Wadą jest to, że jesteś zobowiązany do wstępnego przetwarzania swoich arkuszy stylów i że warunek jest oceniany w czasie kompilacji, a nie w czasie wykonywania.


Nowszą cechą właściwego CSS są właściwości niestandardowe (inaczej zmienne CSS). Są one oceniane w czasie wykonywania (w obsługujących je przeglądarkach).

Dzięki nim możesz zrobić coś wzdłuż linii:

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

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

.two {
  background-color: black;
}

Na koniec możesz wstępnie przetworzyć swój arkusz stylów za pomocą ulubionego języka po stronie serwera. Jeśli używasz PHP, podaj style.css.phpplik, który wygląda mniej więcej tak:

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

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

Boldewyn
źródło
11
Dobra odpowiedź, chcę tylko dodać jedną kwestię dotyczącą buforowania: ponieważ przeglądarki buforują arkusze stylów i zwykle nie pobierają ich ponownie dla każdej strony, trudno jest polegać na „dynamicznych” arkuszach stylów generowanych przez PHP / [język-z-wyboru] . Nie tak to powinno działać. Jeśli potrzebujesz zmiany CSS, możesz oczywiście osadzić go na stronie, ale zaczyna to być sprzeczne z separacją treści / prezentacji.
deceze
3
W odniesieniu do tego, co powiedział deceze, nie oznacza to, że nie możesz mieć dynamicznie zmieniającej się strony internetowej. Arkusze stylów mogą pozostać statyczne i możesz zmieniać klasy elementów za pomocą javascript z lub bez jquery lub PHP, w ten sposób styl elementów może się zmienić.
csga5000,
a co jeśli chcesz stylizować paski przewijania? (nie możesz znaleźć :: - webkit-scrollbar-button w html)
Jerry
Tak? Co z tym? Sass, zmienne CSS i przetwarzanie po stronie serwera nie zależą od HTML. A może coś mi tu brakuje?
Boldewyn
15

Poniżej znajduje się moja stara odpowiedź, która jest nadal aktualna, ale dziś mam bardziej uparte podejście:

Jednym z powodów, dla których CSS jest tak bardzo do bani, jest to, że nie ma on składni warunkowej. CSS jest sam w sobie całkowicie bezużyteczny w nowoczesnym stosie internetowym. Użyj SASS tylko przez chwilę, a będziesz wiedział, dlaczego to mówię. SASS ma składnię warunkową ... i WIELE innych zalet w porównaniu z prymitywnym CSS.


Stara odpowiedź (nadal ważna):

W ogóle nie da się tego zrobić w CSS!

Masz warunki przeglądarki, takie jak:

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

Ale nikt nie powstrzymuje Cię przed używaniem Javascript do zmiany DOM lub dynamicznego przypisywania klas lub nawet łączenia stylów w Twoim języku programowania.

Czasami wysyłam klasy css jako ciągi do widoku i powtarzam je w kodzie w ten sposób (php):

<div id="myid" class="<?php echo $this->cssClass; ?>">content</div>
markus
źródło
14
Zaskoczony nikt nie wskazał, że ta warunkowa składnia nie istnieje w CSS. Komentarze warunkowe istnieją tylko w HTML.
BoltClock
12

Możesz używać calc()w połączeniu z, var()aby posortować naśladujące warunki:

: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;
}

pojęcie

yeedle
źródło
8

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

W jednym z możesz umieścić

background-position : 150px 8px;

W drugim

background-position : 4px 8px;

Myślę, że jedyne sprawdzenie, jakie możesz wykonać w CSS, to rozpoznawanie przeglądarki:

Warunkowy CSS

RaYell
źródło
8

Dziwię się, że nikt nie wspomniał o pseudoklasach CSS, które są również rodzajem warunków w CSS. Dzięki temu możesz zrobić całkiem zaawansowane rzeczy bez ani jednej linii JavaScript.

Niektóre pseudoklasy:

  • : active - Czy klikany element?
  • : zaznaczone - Czy radio / pole wyboru / opcja są zaznaczone? (Pozwala to na warunkowe stylizowanie za pomocą pola wyboru!)
  • : empty - Czy element jest pusty?
  • : fullscreen - Czy dokument jest w trybie pełnoekranowym?
  • : focus - czy element ma fokus klawiatury?
  • : focus-within - czy element lub którekolwiek z jego elementów podrzędnych ma fokus klawiatury?
  • : has ([selector]) - Czy element zawiera element potomny, który pasuje do [selector]? (Niestety, nie jest obsługiwany przez żadną z głównych przeglądarek).
  • : hover - czy mysz znajduje się nad tym elementem?
  • : in-range /: out-of-range - Czy wartość wejściowa znajduje się między / poza minimalnymi i maksymalnymi limitami?
  • : nieważne /: poprawne - Czy element formularza ma nieprawidłową / prawidłową zawartość?
  • : link - Czy to nie odwiedzony link?
  • : not () - Odwróć selektor.
  • : target - czy ten element jest celem fragmentu adresu URL?
  • : odwiedzone - Czy użytkownik odwiedził już ten link?

Przykład:

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

Piotr
źródło
6

Ustaw serwer tak, aby parsował pliki css jako PHP, a następnie zdefiniuj zmienną zmienną za pomocą prostej instrukcji PHP.

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

żebrze
źródło
2
Możesz zamienić „PHP” na „Twój wybrany język programowania lub tworzenia szablonów”
Quentin,
1
Problem w tym, że jeśli twój CSS ma 50kb, a zmieniasz tylko kilka wartości, czy nie lepiej byłoby być statycznym i buforowanym?
Alex
2
tak, ale możesz wyodrębnić części, aby potrzebować dynamiki i ponownie dołączyć je za pośrednictwem @import url('dynamic.css.php').
Boldewyn
To zależy od warunków. Jeśli są one stabilne dla każdego użytkownika, można wyprowadzić zwykłe nagłówki kontroli pamięci podręcznej.
Quentin
5

Możesz użyć not zamiast if like

.Container *:not(a)
{
    color: #fff;
}
Kurkula
źródło
3

O ile wiem, w css nie ma if / then / else. Alternatywnie możesz użyć funkcji javascript do zmiany właściwości background-position elementu.

hadi teo
źródło
3

Jeszcze inną opcją (w zależności od tego, czy chcesz, aby instrukcja była obliczana dynamicznie, czy nie) jest użycie preprocesora C, jak opisano tutaj .

Michiel Buddingh
źródło
3

(Tak, stary wątek. Ale pojawił się w wyszukiwarce Google, więc inni też mogą być zainteresowani)

Wydaje mi się, że logikę if / else można wykonać za pomocą javascript, który z kolei może dynamicznie ładować / usuwać arkusze stylów. Nie testowałem tego w różnych przeglądarkach itp., Ale powinno działać. To pozwoli Ci zacząć:

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

josteinaj
źródło
3

To trochę dodatkowych informacji do powyższej odpowiedzi Boldewyn.

Dodaj trochę kodu PHP, aby wykonać if / else

if($x==1){
  print "<p class=\"normal\">Text</p>\n";
} else {
  print "<p class=\"active\">Text</p>\n";
}
Johan
źródło
3

Możesz dodać element div kontenera dla całego zakresu warunku.

Dodaj wartość warunku jako klasę do elementu div kontenera. (można to 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żyć 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;
}
amichai
źródło
2

W tym celu możesz użyć javascript w ten sposób:

  1. najpierw ustawiasz CSS dla „normalnej” klasy i dla „aktywnej” klasy
  2. następnie nadajesz swojemu elementowi identyfikator „MyElement”
  3. a teraz ustawiasz swój warunek w JavaScript, jak na poniższym przykładzie ... (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>

SeReGa
źródło
2

CSS to ładnie zaprojektowany paradygmat, a wiele z jego funkcji jest rzadko używanych.

Jeśli przez warunek i zmienną masz na myśli mechanizm rozprowadzania zmiany jakiejś wartości na cały dokument lub w zakresie 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 rozkładasz wpływ zmiennej na style CSS. Jest to podobne do tego, co proponują @amichai i @SeReGa, ale bardziej wszechstronne.

Inną taką sztuczką jest rozprowadzenie identyfikatora jakiejś aktywnej pozycji 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 ze sklepu internetowego, w przeciwnym razie wygenerowany CSS byłby zbyt duży. Jest to jednak szczególnie wygodne przy generowaniu statycznych dokumentów offline.

Jeszcze jedna sztuczka umożliwiająca wykonanie „warunków” za pomocą CSS w połączeniu z platformą generującą to:

.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>

Ondra Žižka
źródło
1

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 .classna zielony, jeśli wartość zmiennej jest większa niż 0.

Kyle Lillie
źródło
-1

po prostu zrób to w html za pomocą operatora trójargumentowego, a nie if else

class = "{{warunek? 'klasa1': 'klasa2'}}"

lub

[ngClass] = "stan? 'klasa1': 'klasa2'"

Gaurav Panwar
źródło
-2

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

<style>
    section {
        position: fixed;
        top: <?php if ($test == $tset) { echo '10px' }; ?>;
    }
</style
Tomek
źródło