CSS i Javascript

Ze stylowaniem elementów możemy działać na kilka sposobów.

classList

Po pierwsze możemy utworzyć odpowiednie klasy, a następnie aplikować je dla danych elementów. Aby zarządzać klasami css danego elementu użyjemy właściwości classList(), która udostępnia nam kilka metod:

add("nazwa-klasy", "nazwa-klasy"*, "nazwa-klasy"...) dodawanie klasy lub kilku klas
remove("nazwa-klasy", "nazwa-klasy"*, "nazwa-klasy"*) usuwanie klasy lub kilku klas
toggle("nazwa-klasy") przełączanie (jak nie ma to dodaje, jak jest to usuwa) klasy
contains("nazwa-klasy") sprawdza czy element ma taką klasę
replace("stara-klasa", "nowa-klasa") zamienia starą klasę na nową klasę

el.classList.add("btn");
el.classList.add("btn", "btn-primary");
el.classList.remove("btn");
el.classList.toggle("btn");
el.classList.contains("btn");
el.classList.replace("btn", "element");

A dodatkowo jest tego jeszcze kilka. Wystarczy złapać dany element, wypisać go za pomocą console.dir, a następnie rozwinąć właściwość classList.

Mamy też drugą właściwość - className. Zwraca ona listę klas danego elementu w formie tekstowej. Możemy ją też wykorzystać do dodania wielu klas na raz:


element.className = "button button-big button-important";
element.className += " inna-klasa inna-klasa2";

Osobiście wolę pozostać przy classList, ale kto co lubi.

style

Kolejnym sposobem dodawania styli jest użycie właściwości style. Dzięki niej możemy ustawić ale i odczytać style inline nadane dla danego elementu.


btn.style.backgroundColor = "#4BA2EA";
btn.style.fontSize = "1.6rem";
btn.style.borderRadius = "3rem";
btn.style.color = "#F7F781";

console.log("Kolor przycisku to: ", btn.style.backgroundColor);
console.log("Kolor tekstu to: ", btn.style.color);

Jeżeli właściwość składa się z jednego słowa, to zapisujemy ją tak jak w css. Jeżeli właściwość składa się z kilku słów oddzielonych myślnikiem, wtedy dla takiej właściwości musimy zastosować zapis camelCase. Możemy tutaj też zastosować zapis znany z obiektów:


el.style.fontSize = "1rem";
el.style.background = "linear-gradient(#fff, #ddd)";
el.style.backgroundColor = "rgba(255,255,255,0.5)";

//lub
el.style["font-size"] = "1rem";
el.style["background"] = "linear-gradient(#fff, #ddd)";
el.style["background-color"] = "rgba(255,255,255,0.5)";

Jak widzisz powyżej, za pomocą style możemy ustawiać wartości dla pojedynczych właściwości. Jeżeli chcielibyśmy ustawić kilka wartości na raz, możemy skorzystać z właściwości cssText:


el.style.cssText = `
    color: red;
    background: blue;
    padding: 10px;
`;

Staraj się też nie nadawać całych styli za pomocą powyższych właściwości. Stosuj je raczej tylko w przypadku, gdy dane style muszą być nadawane dynamicznie - np. gdy generujesz losowe tło dla elementu. Jeżeli jednak style są statyczne, o wiele lepszym rozwiązaniem będzie trzymanie ich w pliku css i dodawanie ich do elementu za pomocą classList. Dzięki temu oddzielasz warstwę wizualną od logicznej.

getComputedStyle()

Jeżeli ustawiamy style za pomocą powyższych sposobów, są one wstawiane inline w atrybucie style danego elementu.

style przycisku

Podobna zasada tyczy się odczytu. Jeżeli dany element nie ma ustawionych styli inline (wpisanych z palca w HTML, lub za pomocą JavaScript), to nie jesteśmy w stanie ich pobrać.


console.log(btn.style.fontSize); //""
console.log(btn.style.backgroundColor); //""

//ustawiamy style inline
btn.style.fontSize = "1.5rem";
btn.style.backgroundColor = "#4BA2EA";

console.log(btn.style.fontSize); //"1.5rem"
console.log(btn.style.backgroundColor); //"#4BA2EA"

Bardzo często będziemy chcieli pobrać style, które są zadeklarowane w arkuszach stylów, a nie inline w kodzie HTML. I w sumie - nie za bardzo możemy to zrobić.

Jesteśmy za to w stanie pobrać style przeliczone. Gdy badasz dany element w debugerze, w zakładce Elements pokazuje ci po prawej stronie jego style. Tuż obok zakładki Styles jest zakładka Computed, która pokazuje style przeliczone, czyli takie, jak je widzi przeglądarka (np. ty ustawiasz wielkość 2em, a przeglądarka widzi to jako 32px).

Zakładka computed

Żeby pobrać takie przeliczone stylowanie musimy skorzystać z funkcji
window.getComputedStyle(elem, pseudoElement*).

Pierwszy parametr tej metody określa element, dla którego chcemy pobrać przeliczone style. Drugi - opcjonalny - pozwala pobierać style dla pseudo elementów (wtedy podajemy selektor jako np. ::before lub ::after):


