Ten kto chodził do przedszkola ma pewnie zdjęcie grupowe, na którym stojąc przed przebierańcem w stroju Św. Mikołaja, szczerzył zęby w stroju wróżki lub prężył pierś w stroju kowboja robiąc za mistrza pierwszego planu. Dziś już jako trochę starsi zajmiemy się podobnym efektem - sprawiania wrażenia, że mniejszy element zajmuje całą szerokość strony, pomimo, że mieści się w rodzicu i obydwoje wcale tacy szerocy nie są.
Tylko w butach i szelkach, czyli Bootstrap.
Naszym przedszkolem będzie Bootstrap, który stanie się bazą dla dalszych modyfikacji. Nie będziemy modyfikować domyślnych ustawień elementów, tj. wyświetlania, paddingu, marginesów, a tym bardziej zmieniać rozmiaru elementów, jednak naszym celem będzie wyprowadzenie co poniektórych wierszy na pełną szerokość ekranu. Czyli niektóre wiersze wizualnie będą maksymalnie mieć szerokość kontenera, a niektóre viewportu. Pomimo, że tak realna szerokość nie zmieni się. Jeśli jeszcze na tą chwilę chropoczesz się po głowie myśląc o co cho, to postaraj się doczytać do końca. Być może kiedy zobaczysz efekt końcowy, okaże się, że spotykałeś się z tym "problemem" wcześniej.
Tak więc szkielet w HTML (który możesz dowolnie wypełniać) wygląda tak:
<div class="container">
<div class="row">
<div class="col-12"></div>
</div>
<div class="row even">
<div class="col-12"></div>
</div>
</div>
Mamy tu typową hierarchię: kontener -> wiersz -> kolumna. Jednak wierszom, które chcemy wizualnie poszerzyć na 100% viewportu dodajemy klasę even. Oczywiście dla uproszczenia klasa może mieć nazwę mtvx-l4.
Prężenie muskułów przed panią przedszkolanką.
Mając naszą podstawę możemy ją modyfikować, aby osiągnąć wspomniany efekt. Ponieważ wykorzystywałem ten efekt w praktyce, udało mi się wypracować dwa przedszkola, tj. dwie szkoły. Szkoła inwazyjna i szkoła nieinwazyjna.
Zacznijmy od tej pierwszej. Tu wykorzystamy pseudoprzedszkolaka, czyli pseudoelement ::before.
Potrzebujemy CSS:
/* tło tylko dla rozróżnienia
wierszy
*/
.row {
background: rgb(150, 182, 223);
}
/* ponieważ pseudoelement
ustawiamy absolutnie,
to jego rodzica (.row)
musimy relatywnie
*/
.row.even {
position: relative;
}
/* i tu nasz bohater,
który wyprowadzamy poza
rodzica dzięki pozycjonowaniu
absolutnemu i szerokości 100vw
*/
.row.even:before {
content: "";
position: absolute;
left: calc((100% - 100vw) / 2);
top: 0;
height: 100%;
width: 100vw;
background: rgb(85, 145, 212);
}
Wartość dla left jest po prostu obliczona jako połowa różnicy między szerokością .row, a viewportu. Przykładowo jeśli wiersz ma 640px szerokości, a viewport 720px, to przesuwamy pseudoelement w lewo o -80/2=-40px. W ten sposób ustawi się przy lewej krawędzi ekranu, no i mając szerokość 100vw dociągnie do prawej. Tak więc pomimo, że .row ma 640px, to wizualnie będzie wyglądał na 720px.
Wspomniałem też o drugiej szkole, tej nieinwazyjnej. Tu wykorzystamy właściwość box-shadow. Jest ona o tyle fajna, że cień, czyli poszerzenie elementu możemy ustawiać dla dowolnej strony elementu, również dla kilku, i nie wpływa na rozmiary elementu (na box model). Nie chcemy kombinować z padding, margin. Nie pomoże też border. A outline, który jest podobny w działaniu do box-shadow, niestety możemy ustawić tylko we wszystkich kierunkach jednocześnie.
No więc CSS:
/* znów dla odróżnienia
*/
.row {
background: rgb(150, 182, 223);
}
/* tu nadajemy dwa oddzielnie cienie
dla lewej i prawej strony elementu
*/
.row.even {
background: rgb(85, 145, 212);
box-shadow: -40vw 0 0 0 rgb(85, 145, 212), 40vw 0 0 0 rgb(85, 145, 212);
}
W przeciwieństwie do poprzedniej metody nie możmy użyć formuły calc z wartością 100%, więc szerokość cienia została dobrana eksperymentalnie. Nakładamy też kolor tła dla wiersza, bowiem cienie wystartują tylko od jego krawędzi, a we wcześniejszym przykładzie pseudoelement stanowił jednocześnie tło dla wiersza.
A chodziło mi o efekt wizualnego poszerzenia elementu podrzędnego. Być może w przypadku telefonu nie dostrzerzesz w czym rzecz, bo kontener (a więc i wiersz) zajmie i tak całą szerokość viewport, spróbuj więc obrócić telefon do układu landscape.
No cóż, teraz wracamy do rzeczywistości z podróży sentymentalnej. Do przeczytania!