• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

CSS - inline transform

VPS Starter Arubacloud
+1 głos
181 wizyt
pytanie zadane 22 listopada 2021 w HTML i CSS przez Billy Użytkownik (680 p.)

Hej,

Robię stronę internetową jako większy projekt, i do wykonania jednego jej elementu potrzebuję umieścić  transform(translateX(-100px)) bezpośrednio w linii, gdzie znajduje się dany element. Problem jest taki, że wtedy po najechaniu na element (class="box") nic się nie zmienia. Jeśli dokładnie ten sam kod umieszczę w sekcji <style> wszystko działa.

Poniżej zamieszczam kod uproszczony, pokazujący tylko problem (specjalnie spreparowany plik html z tym błędem).

<!DOCTYPE html>
<head>
</head>
<body>
<style>
    div{
        border: 1px solid red;
    }
        .container{
            display: flex;
            justify-content: center;
            align-items: center;
            
            width: 600px;
            height: 200px;
        }
        .box{
            width: 100px;
            height: 50px;
            transition: 1s transform;
            /* transform: translateX(-100px); */
        }
        .box:hover{
            transform: translateX(0);
        }
</style>

    <div class="container">
        <!-- Po zakomentowaniu style="transform: translateX(-100px)" 
        z poniższego diva i odkomentowaniu tej właściwości 
        wyżej (w <style> w .box) wszystko działa -->
        <div class="box active" style="transform: translateX(-100px)">
        </div>
    </div>

</body>
</html>

Wiecie, jaka może być tego przyczyna?

 

 

1
komentarz 23 listopada 2021 przez VBService Ekspert (251,210 p.)
edycja 23 listopada 2021 przez VBService

Dlaczego?

potrzebuję umieścić  transform(translateX(-100px)) bezpośrednio w linii, gdzie znajduje się dany element. 

 

 

Workaround   ("nieładny", ale ... "działa")  wink

<!DOCTYPE html>
<head>
  <style>
    div{
      border: 1px solid red;
    }
    .container{
      display: flex;
      justify-content: center;
      align-items: center;

      width: 600px;
      height: 200px;
    }
    .box{
      width: 100px;
      height: 50px;
      transition: transform 1s;            
    }
  </style>
</head>
<body> 
  <div class="container">
    <div class="box active" style="transform: translateX(-100px);" 
         onmouseover="this.style.transform='translateX(0)'"
         onmouseout="this.style.transform='translateX(-100px)'">
    </div>
  </div>
</body>
</html>

 

komentarz 23 listopada 2021 przez Billy Użytkownik (680 p.)

Dlaczego?

No więc już tłumaczę. Robię stronę - portfolio. Chciałbym na niej umieścić slajder, więc osobno stworzyłem projekt ze wzorem slajdera. Wszystko już działa, tylko chciałem dodać nieco "fajarwerków", żeby w zależności od klikniętej strzałki w tą stronę przesunął się slajd.

I tu się pojawia problem, bo samo przesuwanie działa, ale jak chciałem w JS dodać odpowiednie kierunki, to pojawiało się to inline-owo - stąd post na ten temat.

Teraz jednak sprawdziłem, i nawet eksportując te właściwości do osobnych klas i dodawanie ich w JS też nie działa (wcześniej szukałem prostszego rozwiązania, bo myślałem, że z klasami zadziała, ale brzydko by wyglądało :)).

Co więcej, nawet dodanie ich w HTMLu nie działa (wykomentowałem działanie JS w kwestii potencjalnej zmiany kierunku (żeby nie robić chaosu) i zostawiłem tylko tą zmianę w HTMLu).


Innymi słowy - mam klasę na każdy slajd - .slide - i gdy jest na niej transform i transition, to wszystko działa.
Gdy jednak wykomentuję te 2 właściwości i wrzucę je do osobnej klasy - .slideLeft / .slideRight -, a w HTMLu dopiszę tą nową klasę, to już się rozkracza i nie działa.

P.S. Ustawiłem tylko 50% na transformie, żeby było widać co się dzieje z tym slidem (ogólnie jest ustawiony na 100%, wtedy animacja jest płynna)

 

Poniżej cały kod:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>slider</title>
    <script src="script.js"></script>
    <link rel="stylesheet" href="style.css">
</head>
<body>

    <div class="container">
        <div class="center">
            <div id="slider">
                <span class="sButton" onclick="NextPrevButton(-1)"> &#10094;</span>
                <div class="slide slideLeft" id="s1" > NIENAWIDZĘ </div>
                <div class="slide slideLeft" id="s2" > SWOJEGO </div>
                <div class="slide slideLeft" id="s3" > ŻYCIA </div>
                <div class="slide slideLeft" id="s4" > :) </div>
                <span class="sButton" onclick="NextPrevButton(1)"> &#10095;</span>
            </div>
            <div id="buttons">
                <span class="sDot" onclick="chooseSlide(0); "></span>
                <span class="sDot" onclick="chooseSlide(1)"></span>
                <span class="sDot" onclick="chooseSlide(2)"></span>
                <span class="sDot" onclick="chooseSlide(3)"></span>
            </div>
        </div>
    </div>
