Aby zawinąć tekst akapitu wokół obrazu wystającego poza krawędź karty, ustaw obraz jako element pływający i zastosuj ujemny margines zewnętrzny. Dodaj shape-outside, aby uzyskać zakrzywiony kontur. W tym samouczku utworzysz kompletny przykład lokalny, który możesz otworzyć w Safari na Macu.
Co sprawia, że tekst zawija się wokół wystającego obrazu?
Obraz musi uczestniczyć w układzie akapitu z elementami pływającymi. Właściwość CSS float umieszcza element przy jednej krawędzi kontenera i pozwala zawijać sąsiadujący tekst wokół niego. W tym przykładzie obraz wyrównany do prawej pozostawia tekst po lewej stronie i poniżej. MDN: float.
Trzy ustawienia wpływają na wynik: element pływający tworzy efekt zawijania, ujemny prawy margines pozwala obrazowi wystawać poza kontener, a shape-outside określa kontur, za którym podąża sąsiadujący tekst. Zwykłe elementy pływające powodują zawijanie prostokątne; kształt pozwala poszczególnym wierszom podążać za okręgiem. MDN: shape-outside.
Samo wizualne przesunięcie obrazu nie wystarczy. Obraz pozycjonowany bezwzględnie nie zajmuje miejsca w normalnym przepływie, więc sąsiednie elementy zachowują się tak, jakby go nie było. Przesunięcie zmienia położenie renderowanego elementu bez przestawiania normalnego przepływu dokumentu. To wyjaśnia, dlaczego wystający obraz może zasłaniać tekst, gdy zostanie ustawiony za pomocą position: absolute lub transform: translateX(...). MDN: position, MDN: używanie transformacji CSS.
Zadanie jest celowo konkretne: jeden okrągły obraz wystaje poza prawą krawędź jednej karty z tekstem, a akapity karty podążają za lewym konturem okręgu. Obraz i akapity należą do tego samego obszaru zawijania.
Utwórz kompletny przykład na Macu
W zwykłym edytorze tekstu utwórz plik o nazwie overlap-wrap.html. Wklej cały poniższy dokument, zapisz go i otwórz w Safari. Przykład zawiera abstrakcyjny obraz SVG zapisany jako adres URL data, więc nie trzeba instalować plików graficznych, pakietów ani narzędzi do budowania.
Obraz pływający pojawia się przed akapitami, na które ma wpływać. To położenie ma znaczenie, ponieważ pozycję elementu pływającego ogranicza treść występująca wcześniej w dokumencie. Umieszczenie nagłówka przed obrazem pływającym pozwala też nagłówkowi zajmować całą szerokość obszaru tekstu karty. W3C: model formatowania wizualnego.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Overlapping image and paragraph wrapping</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
padding: 32px 96px 32px 32px;
background: #eef1f5;
color: #243247;
font: 18px/1.65 system-ui, sans-serif;
}
.card {
display: flow-root;
width: 100%;
max-width: 640px;
margin: 0 auto;
padding: 24px;
background: white;
box-shadow: 0 0 0 1px #cbd3df;
overflow: visible;
}
.card h2 {
margin: 0 0 16px;
font-size: 26px;
line-height: 1.25;
}
.card p { margin: 0 0 16px; }
.card p:last-child { margin-bottom: 0; }
.art {
display: block;
float: right;
width: 240px;
height: 240px;
margin: 0 -88px 16px 16px;
border-radius: 50%;
shape-outside: circle(50%) border-box;
shape-margin: 16px;
}
@media (max-width: 760px) {
body { padding: 16px; }
.art {
float: none;
width: min(240px, 100%);
height: auto;
margin: 0 auto 24px;
shape-outside: none;
}
}
</style>
</head>
<body>
<article class="card">
<h2>Study A: circles and spacing</h2>
<img class="art" width="240" height="240" alt=""
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240' viewBox='0 0 240 240'%3E%3Crect width='240' height='240' fill='%233a628b'/%3E%3Ccircle cx='90' cy='85' r='60' fill='%23b9d8eb'/%3E%3Ccircle cx='165' cy='170' r='45' fill='%238db5cc'/%3E%3C/svg%3E">
<p>Panel A pairs a circular graphic with a continuous passage of
sample text. Follow the right edge of this paragraph as each
line approaches the curved outline. Near the widest part of
the circle, the available space becomes narrower.</p>
<p>Panel B continues the same passage with a second paragraph.
The graphic extends into the outer gutter while the words
remain inside the white card. As the contour curves inward,
later lines can use more of the available width.</p>
<p>Panel C provides enough additional text to show the transition
below the graphic. Once the passage continues beyond the
wrapping region, its lines return to the full content width.
Resize the window to compare the desktop arrangement with
the stacked layout used in a narrower window.</p>
</article>
</body>
</html>
Przy szerokości obszaru wyświetlania większej niż 760px zamierzony efekt to okrągła grafika wystająca w prawy odstęp, z wierszami akapitu podążającymi za jej lewą stroną. Przy szerokości 760px lub mniejszej obraz staje się wyśrodkowanym blokiem nad akapitami. Punkt przerwania to przykładowy wybór projektowy; @media stosuje zawarte deklaracje, gdy spełnione jest jego zapytanie. MDN: @media.
Przykładowa grafika jest dekoracyjna, dlatego element obrazu używa alt="". Jeśli zastąpisz ją grafiką przekazującą informacje, podaj odpowiedni tekst alternatywny. WHATWG rozróżnia obrazy dekoracyjne od tych, których informacje wymagają tekstowego odpowiednika. WHATWG: wymagania dotyczące tekstu alternatywnego dla obrazów.
Jak dobrać wystawanie obrazu i odstęp od tekstu?
Najpierw ustaw położenie obrazu, a potem dopasuj kontur. Element pływający wyrównany do prawej jest pozycjonowany na podstawie swojego obszaru marginesów. W tym przykładzie ujemny prawy margines umieszcza prawą krawędź obrazu 88px poza krawędzią treści karty. Karta ma prawy padding o szerokości 24px, więc obraz wystaje o 64px poza białe tło. Są to wymiary wyliczone dla tego przykładu i podane w pikselach CSS. W3C: pozycjonowanie elementu pływającego.
| Wielkość | Przykładowa wartość | Obliczenie lub przeznaczenie |
|---|---|---|
| Szerokość obrazu | 240px |
Średnica wyświetlanego okręgu |
| Przesunięcie na zewnątrz od krawędzi treści | 88px |
Wartość bezwzględna ujemnego prawego marginesu |
| Padding karty | 24px |
Odstęp między krawędzią treści a krawędzią tła |
| Widoczne wystawanie poza tło | 64px |
88 − 24 |
| Szerokość obrazu pozostająca w obszarze treści | 152px |
240 − 88 |
| Rezerwacja miejsca przy prostokątnym zawijaniu | 168px |
240 − 88 + 16, z uwzględnieniem lewego marginesu |
W swoim układzie oblicz wartość bezwzględną ujemnego marginesu, dodając żądane wystawanie do prawego paddingu kontenera. Na przykład wystawanie o 40px przy paddingu 24px wymaga prawego marginesu -64px. Za każdym razem, gdy powiększasz obraz lub zmniejszasz szerokość kontenera, sprawdź ponownie, ile miejsca pozostaje na tekst.
W wersji z okręgiem użyj shape-outside: circle(50%) border-box, aby jego geometria odpowiadała kwadratowemu polu obrazu. Jawne wybranie border-box jest tu przydatne, ponieważ asymetryczne marginesy zmieniają obszar marginesów. Bez jawnego określenia obszaru odniesienia podstawowy kształt domyślnie używa margin-box. MDN: podstawowe kształty z shape-outside.
shape-margin: 16px dodaje odstęp wokół konturu zawijania. Dodatni lewy margines zapewnia miejsce na ten odstęp po stronie tekstu. Kształty, wraz z ich marginesami kształtu, są przycinane do obszaru marginesów elementu pływającego; samo zwiększanie shape-margin nie pozwala bez końca rozszerzać obszaru zawijania. Ujemny prawy margines przycina też kształt po zewnętrznej stronie, gdzie w tym przykładzie nie ma tekstu akapitu. W3C: moduł CSS Shapes, poziom 1.
W przypadku prostokątnego obrazu zmień border-radius na 0, shape-outside na none i shape-margin na 0. Zachowaj element pływający i marginesy. Otrzymasz proste krawędzie zawijania przy takim samym wystawaniu na zewnątrz. Usunięcie samego kształtu przy zachowaniu okrągłego przycięcia pozostawia okrągły obraz z prostokątnym odstępem od tekstu.
Które granice kontenera wpływają na zawijanie?
Karta używa display: flow-root, aby utworzyć kontekst formatowania blokowego, który obejmuje jej element pływający w pionie. Dzięki temu wysokość karty uwzględnia obraz nawet wtedy, gdy tekst jest krótki. Oddziela to również ten obszar zawijania od zewnętrznych elementów pływających. MDN: kontekst formatowania blokowego.
Pozostaw akapity w zwykłym przepływie blokowym w tym obszarze. Jeśli obraz jest bezpośrednim elementem flex lub grid, jego właściwość float nie zapewni takiego układu zawijania tekstu akapitu. Podobnie osobny kontener akapitu z własnym kontekstem formatowania blokowego wyklucza zewnętrzny element pływający z jego zawartości. Zewnętrzny układ grid może ustawiać całą kartę; jej wnętrze nadal może używać układu przepływowego. MDN: kontekst formatowania blokowego.
Sprawdź też osobno przycinanie. W przykładzie przepełnienie pozostaje widoczne, aby można było wyświetlić wystającą część. Użycie overflow do obejmowania elementów pływających może spowodować przycinanie lub pojawienie się pasków przewijania; flow-root pozwala objąć elementy pływające bez takiego rozwiązania. Sprawdź też kontenery nadrzędne, jeśli obraz znika dokładnie przy krawędzi jednego z nich. MDN: obejmowanie wewnętrznych elementów pływających.
CSS Shapes ma też ograniczenie kierunkowe: element pływający wyrównany do prawej pozwala na zawijanie po lewej, a wyrównany do lewej — po prawej. Pojedynczy element pływający nie utworzy przejść tekstu po obu stronach wyśrodkowanego obrazu. W tym zadaniu obsługiwany jest układ z obrazem przy krawędzi. W3C: CSS Shapes i zachowanie elementów pływających.
Czy można zastosować to podejście z Tailwind CSS?
Tak. W istniejącym projekcie Tailwind float-right ustawia float: right, a float-none usuwa float. Tailwind udostępnia te klasy użytkowe; przeglądarka nadal odpowiada za układ tekstu. Tailwind CSS: float.
Deklarację konturu można zapisać za pomocą składni dowolnej właściwości Tailwinda: [shape-outside:circle(50%)_border-box] i [shape-margin:16px]. Podkreślenie reprezentuje spację przed border-box. To fragmenty nazw klas dla już skonfigurowanego projektu Tailwind, a nie zamiennik kompletnego dokumentu powyżej. Podczas przenoszenia przykładu zachowaj te same wymiary, marginesy, układ kontenera i reset dla wąskiego okna. Tailwind CSS: dodawanie niestandardowych stylów.
Jak diagnozować nieprawidłowe zawijanie tekstu?
Użyj lokalnego przykładu jako punktu odniesienia, a następnie wprowadzaj istniejące style pojedynczo. Ta kolejność pozwala sprawdzić warunki wpływające na układ:
- Najpierw sprawdź zawijanie prostokątne. Tymczasowo ustaw
shape-outside: none. Jeśli tekst nadal pojawia się pod obrazem, sprawdź, czy obraz jest elementem pływającym, pozycjonowanym bezwzględnie albo bezpośrednim elementem flex/grid. - Sprawdź kolejność w dokumencie. Umieść element pływający przed akapitami, które mają się wokół niego zawijać.
- Sprawdź obszar zawijania. Umieść element pływający i treść akapitu w tym samym kontekście formatowania blokowego; usuń niepotrzebny, niezależny kontekst z kontenera akapitu.
- Sprawdź kontur. Przywróć okrąg i jego jawne odwołanie do
border-box. Przed zastosowaniem okrągłego przycięcia upewnij się, że wyświetlany obraz jest kwadratowy. - Sprawdź odstęp. Zwiększ szerokość obszaru wyświetlania i sprawdź, czy karta lub jej kontenery nadrzędne nie przycinają obrazu. Upewnij się, że strona rezerwuje wystarczająco dużo zewnętrznego miejsca na wystającą część.
- Sprawdź układ dla wąskiego okna. Zmieniaj rozmiar okna, przekraczając punkt przerwania z przykładu, i sprawdź, czy zarówno float, jak i ujemny margines są resetowane.
Te kontrole odzwierciedlają udokumentowane zasady pozycjonowania elementów pływających, kontekstów formatowania i obszarów odniesienia kształtów. Nie dodawaj ręcznych podziałów wiersza, aby poprawiać pojedyncze linie; uzależniłyby one tekst od konkretnej szerokości okna.
MDN wskazuje, że shape-outside jest szeroko dostępne, zaznaczając jednocześnie, że obsługa części jego składni może się różnić. W tym przykładzie użyto udokumentowanej postaci circle(). Sprawdź stronę w przeglądarkach na Macu, które zamierzasz obsługiwać, i oceń odstępy oraz czytelność zamiast wymagać identycznych zakończeń wierszy. Jeśli deklaracja kształtu nie jest obsługiwana, element pływający nadal zapewnia prostokątne zawijanie. MDN: shape-outside.
W gotowym układzie dobierz wspólnie rozmiar obrazu i jego wystawanie, zapewnij tekstowi wystarczająco dużo miejsca i zachowaj układ awaryjny z obrazem nad tekstem. Gdy te wymiary będą odpowiednie, użyj konturu, aby dopracować odstęp wokół obrazu. Dzięki temu akapit może zmieniać układ, gdy zmieni się jego treść lub dostępna szerokość.
Źródła
- Właściwość CSS float — MDN Web Docs.
- Właściwość CSS shape-outside — MDN Web Docs.
- Właściwość CSS position — MDN Web Docs.
- Używanie transformacji CSS — MDN Web Docs.
- Model formatowania wizualnego — W3C.
- Reguła CSS @media — MDN Web Docs.
- Standard HTML: obrazy — WHATWG.
- Podstawowe kształty z shape-outside — MDN Web Docs.
- Moduł CSS Shapes, poziom 1 — W3C.
- Kontekst formatowania blokowego — MDN Web Docs.
- float — Tailwind CSS.
- Dodawanie niestandardowych stylów — Tailwind CSS.