Wyrównywanie tekstu do dolnej krawędzi elementu przy pomocy CSS3
Dzisiaj ktoś na Twitterze zapytał, czy jest jakiś sposób żeby tekst w jakimś elemencie przylegał do dolnej krawędzi. Tym elementem był znacznik <h1>. I to wszystko, co było z markupu. H1 był też dodatkowo ostylowany: wysokość, obramowanie itp… Od razu stwierdziłem, że tekstu nie da się wyrównać do dolnej linii bez dodatkowego markupu. Po chwili jednak przyszło mi do głowy inne rozwiązanie. Co prawda działa ono tylko w nowoczesnych przeglądarkach, ale cóż… Stwierdziłem, że rozwiążę ten problem, ot po prostu dla sztuki. To nasz początkowy kod:
h1 { border: 1px solid black; width: 100%; height: 200px; text-align: center; }
Oczwiście nie trudno stwierdzić, że z takim kodem powstanie nam jakiś kontener (<h1>) z tekstem wyśrodkowanym w poziomie. I jak ten tekst teraz przenieść na dół elementu? Można by owy tekst (przepraszam za wszelkie powtórzenia ;)) wewnątrz wypozycjonować absolutnie względem kontenera, ale to wymaga dodatkowych znaczników. A na te sobie pozwolić nie możemy. Dlatego z pomocą przychodzi Flexible Box Model, o którym można przeczytać nieco więcej tutaj: klik! Dzięki zmianie wartości atrybutu display na box dostajemy kilka (bodajże 8) nowych atrybutów do dyspozycji:
box-orientbox-alignbox-packbox-flexbox-flex-groupbox-ordinal-groupbox-directionbox-lines
Nas interesują dwie z nich (w zasadzie to jedna, ale to zaraz wytłumaczę dlaczego):
box-align– to jest nasz kluczowy atrybut. Ustawiamy w nim, jakie ma być pozycjonowanie zawartości danego elementu. Tak więcbox-alignprzyjmuje pięć wartości:start|end|center|baseline|stretch. Ostatnia z nich jest domyślna. My powinniśmy zmienić ją na wartośćend. To ona wypozycjonuje nasz tekst właśnie na dole.box-pack– jeśli wartośćbox-orientjest ustawiona nahorizontal(a tak jest domyślnie) to wtedy dziękibox-packjesteśmy w stanie ustalić pozycję tekstu (boksa) w poziomie *
* – teoretycznie ta wartość nie powinna być nam potrzebna, jako, że element <h1> ma już text-align: center, jednakże zmieniliśmy sposób wyświetlania tego elementu (display z domyślnego block na nowy box, a wiadomo, że text-align działa tylko na elementach blokowych oraz tabelarycznych), stąd potrzeba wyśrodkowania tekstu raz jeszcze w inny sposób. Dlatego dopisujemy do naszego arkusza CSS takie oto linijki:
h1 { ... display: box; box-pack: center; box-align: end; }
A jak wiadomo, życie nie jest takie proste, dlatego musimy targetować poszczególne przeglądarki osobno. Zatem kod który dopiszemy to nie będą 3 nowe linijki a aż 9:
h1 { ... display: box; box-pack: center; box-align: end; display: -webkit-box; -webkit-box-pack: center; -webkit-box-align: end; display: -moz-box; -moz-box-pack: center; -moz-box-align: end; }
Tak czy inaczej osiągamy nasz cel. Wersja finalna + demo.
UPDATE:
Okazuje się, że Firefox ma problemy z Flexible Box Model, jeśli dany element jest wypozycjonowany absolutnie. Dlatego też musiałem nieco poprawić mój przykładowy kod. Teraz wszystko powinno być ok. Bug właśnie zgłaszam Firefoksowi, a za wychwycenie tego błędu bardzo dziękuję css3.pl.
Komentarze (8):dodaj komentarz
Ten przykład nie działa w Firefoksie 3.6
@css3.pl: cholera, rzeczywiście masz rację. Ja, gdy tworzyłem ten przykład opierałem się głównie na Chromie, jednakże widziałem w którejś specyfikacji, że Flex Box Model działa również w Firefox 3+, dlatego jestem trochę zdziwiony teraz, gdy to sprawdzam… Okazuje się, że FF ma jakiś problem z Flex Box Model jeśli elementowi dodamy również position: absolute;
Ja, position:absolute; musiałem mieć ponieważ właśnie taki przykład dostałem od kogoś na Twitterze. Teraz to usunąłem i poprawiłem kilka rzeczy, więc wszystko powinno być ok.
Dzięki wielkie za wychwycenie! Swoją drogą, za chwilę to zgłoszę jako bug w Firefoksie.
Śliczności. Po ostatnich zabawach z positon:absolute;bottom:0px tylko czekam, aż zostanie to ładnie zaimplementowane w każdej przeglądarce.
A może jest jakiś sposób, żeby zaemulować te własności w jQuery?
@Łukasz Wójcik: w jQuery ot tak raczej tego się nie da zrobić. Oczywiście można napisać jakiś skrypt, który będzie wyliczał różne wysokości i pozycjonował wszystko, ale samego Flexible Box Model raczej się nie zaemuluje :( Choć podejrzewam, że ktoś już napisał jakiś plugin do tego ;)
panowie nie wiem ale jak wpisałem ten kod to w FF jest ok ale w IE i w Opera to nie chodzi
Kurs MySQL – Strona Mateusza Dutkiewicza
#h1{
width: 450px ;
color: green;
background-color: yellow;
border: 3px solid green;
}
h1 {
width: 450px ;
height: 350px;
text-align: centrum;
display: box;
box-pack: center;
box-align: end;
display: -webkit-box;
-webkit-box-pack: center;
-webkit-box-align: end;
display: -moz-box;
-moz-box-pack: center;
-moz-box-align: end;
}
To jest tekst
@nowy, chyba nie bardzo wiem o co chodzi ;)
IE oczywiście tego nie obsłuży, ponieważ IE nie wspiera display:box.
natomiast co do kodu który podesłałeś to mogę tylko powiedzieć, że nie istnieje wartość “centrum” dla text-align ;)
poprawiam kod opera też nie działa
<!–
@font-face {
font-family: ‘Silesiana’;
src: url(silesiana.otf);
}
h1 {
font-family: ‘Silesiana’,Serif;
}
#h1{
width: 550px ;
color: green;
background-color: yellow;
border: 2px solid green;
}
h1 {
border: 0px solid black;
width: 550px ;
height: 350px;
text-align: center;
display: box;
-box-pack: center;
-box-align: end;
display: -webkit-box;
-webkit-box-pack: center;
-webkit-box-align: end;
display: -moz-box;
-moz-box-pack: center;
-moz-box-align: end;
display: -O-box;
-O-box-pack: center;
-O-box-align: end;
}
To jest jakiś tekst świetnie
–>
Trochę stary post, ale zaproponuję bardziej uniwersalne rozwiązanie: http://jsfiddle.net/dominik/6qp7t
W ten sposób możemy wyrównać nie tylko tekst do dolnej krawędzi danego elementu, ale również inne elementy blokowe.