Ellipsize — to mechanizm przycinania tekstu, w którym zamiast pikselowego obcinania linii, na końcu lub w środku dodawany jest symbol wielokropka (…), sygnalizujący użytkownikowi, że tekst nie zmieścił się w kontenerze. Technika ta jest używana w nagłówkach, przyciskach, listach kontaktów i wszelkich komponentach UI o ograniczonej szerokości. Według Google Material Design Guidelines, ellipsize jest standardowym zachowaniem dla TextView i UILabel, obsługując cztery tryby przycinania: początek, środek, koniec i ruchomy tekst.
Najważniejsze
Ellipsize (od ang. ellipsis — wielokropek) — to technika wyświetlania tekstu, który przekracza rozmiary kontenera. Zamiast zwykłego przycinania linii do granicy (clip), ellipsize dodaje symbol wielokropka (trzy kropki, Unicode U+2026), wskazując użytkownikowi na obecność ukrytej treści.
Termin utrwalił się w Android SDK, gdzie właściwość android:ellipsize określa zachowanie TextView przy przepełnieniu. Na iOS analogiczna funkcjonalność nazywa się truncation (przycinanie) i jest zarządzana przez NSLineBreakMode. W sieci używana jest właściwość CSS text-overflow z wartością ellipsis.
Głównym celem ellipsize jest informowanie użytkownika, że tekst został skrócony. W przeciwieństwie do przycinania po pikselach, gdzie słowo może zostać przerwane na pół, ellipsize gwarantuje czytelność: wielokropek stawiany jest po całym słowie lub znaku, nie rozrywając go. Jest to zgodne z zasadami Material Design i Human Interface Guidelines.
Używaj ellipsize wszędzie tam, gdzie szerokość kontenera jest stała, a długość tekstu dynamiczna: nagłówki artykułów, komórki tabel, przyciski z etykietami, kontakty na liście, breadcrumbs i ścieżki plików.
W Android ellipsize konfiguruje się przez atrybut android:ellipsize w XML lub metodę setEllipsize() w kodzie. Dostępne są cztery tryby, z których każdy określa, z której strony tekst zostanie przycięty.
Tryb END (domyślny w większości przypadków) przycina koniec linii i umieszcza wielokropek w prawej części kontenera. Tryb START przycina początek — wielokropek po lewej, widoczny tekst po prawej. MIDDLE przycina środek, pozostawiając początek i koniec linii widocznymi. Tryb MARQUEE — animowane przewijanie tekstu, w którym wielokropek nie jest pokazywany, a tekst cyklicznie się przewija.
<!-- XML layout -->
<TextView
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Very long text that will be truncated"
android:ellipsize="end"
android:maxLines="1"
android:singleLine="true" />
<!-- Kotlin code -->
textView.setEllipsize(TextUtils.TruncateAt.MIDDLE)
Ważne: ellipsize działa tylko w kombinacji z maxLines lub singleLine. Jeśli nie ograniczysz liczby linii, TextView będzie rosnąć na wysokość i ellipsize nie zostanie włączone. Od Androida 8.0 (API 26) ellipsize obsługuje tryb wieloliniowy z maxLines > 1 — wielokropek umieszczany jest na końcu ostatniej linii.
Do programowego wywołania używaj TextUtils.TruncateAt z jedną z wartości: END, START, MIDDLE, MARQUEE. Wartość NONE wyłącza ellipsize.
W praktyce END pasuje do 90% przypadków — użytkownicy oczekują, że tekst został przycięty na końcu. MIDDLE jest używane dla ścieżek plików (np. "/User/.../project/main.kt"), aby widoczny był koniec ścieżki. START — dla nazw ze wspólnym prefiksem (np. "...@gmail.com").
Na iOS odpowiednikiem ellipsize jest właściwość lineBreakMode klasy UILabel (i NSTextContainer dla UITextView). Dostępne są trzy tryby przycinania: .byTruncatingTail (koniec), .byTruncatingMiddle (środek) i .byTruncatingHead (początek).
Tryb .byTruncatingTail odpowiada android:ellipsize="end". Tryb .byTruncatingHead — START, .byTruncatingMiddle — MIDDLE. Tryb .byClipping — przycina tekst bez wielokropka, rzadko używany we współczesnych interfejsach. Tryb .byCharWrapping — zawijanie po znakach bez przycinania.
let label = UILabel()
label.text = "Długi tekst, który nie mieści się w granicach etykiety"
label.lineBreakMode = .byTruncatingMiddle
label.numberOfLines = 1
// NSAttributedString obsługuje również lineBreakMode
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byTruncatingTail
W iOS truncation działa w parze z numberOfLines. Jeśli numberOfLines = 1, tekst jest przycinany w jednej linii. Jeśli numberOfLines = 2 — w drugiej linii. UITextView używa NSTextContainer.lineBreakMode, który również obsługuje wszystkie trzy tryby przycinania.
Cecha iOS: tryb .byTruncatingMiddle na UILabel może zachowywać się nieoczywiście na krótkich liniach — jeśli linia mieści się w całości, wielokropek nie pojawia się. Aby zagwarantować wyświetlenie wielokropka na krótkich liniach, użyj niestandardowej logiki przez sizeThatFits.
W sieci ellipsize jest realizowane przez właściwość CSS text-overflow: ellipsis w kombinacji z overflow: hidden i white-space: nowrap. Jest to standardowy sposób przycinania linii z wielokropkiem w interfejsach internetowych.
.text-cell {
width: 250px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Właściwość text-overflow nie działa bez overflow: hidden — przeglądarka musi wiedzieć, że treść jest przycinana. white-space: nowrap zabrania zawijania linii, w przeciwnym razie tekst przejdzie do następnej linii i nie nastąpi przepełnienie.
Do przycinania wieloliniowego (np. 2 linie z wielokropkiem na końcu drugiej) wcześniej używano eksperymentalnej właściwości -webkit-line-clamp, która teraz jest standardem jako line-clamp w CSS Overflow Level 4.
W praktyce text-overflow: ellipsis jest obsługiwane przez wszystkie nowoczesne przeglądarki od ponad 10 lat i jest najbardziej niezawodnym sposobem przycinania tekstu w sieci.
Wybór trybu ellipsize wpływa na UX i może zarówno poprawić odbiór interfejsu, jak i zdezorientować użytkownika. Główna zasada: użytkownik oczekuje, że przycięta część znajduje się tam, gdzie jest najmniej potrzebna do zrozumienia.
Tryb END pasuje do nagłówków, etykiet, nazw — użytkownik widzi początek linii i rozumie kontekst. Wielokropek po prawej oznacza „istnieje kontynuacja, ale się nie zmieściła". Jest to najbardziej intuicyjny i rozpowszechniony tryb.
Tryb MIDDLE jest niezastąpiony dla ścieżek plików, adresów email i długich identyfikatorów. Gdy koniec linii zawiera unikalną informację (nazwa pliku, domena), użytkownik powinien widzieć właśnie ją, a początek można skrócić. Przykład: "/User/.../important_document.pdf" — od razu widać nazwę pliku.
Tryb START jest używany rzadko, ale przydatny dla listy kontaktów ze wspólnym prefiksem — na przykład "...@gmail.com" zamiast "username@gmail.com", gdy wszystkie adresy należą do jednej domeny. Jednak taki wzorzec częściej dezorientuje niż pomaga. Według Nielsen Norman Group, użytkownicy czytają od lewej do prawej i oczekują ważnych informacji na początku, dlatego START-przycinanie zwiększa obciążenie poznawcze.
Tryb MARQUEE (ruchomy tekst) jest odpowiedni tylko dla jednoelementowych komponentów o niskiej częstotliwości odświeżania: bieżący utwór w odtwarzaczu, ticker wiadomości, pasek stanu. Nie używaj marquee w tabelach, listach lub formularzach — animacja rozprasza i obniża wydajność na słabych urządzeniach.
Pierwszy problem — ellipsize nie działa. Najczęściej przyczyną jest brak ograniczenia liczby linii. Bez maxLines TextView rośnie na wysokość i nie dochodzi do przepełnienia w poziomie. Rozwiązanie: zawsze podawaj maxLines (lub singleLine="true" dla jednej linii).
Drugi problem — wielokropek nie pojawia się przy programowej zmianie tekstu. Po wywołaniu setText() TextView może nie przerysować się poprawnie. Rozwiązanie: wywołaj invalidate() lub post(() -> requestLayout()) po zmianie tekstu.
Trzeci problem — różne zachowanie na różnych wersjach Androida. Przed API 23 ellipsize w trybie wieloliniowym (maxLines > 1) nie było obsługiwane. Rozwiązanie: dla zgodności sprawdzaj Build.VERSION.SDK_INT i używaj ViewCompat.setEllipsize() z AndroidX.
Czwarty problem — symbol wielokropka nie wyświetla się w niestandardowych czcionkach. Jeśli czcionka nie zawiera glifu U+2026, wielokropek jest zastępowany trzema kropkami. Rozwiązanie: sprawdź czcionkę pod kątem obecności glifu ellipsis lub dodaj fallback-font przez fontFamily.
Często zadawane pytania
Tak, maxLines lub singleLine jest obowiązkowe. Bez ograniczenia liczby linii TextView będzie rozszerzać się na wysokość i przycinanie nie zostanie aktywowane.
Ellipsize dodaje wielokropek w miejscu przerwania, informując użytkownika o ukrytym tekście. Clip po prostu przycina tekst do granicy bez żadnego wskaźnika.
Standardowy text-overflow: ellipsis przycina po całym słowie. Aby przyciąć w środku słowa, użyj overflow-wrap: break-word lub rozwiązania JavaScript z mierzeniem szerokości.
Tak, przez właściwość textContainer.lineBreakMode w NSTextContainer. Domyślnie UITextView używa .byWordWrapping; zmień na .byTruncatingTail/Middle/Head dla przycinania.
Wywołaj textView.setEllipsize(null) lub textView.setEllipsize(TextUtils.TruncateAt.NONE). Po tym tekst będzie zawijany, a nie przycinany.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również