Czy przetłumaczyć wartości procentowe X i Y na podstawie wysokości i szerokości elementów?

80

Przesunięcie elementu osi Y o 50% spowoduje przesunięcie go w dół o 50% jego własnej wysokości, a nie o 50% wysokości rodziców, jak bym się spodziewał. Jak powiedzieć elementowi tłumaczącemu, aby oparł procent tłumaczenia na elemencie nadrzędnym? A może czegoś nie rozumiem?

http://jsfiddle.net/4wqEm/2/

Andrew Tibbetts
źródło
6
W porządku, wygląda na to, że nie da się tego obejść. Tłumaczenie CSS w procentach bierze udział procentowy tłumaczonego elementu, aby obliczyć odległość do przesunięcia. Nie działa jak typowa deklaracja CSS, taka jak top, margin-top lub padding-top, które są oparte na kontenerze nadrzędnym.
Andrew Tibbetts
1
Dzięki, nie od razu było dla mnie jasne, jaki procent to procent.
Philip Walton,
3
Następną rzeczą, jaką wiesz, będzie to, że procenty będą stanowić średni procent rozmiaru czcionki! (oh ...)
Kevin Peno

Odpowiedzi:

41

Używając procentu w tłumaczeniu, odnosi się do szerokości lub wysokości samego siebie. Spójrz na https://davidwalsh.name/css-vertical-center ( demo ):

Interesującą rzeczą dotyczącą transformacji CSS jest to, że stosując je z wartościami procentowymi, opierają tę wartość na wymiarach elementu, na którym są implementowane, w przeciwieństwie do właściwości takich jak top, right, bottom, left, margin i padding , które używają tylko wymiarów rodzica (lub w przypadku pozycjonowania bezwzględnego, który używa swojego najbliższego krewnego rodzica).

Bowen
źródło
2
Ale w animowaniu SVG transform: translate(50%)wydaje się używać szerokości i wysokości elementu nadrzędnego
Atav32
27

Możesz użyć vw i vh, aby przetłumaczyć na podstawie rozmiaru widocznego obszaru

@keyframes bubbleup {
  0% {
    transform: translateY(100vh);
  }

  100% {
    transform: translateY(0vh);
  }
}
Kokodoko
źródło
To nie działa dla mnie ... vh ~ 40 jest jak dół strony ?!
AturSams
To było moje złe ... element nie był wewnątrz elementu absolutnego ... :)
AturSams
11
@AxeEffect To nie powinna być akceptowana odpowiedź. Dotyczy to rzutni, a nie elementu nadrzędnego. Co się stanie, jeśli element nadrzędny nie ma pełnego rozmiaru rzutni?
trusktr
@wolfdawn Jeśli używasz skalowania, porządek ma znaczenie. Więc „scale (1.5) translateY (40vw)” to nie to samo, co „translateY (40vw) scale (1.5)”.
Kardaw,
1
Powinieneś wiedzieć, że Apple i Google zepsuły jednostkę vh w przeglądarkach mobilnych, więc w takim przypadku jest to zawodne.
Kev
17

To, co działa u mnie tylko przy użyciu CSS, to:

.child {
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);

    /* Backward compatibility */
    -webkit-transform: translate(-50%, -50%);
    -moz-transform: translate(-50%, -50%);
    -o-transform: translate(-50%, -50%);
    -ms-transform: translate(-50%, -50%);
}

Jak to działa:

  • pozycjonowanie w górę iw lewo przesuwa widżet podrzędny zgodnie ze współrzędnymi rodzica. Lewy górny róg widżetu dziecka pojawi się dokładnie na środku rodzica (nie tego chcemy w tej chwili).
  • tłumaczenie przesunie widżet potomny -50% na górę i w lewo w zależności od jego rozmiaru (nie nadrzędnego). Oznacza to, że punkt środkowy widżetu zostanie przesunięty dokładnie tam, gdzie znajdował się lewy górny punkt - który wcześniej był ustawiony jako środek rodzica, a tego właśnie chcemy.
zolv
źródło
6

Aby użyć wartości procentowej we właściwości translate, musisz użyć Javascript: http://jsfiddle.net/4wqEm/27/

Kod HTML :

<div id="parent">
    <div id="children"></div>
</div>​​​​​​​​​​​​​

Kod CSS:

#parent {
    width: 200px;
    height: 200px;
    background: #ff0;
}
#children {
    width: 10%;
    height: 10%;
    background: #f00;
}

Kod JavaScript:

parent = document.getElementById('parent');
children = document.getElementById('children');

parent_height = parent.clientHeight;
​children_translate = parent_height * 50/100;
children.style.webkitTransform = "translateY("+children_translate+"px)";​​​​​​​​​​​​​​​​​​​​​​​​​​

Mam nadzieję, że mógłbym ci pomóc i powiedzieć mi, jeśli masz inny problem.

Lucas Willems
źródło
1
nie mogę tego zrobić tylko z CSS3?
Dchris,
3
To jest opóźnione (nie twoja odpowiedź, tylko fakt, że autorzy specyfikacji nie zrobili tego w CSS i że musimy używać JS).
trusktr
3

Twoje stwierdzenie jest całkowicie słuszne, jeśli chodzi o wartości procentowe pochodzące z samego przetłumaczonego elementu. Zamiast używać właściwości translate w twoim przypadku, powinieneś używać pozycjonowania bezwzględnego, aby pozostać względem nadrzędnego div. Ustawiłem tutaj absolutnie pionowo twój czerwony div: (nie zapomnij o dodaniu pozycji względem nadrzędnego div, musi być ustawiony inaczej niż statyczny domyślny):

js fiddle pen tutaj

 body {
    margin: 0;
    width: 100%;
    height: 100%;
    }
 body > div {
    width: 200px;
    height: 200px;
    background: #ff0;
    position: relative;
    }
 body > div > div {
    width: 10%;
    height: 10%;
    -webkit-transform: translateY(-50%);
    background: #f00;
    position: absolute;
    top: 50%;
    }
Iulial
źródło
1
Ale animacja w górę i w lewo nie jest przyspieszana sprzętowo, prawda?
trusktr
1

Możesz także użyć jednego dodatkowego bloku i użyć do niego przejścia, z wyjątkiem węzła podrzędnego

Kod HTML :

<div id="parent">
    <div id="childrenWrapper">    
        <div id="children"></div>
    </div>
</div>​​​​​​​​​​​​​

css powinno wyglądać mniej więcej tak

#parent {
    position: relative;
    width: 200px;
    height: 200px;
    background: #ff0;
}
#childrenWrapper{
    width: 100%;
    height: 100%;
}
#children {
    width: 10%;
    height: 10%;
    background: #f00;
}
Petryk P'yatochkin
źródło
1

Możesz ustawić element w pozycji bezwzględnej i użyć właściwości left i top, aby przyjąć wartość procentową jako element nadrzędny.

user4993573
źródło
1

Jest rozwidlony z wymaganym pozycjonowaniem w poniższym przykładzie roboczym adresu URL

body {
margin: 0;
width: 100%;
height: 100%;
}

body>div {
position: relative;
width: 200px;
height: 200px;
background: #ff0;
}

body>div>div {
position: absolute;
left: 50%;
top: 50%;
width: 10%;
height: 10%;
background: #f00;
transform: translate(-50%, -50%);
}

uwagi:

  1. możesz bezwzględnie ustawić swój czerwony kwadrat, zmieniając element nadrzędny na pozycję względną
  2. wtedy użycie 50% do góry i 50% do lewej spowoduje umieszczenie czerwonego kwadratu zgodnie z jego lewym górnym rogiem
  3. używając transform: translate (-50%, - 50%) ustawi czerwony kwadrat zgodnie z jego środkiem
Mhmad Q. Abdelhaq
źródło
0

Rozwiązaniem tego problemu jest w ogóle nie używać tłumaczenia. Kiedy tłumaczysz element, wartość procentowa, którą wybierasz, zależy od jego własnej wysokości.

Jeśli chcesz ustawić element na podstawie wysokości rodzica, użyj top: 50%;

Tak więc kod będzie wyglądał następująco:

body {
    margin: 0;
    width: 100%;
    height: 100%;
}
body > div {
    width: 200px;
    height: 200px;
    background: #ff0;
    position: relative;
}
body > div > div {
    position: absolute;
    top: 50%;
    width: 10%;
    height: 10%;
/*     -webkit-transform: translateY(50%); */
    background: #f00;
}
Vlad
źródło