</body>
</html>

body{
    background-color: rgb(46, 46, 46);
    color: white;
    font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
    font-size: xxx-large;
}
.container{
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
}
#slider{
    border: 1px solid red;
    height: 300px;
    width: 700px;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
}
.slide{
    display: inline-flex;
    justify-content: center;
    align-items: center;
    /* text-align: center; */

    background-color: red;
    width: 100%;
    height: 100%;
    transition: transform 1s;
}
#s1{background-color: rgb(128, 128, 128);}
#s2{background-color: rgb(102, 102, 102);}
#s3{background-color: rgb(88, 88, 88);}
#s4{background-color: rgb(65, 65, 65);}

#buttons{
    margin-top: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.sDot{
    width: 15px;
    height: 15px;
    margin: 10px;
    outline: red solid 3px;
    outline-offset: 3px;
    border-radius: 50%;
}
.sDot:hover{
    background-color: rgb(179, 10, 10) !important;
    cursor: pointer;
}

.activeButton{
    background-color: red;
}
.sButton{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    font-size: 50px;
    width: 50px;
    height: 100%;
    color: red;
    cursor: pointer;
    user-select: none;
    z-index: 10;
}
    .sButton:hover{
        color: rgb(179, 10, 10);
    }
    .sButton:first-child{
        left: 0;
    }
    .sButton:last-child{
        right: 0;
    }

.slide {
    opacity: 1;
    visibility: hidden;
    display: none; 
/*jeśli odkomentuję 2 ostatnie klasy, to już nie działa 
(komentowanie 2 poniższych linii nie wpłwa na nic)*/
    transition: all 0.7s cubic-bezier(0.92, 0.05, 0.74, 0.76);
    transform: translateX(-50%);
}
    .active{
        opacity: 1;
        z-index: -10;
        visibility: visible;
        transform: translateX(0);
    }
    /* .slideLeft{
        transition: all 0.7s cubic-bezier(0.92, 0.05, 0.74, 0.76);
        transform: translateX(-50%);
    }
    .slideRight{
        transition: all 0.7s cubic-bezier(0.92, 0.05, 0.74, 0.76);
        transform: translateX(50%);
    } */

window.onload = changeSlide;
var nrSlide = 0; //Math.floor(Math.random()*4)-1;

var slides = document.getElementsByClassName("slide");
var dots = document.getElementsByClassName("sDot");

var TIMER_changeSlide = 0, fadeOut = 0;
var sChangeDuration = 3000, fadeOutDuration = 700;

var slideLeft = true;

function changeSlide()
{
    if(nrSlide > slides.length - 1) 
        nrSlide = 0;
    chooseSlide(nrSlide);
}

function NextPrevButton(n) 
{
    //setting flag to change direction of sliding
    // if(n = -1) {slideLeft = true}
    // else {slideTrue = false}

    nrSlide += n - 1;
    if(nrSlide < 0) {nrSlide = slides.length - 1;}
    if(nrSlide > slides.length - 1) {nrSlide = 0;}
        
    chooseSlide(nrSlide);
}

function chooseSlide(n)
{
    clearTimeout(TIMER_changeSlide);

    nrSlide = n;
    slideImage();

    for(i = 0; i < slides.length; i++){
        dots[i].style.background = "transparent";
    }
    dots[n].style.background = "red";

    TIMER_changeSlide = setTimeout(changeSlide, sChangeDuration);
}


function slideImage()
{
    //clearing fade out (double-click issue)
    clearTimeout(fadeOut); 
    // remove active class from current activated image
    for(i = 0; i < slides.length; i++){
        // if(slideLeft)
        // {
        //     slides[i].classList.add('slideLeft');
        //     slides[i].classList.remove('slideRight');
        // }
        // else
        // {
        //     slides[i].classList.add('slideRight');
        //     slides[i].classList.remove('slideLeft');
        // }

        slides[i].classList.remove('active');
        slides[i].style.position = "absolute";
        
    }
    
    

    if(nrSlide == slides.length){ nrSlide = 0; }
    slides[nrSlide].style.display = 'flex';
            
    slides[nrSlide].classList.add('active');
    nrSlide++;

    // wait for fade effect to finish,  then add display none to current image and activate next one
    fadeOut = setTimeout(
        function()
        {                 
            //add display none to current image
            for(i = 0; i < slides.length; i++){
                if(nrSlide - 1 != i){
                    slides[i].style.display = 'none';
                }
            }
        }, fadeOutDuration);
}

 

2 odpowiedzi

+2 głosów
odpowiedź 23 listopada 2021 przez ScriptyChris Mędrzec (190,190 p.)

