Ellipsize — это механизм обрезки текста, при котором вместо пиксельного обрезания строки в конец или середину добавляется символ многоточия (…), сигнализирующий пользователю, что текст не поместился в контейнер. Эта техника используется в заголовках, кнопках, списках контактов и любых UI-компонентах с ограниченной шириной. По данным Google Material Design Guidelines, ellipsize является стандартным поведением для TextView и UILabel, поддерживая четыре режима обрезки: начало, середина, конец и бегущая строка.
Главное
Ellipsize (от англ. ellipsis — многоточие) — это техника отображения текста, который превышает размеры контейнера. Вместо того чтобы просто обрезать строку по границе (clip), ellipsize добавляет символ многоточия (три точки, Unicode U+2026), указывая пользователю на наличие скрытого содержимого.
Термин закрепился в Android SDK, где свойство android:ellipsize определяет поведение TextView при переполнении. На iOS аналогичная функциональность называется truncation (обрезание) и управляется через NSLineBreakMode. В вебе используется CSS-свойство text-overflow со значением ellipsis.
Основная цель ellipsize — информировать пользователя, что текст сокращён. В отличие от обрезания по пикселям, где слово может быть разорвано на половинки, ellipsize гарантирует читаемость: многоточие ставится после целого слова или символа, не разрывая его. Это соответствует принципам Material Design и Human Interface Guidelines.
Используйте ellipsize везде, где ширина контейнера фиксирована, а длина текста динамическая: заголовки статей, ячейки таблиц, кнопки с подписями, контакты в списке, хлебные крошки и пути файлов.
В Android ellipsize настраивается через атрибут android:ellipsize в XML или метод setEllipsize() в коде. Доступны четыре режима, каждый из которых определяет, с какой стороны текст будет обрезан.
Режим END (по умолчанию в большинстве случаев) обрезает конец строки и ставит многоточие в правой части контейнера. Режим START обрезает начало — многоточие слева, видимый текст справа. MIDDLE обрезает середину, оставляя начало и конец строки видимыми. Режим MARQUEE — анимированная прокрутка текста, при которой многоточие не показывается, а текст циклически прокручивается.
<!-- 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)
Важно: ellipsize работает только в комбинации с maxLines или singleLine. Если не ограничить количество строк, TextView будет расти по высоте, и ellipsize не включится. Начиная с Android 8.0 (API 26), ellipsize поддерживает многострочный режим с maxLines > 1 — многоточие ставится в конце последней строки.
Для программного вызова используйте TextUtils.TruncateAt с одним из значений: END, START, MIDDLE, MARQUEE. Значение NONE отключает ellipsize.
На практике END подходит для 90% случаев — пользователи ожидают, что текст обрезан в конце. MIDDLE используется для путей файлов (например, "/User/.../project/main.kt"), чтобы был виден конец пути. START — для имён с общим префиксом (например, "...@gmail.com").
На iOS аналог ellipsize — свойство lineBreakMode класса UILabel (и NSTextContainer для UITextView). Доступны три режима обрезки: .byTruncatingTail (конец), .byTruncatingMiddle (середина) и .byTruncatingHead (начало).
Режим .byTruncatingTail соответствует android:ellipsize="end". Режим .byTruncatingHead — START, .byTruncatingMiddle — MIDDLE. Режим .byClipping — обрезает текст без многоточия, что редко используется в современных интерфейсах. Режим .byCharWrapping — перенос по символам без обрезки.
let label = UILabel()
label.text = "Long text that does not fit the label bounds"
label.lineBreakMode = .byTruncatingMiddle
label.numberOfLines = 1
// NSAttributedString also supports lineBreakMode
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byTruncatingTail
В iOS truncation работает в паре с numberOfLines. Если numberOfLines = 1, текст обрезается на одной строке. Если numberOfLines = 2 — на второй строке. UITextView использует NSTextContainer.lineBreakMode, который также поддерживает все три режима обрезки.
Особенность iOS: режим .byTruncatingMiddle на UILabel может вести себя неочевидно на коротких строках — если строка помещается целиком, многоточие не появляется. Для гарантированного отображения многоточия на коротких строках используйте кастомную логику через sizeThatFits.
В вебе ellipsize реализуется через CSS-свойство text-overflow: ellipsis в комбинации с overflow: hidden и white-space: nowrap. Это стандартный способ обрезки строки с многоточием в веб-интерфейсах.
.text-cell {
width: 250px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Свойство text-overflow не работает без overflow: hidden — браузеру нужно знать, что контент обрезается. white-space: nowrap запрещает перенос строки, иначе текст уйдёт на следующую строку, и переполнения не произойдёт.
Для многострочной обрезки (например, 2 строки с многоточием в конце второй) раньше использовали экспериментальное свойство -webkit-line-clamp, которое теперь стандартизировано как line-clamp в CSS Overflow Level 4.
На практике text-overflow: ellipsis поддерживается всеми современными браузерами более 10 лет и является самым надёжным способом обрезки текста в вебе.
Выбор режима ellipsize влияет на UX и может как улучшить восприятие интерфейса, так и запутать пользователя. Основное правило: пользователь ожидает, что обрезанная часть — там, где она меньше всего нужна для понимания.
Режим END подходит для заголовков, подписей, названий — пользователь видит начало строки и понимает контекст. Многоточие справа означает «продолжение есть, но оно не поместилось». Это самый интуитивный и распространённый режим.
Режим MIDDLE незаменим для путей файлов, email-адресов и длинных идентификаторов. Когда конец строки содержит уникальную информацию (имя файла, домен), пользователь должен видеть именно его, а начало можно сократить. Пример: "/User/.../important_document.pdf" — сразу видно имя файла.
Режим START используется редко, но полезен для списка контактов с общим префиксом — например, "...@gmail.com" вместо "username@gmail.com", когда все адреса относятся к одному домену. Однако такой паттерн чаще запутывает, чем помогает. По данным Nielsen Norman Group, пользователи читают слева направо и ожидают важную информацию в начале, поэтому START-обрезка повышает когнитивную нагрузку.
Режим MARQUEE (бегущая строка) уместен только для однострочных элементов с невысокой частотой обновления: текущий трек в плеере, тикер новостей, статусная строка. Не используйте marquee для таблиц, списков или форм — анимация отвлекает и снижает производительность на слабых устройствах.
Первая проблема — ellipsize не срабатывает. Чаще всего причина в отсутствии ограничения количества строк. Без maxLines TextView растёт по высоте, и переполнения по ширине не происходит. Решение: всегда указывайте maxLines (или singleLine="true" для одной строки).
Вторая проблема — многоточие не показывается при программном изменении текста. После вызова setText() TextView может не перерисоваться корректно. Решение: вызовите invalidate() или post(() -> requestLayout()) после изменения текста.
Третья проблема — разное поведение на разных версиях Android. До API 23 ellipsize в многострочном режиме (maxLines > 1) не поддерживался. Решение: для совместимости проверяйте Build.VERSION.SDK_INT и используйте ViewCompat.setEllipsize() из AndroidX.
Четвёртая проблема — символ многоточия не отображается в кастомных шрифтах. Если шрифт не содержит глиф U+2026, многоточие заменяется на три точки. Решение: проверьте шрифт на наличие ellipsis-глифа или добавьте fallback-шрифт через fontFamily.
Часто задаваемые вопросы
Да, maxLines или singleLine обязателен. Без ограничения количества строк TextView будет расширяться по высоте, и обрезка не активируется.
Ellipsize добавляет многоточие на месте обрыва, информируя пользователя о скрытом тексте. Clip просто обрезает текст по границе без какого-либо индикатора.
Стандартный text-overflow: ellipsis обрезает после целого слова. Для обрезки на середине слова используйте overflow-wrap: break-word или JavaScript-решение с измерением ширины.
Да, через свойство textContainer.lineBreakMode у NSTextContainer. По умолчанию UITextView использует .byWordWrapping; измените на .byTruncatingTail/Middle/Head для обрезки.
Вызовите textView.setEllipsize(null) или textView.setEllipsize(TextUtils.TruncateAt.NONE). После этого текст будет переноситься, а не обрезаться.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также