2011-01-20 11 views
9

Tak, tak, wiem, że jest to kolejne pytanie dotyczące pionowego wyrównania z CSS i zrobiono to milion razy wcześniej. Zapewniam, że natknąłem się na ten problem wiele razy i już przeczytałem o różnych sposobach centrowania w pionie za pomocą CSS. Pytam tutaj, ponieważ żaden z tych sposobów nie robi dokładnie tego, co chcę zrobić, i chcę tylko upewnić się, że moje podejrzenie (że pionowe wyrównanie CSS jest zepsute i nie zrobi tego, co chcę zrobić) jest zdecydowanie poprawne.Wyrównanie w pionie za pomocą CSS

Najpierw, tutaj jest mój przypadek testowy: http://www.game-point.net/misc/testAlign/

Oto kryteria:

  • Chcę wyrównać „tekst wyśrodkowany” pionowo w stosunku do DIV zawierający „TestTestTest ... "tekst.
  • Nie chcę podawać ŻADNYCH wysokości.
  • Chcę, aby DIV "TestTestTest" i "Centered text" dynamicznie zwiększały wysokość, stosownie do ilości tekstu, jaki mają, i limitu szerokości, jaki mają.
  • Nie chcę używać Javascript.

Wydaje się to niemożliwe nawet w CSS3, nie mówiąc już o CSS2. Denerwujące jest to, że prawie jestem; position:absolute; top:-50%; DIV działa, aby ustawić wierzchołek tego DIV na połowie DIV kontenera. Problem polega na tym, że wewnętrzny DIV, ze stylem position:relative; top:-50%;, nie robi nic, aby przesunąć zawartość o połowę wysokości, aby ją w pełni wyśrodkować, ponieważ CSS mówi, że bezwzględnie umiejscowiony DIV nie ma wysokości, a zatem top:-50% jest bez znaczenia . O ile mogę powiedzieć, jest to tylko podstawowa wada CSS bez konkretnego powodu. Element absolutnie pozycjonowany ma wysokość i nie wiem, dlaczego CSS udaje, że tego nie robi. Chciałem tylko zapytać, czy ktoś ma jakieś pomysły, jak osiągnąć pożądany efekt, przedstawiony na dole, biorąc pod uwagę kryteria, które opisałem powyżej. Jak na ironię "złamany" model IE6/7/8, w trybie dziwactwa, daje mi ten efekt. Szkoda, że ​​"naprawiają" to w IE9, więc to już nie będzie.

+0

Cóż, zawsze można użyć jQuery zrobić magię. Ale twoje podejrzenia są prawdopodobnie poprawne, o ile wiem. –

+0

Myślisz, że możesz to zrobić za pomocą schematu flexbox teraz http://css-tricks.com/snippets/css/a-guide-to-flexbox/ – Ruskin

Odpowiedz

5

OK, moje podejrzenie było rzeczywiście prawidłowe i nie jest to możliwe (Myślę, że to błąd w CSS i powinny one zapewniać pionowe wyrównanie wewnątrz DIV bez określania wysokości elementów wewnętrznych).

Najgorszym rozwiązaniem, jakie znalazłem, było to, że: określ wysokość "środkowego" DIV - czyli DIV, który jest wyświetlany przy użyciu position:absolute i zawiera rzeczywistą treść. Dodałem go do przypadku strony testowej w http://www.game-point.net/misc/testAlign/ pod nagłówkiem Z line-height: 100% i sztywno „środkowy” wysokość DIV. To rozwiązanie oznacza, że ​​musisz znać wysokość treści, która ma być pionowo wyśrodkowana, co jest do bani, ponieważ przeglądarka oblicza to i nie powinieneś jej określać, ale jest to jedyny sposób (dopóki CSS nie zacznie działać razem). Użyłem też em s, aby określić także wysokość, tak aby powiększanie i zmniejszanie tekstu nie zepsuło pionowego centrowania. Okazuje się, że dla 2 linii "wyśrodkowanego tekstu", który miałem, ta wysokość równa się dokładnie 2 em s (przynajmniej na moim komputerze). Gdybym miał zmienić wysokość tej zawartości lub miałaby ona zmieniać się dynamicznie, aby powiedzieć 3 linie lub 1 linię, stała macierzysta o stałej wysokości musiałaby się zmienić.

Więc tutaj jest kod I w końcu skończyło się, jeśli ktoś jest zainteresowany:

<div style="border:1px solid black; padding-left:60px; width:250px; position:relative; word-wrap:break-word;"> 
     TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest 
     <!-- Unfortunately, must set this DIV's height explicitly or the contained DIV's relative positioning won't work, as this DIV is considered to have NO implicit height --> 
     <div style="position:absolute; display:block; top:50%; left:0px; height:2em;"> 
      <div style="position:relative; top:-50%; background-color:#00aa00; line-height:100%;"> 
       Centred text<br/> 
       Centred text 
      </div> 
     </div> 
    </div> 