const btn = document.querySelector(".button");
const style = getComputedStyle(btn);

console.log( style.height );
console.log( style.backgroundColor );

Jak zauważysz, nie zawsze będą to style identyczne do tych jakie wpisałeś w pliku css. Przykładowo jeżeli my ustawimy kolor red, pobierzemy go w postaci rgb(255, 0, 0), jeżeli ustawimy wielkość w em, zwracana wartość będzie w px.

Style pobrane za pomocą getComputedStyle() są żywe (reagują na zmiany stylowania danego elementu) stan styli tylko do odczytu. Próba zmiany ich wartości zakończy się błędem.

setProperty() i getPropertyValue()

Gdy wypiszesz sobie w konsoli debugera obiekt element.style, zobaczysz, że udostępnia nam on jeszcze kilka ciekawych rzeczy.

Wśród nich są dwie metody:

element.style.setProperty(propertyName, value, priority*) służy do ustawiania stylowania. Ostatni opcjonalny parametr priority służy do ewentualnego dodania do danych styli deklaracji !important. Najczęściej jest pomijany.
element.style.getPropertyValue(property) służy do pobierania stylowania

el.style.setProperty("background-color", "#4BA2EA");
el.style.setProperty("font-size", "1.5rem");

el.style.getProperty("background-color");
el.style.getProperty("font-size");

Zastosowanie tych metod jak w powyższym kodzie jest raczej bez sensu, ponieważ właściwości takie możesz bez problemu ustawiać i pobierać za pomocą wcześniej pokazanej krótszej składni. Metody te mają jednak zastosowanie przy pracy ze zmiennymi css:


el.style.setProperty("--size", "1em");
el.style.getPropertyValue("--size"); //"1em"

A jeżeli połączymy to z pobieraniem przeliczonych styli, zmienne takie stają się swoistą furtką, która może łączyć css z Javascriptem:


const size = getComputedStyle(element).getPropertyValue("--size");

element.setProperty("--size", `{++size}`);

Co pozwala nam traktować to jako swoisty kolejny punkt komunikacji między JS-CSS.

Przykład 1 - zmiana koloru

W pierwszym przykładzie za pomocą inputa typu color zmieniamy właściwości elementu:

Zmień kolor i najedź kursorem

<div class="element">
    Zmień kolor i najedź kursorem
</div>

<input type="color" class="color">

.element {
    --color : red;

    border: 2px solid var(--color);
    color: var(--color);
    padding: 30px;
    font-weight: bold;
    text-transform: uppercase;
    font-family: sans-serif;
    position: relative;
    background: #eee;
    transition: 0.5s;
}
.element:hover {
    background-color: var(--color);
    color: #fff;
}

const element = document.querySelector(".element");
const inputColor = document.querySelector(".color");

inputColor.addEventListener("change", e => {
    element.style.setProperty("--color", inputColor.value)
});

Podobna technika zastosowana jest na tej stronie jeżeli chodzi o tryb jasny i ciemny.

Przykład 2 - zmiana po najechaniu

W kolejnym przykładzie pobieramy pozycję kursora na elemencie i ustawiamy mu pozycję pseudoelementu z gradientem. Dodatkowo na hover zmieniamy jego wielkość:


<button type="button" class="button-test">
    <span>KLIK</span>
</button>

.button-test {
    --size: 0;
    --left: 0;
    --top: 0;

    border: 0;
    padding: 20px 70px;
    border-radius: 50px;
    text-transform: uppercase;
    font-family: sans-serif;
    color: #fff;
    overflow: hidden;
    position: relative;
    background-color: tomato;
}

.button-test span {
    position: relative;
    z-index: 1;
}

.button-test:hover { /* wielkość gradientu zwiększam na hover */
    --size: 400px;
}

.button-test:after {
    content: "";
    position: absolute;
    left: var(--left);
    top: var(--top);
    width: var(--size);
    height: var(--size);
    background: radial-gradient(circle closest-side, #4405f7, tomato 60%);
    background-repeat: no-repeat;
    transform: translate(-50%, -50%);
    transition: 0.3s width, 0.3s height;
    z-index: 0;
}

const element = document.querySelector(".button-test");

element.addEventListener("mousemove", e => {
    const rect = element.getBoundingClientRect();
    element.style.setProperty("--left", `${e.pageX - (rect.left + window.scrollX)}px`);
    element.style.setProperty("--top", `${e.pageY - (rect.top + window.scrollY)}px`);
})

Przykład 3 - zmiana pozycji elementów

Ostatni przykład możesz zobaczyć na oddzielnej stronie. To jeden z moich eksperymentów odnośnie animacji w CSS. Tutaj także wykorzystałem powyższe techniki do animowania elementów.

Trening czyni mistrza

Jeżeli chcesz sobie potrenować zdobytą wiedzę z tego działu, to zadania znajdują się w repozytorium pod adresem: https://github.com/kartofelek007/zadania-dom

W repozytorium jest branch "solutions". Tam znajdziesz przykładowe rozwiązania.

Wszelkie prawa zastrzeżone. Jeżeli chcesz używać jakiejś części tego kursu, skontaktuj się z autorem.
Aha - i ta strona korzysta z ciasteczek.

Menu