Styl inline-owy ma wyższy priorytet względem tego w CSS, więc :hover nie działa - możesz to sprawdzić w devtoolsach przeglądarki.

Pytanie, dlaczego zależy Ci na tym, żeby styl był bezpośrednio na elemencie, zamiast w CSS?

komentarz 23 listopada 2021 przez Billy Użytkownik (680 p.)

Za chwilę wszystko wytłumaczę w komentarzu kolegi wyżej, natomiast pytanie - czemu :hover nie działa, skoro zmieniam tylko pozycję poza :hover'em?

1
komentarz 23 listopada 2021 przez VBService Ekspert (251,210 p.)
edycja 23 listopada 2021 przez VBService

:hover - działa

<!DOCTYPE html>
<head>
</head>
<body>
<style>
    div{
        border: 1px solid red;
    }
        .container{
            display: flex;
            justify-content: center;
            align-items: center;
             
            width: 600px;
            height: 200px;
        }
        .box{
            width: 100px;
            height: 50px;
            transition: 1s transform;
            /* transform: translateX(-100px); */
        }
        .box:hover{
            transform: translateX(0);
          background-color: green; /* DZIAŁA */
        }
</style>
 
    <div class="container">
        <!-- Po zakomentowaniu style="transform: translateX(-100px)" 
        z poniższego diva i odkomentowaniu tej właściwości 
        wyżej (w <style> w .box) wszystko działa -->
        <div class="box active" style="transform: translateX(-100px)">
        </div>
    </div>
 
</body>
</html>

 

tylko właściwość transform ustawiona bezpośrednio w atrybucie style elementu nie działa, gdy :hover "wywoływany" jest z elementu <style>, bo

Styl inline-owy ma wyższy priorytet względem tego w CSS

 

komentarz 23 listopada 2021 przez Billy Użytkownik (680 p.)

Czyli transform w atrybucie style nadpisuje nawet transform w :hoverze?

P.S. Opisałem sytuację w komentarzu w odpowiedzi wyżej

0 głosów
odpowiedź 23 listopada 2021 przez VBService Ekspert (251,210 p.)
edycja 23 listopada 2021 przez VBService

Widać z "grubsza", że pomysł miałeś dobry, ale "poległeś" na

if (slideLeft)
{
     slides[i].classList.add('slideLeft');
     slides[i].classList.remove('slideRight');
}
else
{
     slides[i].classList.add('slideRight');
     slides[i].classList.remove('slideLeft');
 }

jest na to "lekarstwo", np.:  void element.offsetWidth;


What does "void element.offsetWidth;" do?
 (W poście jest wyjaśnione "o co kaman" wink )

When you make changes to the dom, such as classList.remove('run-animation'), this can result in a cascade of changes to the page. Rendering those changes can be expensive, and since it's pretty common that you'll change multiple things in a row, browsers try to batch up accumulated changes and only perform the calculation at the end of what you're doing.

 

chodzi o ten "trik"

slides[i].classList.add('slideLeft');
void slides[i].offsetWidth;
slides[i].classList.remove('slideRight');

 

komentarz 23 listopada 2021 przez Billy Użytkownik (680 p.)

Tylko na razie problem polega na tym, że nawet bez JS to nie działa - 

Innymi słowy - mam klasę na każdy slajd - .slide - i gdy jest na niej transform transition, to wszystko działa.
Gdy jednak wykomentuję te 2 właściwości i wrzucę je do osobnej klasy - .slideLeft / .slideRight -, a w HTMLu dopiszę tą nową klasę, to już się rozkracza i nie działa.

Wykomentowałem specjalnie zmianę tych klas w JS, żeby można się było skupić na tym, dlaczego już w HTMLu nie działa.

Po prostu to co było w .slide przeniosłem do .slideLeft, dodałem tą klasę do aytybutu class="" w HTMLu, i już w tym momencie nie działa, jeszcze bez wprowadzania JSa.

Aczkolwiek pewnie za chwilę twoja rada się przyda ;P

komentarz 23 listopada 2021 przez Billy Użytkownik (680 p.)

@VBService, Mógłbyś zerknąć na tego CSS i zobaczyć, czemu gdy odkomentuję tą klasę .slideLeft to slider się psuje? Dodawanie tych klas przez JS jest na razie wyłączone w tym kodzie wyżej, więc tylko .slideLeft jest na sztywno wpisane do HTMLa

Podobne pytania

+1 głos
0 odpowiedzi 735 wizyt
pytanie zadane 28 lutego 2021 w HTML i CSS przez lukasz21 Obywatel (1,090 p.)
0 głosów
1 odpowiedź 103 wizyt
pytanie zadane 25 czerwca 2018 w HTML i CSS przez grands14320 Obywatel (1,080 p.)
0 głosów
2 odpowiedzi 161 wizyt
pytanie zadane 6 maja 2018 w HTML i CSS przez Tradereu Użytkownik (780 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...