-3
.item { 
    height: 40px; 
    top: 50%; 
    margin-top: -20px; 
} 

pozycja względna lub absolutna;

+2

OP: „Nie chcę, aby określić wysokość” – kapa

+0

rozwiązanie z "top: 50%" działa tylko z określoną wysokością. – jcubic

+0

Istnieje również inne rozwiązanie z wykorzystaniem marginesu ustawionego na auto, ale uważam, że wymaga on również określonej wysokości. – jcubic

2

Zastosowanie margin-top: zamiast top: jak margin-top: -25%;

+0

miło, działa dla mnie – kapa

+1

To całkiem nieźle, ale nie uwzględnia wysokości wyśrodkowanej skrzynki. Ponieważ ma być dynamiczny, może to stanowić problem. – sfarbota

+0

Interesujące ... jaka jest wartość procentowa marginesu górnego w stosunku do? Więc, to jest -25% z czego? Jeśli zredukuję wyśrodkowany tekst do 1 linii tekstu, nie zostanie on odpowiednio wyśrodkowany. – Jez

2

rzeczą jest jednak, że pionowy manipulowanie zawartością jest wykonana w ten sposób z oczywistych powodów, które jestem pewien, że już jesteś świadomy. Ale próbujesz rozwiązać nierozwiązywalny problem, to naprawdę nie jest problem. (ma to sens, gdy wiesz, dlaczego tak się zachowuje)

Używając pozycji absolutnej, po prostu czerpiesz treści z naturalnego przepływu. Znacznie lepiej jest zrobić wszystko, co powinno, z pływakami i odpowiednimi rozmiarami lub cokolwiek jest potrzebne, aby ładnie się rozpadło i wygląda dobrze na wszystkich urządzeniach. Następnie napisz dwa wiersze kodu w jquery, aby sprawdzić wysokości i wyrównać wszystko (co będzie również działać na "wszystkich" urządzeniach). 2-3% bez JS będzie musiało żyć z nudnymi stronami.

+4

Tak, biorę trochę treści z naturalnego przepływu; to jedyny sposób na nałożenie tekstu na inny tekst. Co byś zasugerował? Wydaje się, że mówisz, że aby uzyskać więcej niż możliwości Netscape 3, musisz użyć Javascript. Myślę, że CSS miał być nieco bardziej wytrzymały. – Jez

+0

To, co mówię, to to, że jeśli bierzesz treści z naturalnego przepływu, jesteś w stanie odebrać dynamiczne możliwości zawartości div, aby naturalnie się rozwinąć. Pozycja bezwzględna z pozycjonowaniem jest ograniczona w tym obszarze. Więc rozwiązuje to dokładnie tak, jak mówisz, jestem prawie pewien, że nie jest to możliwe. Z ciekawości, dlaczego nie ma na przykład jQuery? W dzisiejszych czasach jest tak szybki i prosty. – plebksig

+0

"to jedyny sposób na nałożenie tekstu na inny tekst." a co z 'z-index'? – Knu

0

Zacząłem dostawać się gdzieś z następującym kodem ... choć wymaga to pracy.

podstawie przedmiotów znalezionych http://www.jakpsatweb.cz/css/css-vertical-center-solution.html

Uwaga, Twój kod działa w trybie quirks, zmieniłem to html 5

<!DOCTYPE HTML> 
<html> 
<head> 
    <title>Vertical align test</title> 
</head> 

<style type="text/css"> 


#outer { overflow: hidden; position: relative; border: 1px solid red; } 
#outer[id] {display: table; position: static;} 

#middle {position: absolute; top: 50%;} /* for explorer only*/ 
#middle[id] {position: relative; display: table-cell; vertical-align: middle; width: 100%;} 

#inner {position: relative; top: -50%; width: 100px} /* for explorer only */ 
/* optional: #inner[id] {position: static;} */ 

</style> 

<body> 
<h1>New test</h1> 

<div id="outer"> 
    <div id="middle"> 
    <div id="inner"> 
     any text<br> 
     any height<br> 
     any content, for example generated from DB<br> 
     everything is vertically centered 
    </div> 

    </div> 

test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test 
</div> 


</body> 
</html> 
+0

Niestety, używa to wyświetlania: tabeli. To uniemożliwia użycie CSS 'word-wrap: break-word;' (nie rozbija wewnątrz komórek tabeli), więc chciałbym to zrobić bez wyświetlania: table. – Jez

Powiązane problemy