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

CSS - inline transform

Aruba Cloud - Virtual Private Server VPS
+1 głos
288 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 (256,600 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 (256,600 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 (256,600 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 1,023 wizyt
pytanie zadane 28 lutego 2021 w HTML i CSS przez lukasz21 Obywatel (1,090 p.)
0 głosów
1 odpowiedź 133 wizyt
pytanie zadane 25 czerwca 2018 w HTML i CSS przez grands14320 Obywatel (1,080 p.)
0 głosów
2 odpowiedzi 199 wizyt
pytanie zadane 6 maja 2018 w HTML i CSS przez Tradereu Użytkownik (780 p.)

93,335 zapytań

142,331 odpowiedzi

322,415 komentarzy

62,670 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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...