Pull to refresh

Кроссбраузерный text-overflow \(^_^)/

Reading time5 min
Views27K
В случае, когда текст не влезает в ширину блока, есть несколько вариантов его визуализации:
  1. Разрешить ему вылезать за пределы блока. В большинстве случаев смотрится весьма косячно.
  2. Обрезать текст по границе блока. То же смотрится некузяво.
  3. Обрезать и нарисовать скроллинг. Это вообще жуть какая-то.
  4. Обрезать и сделать плавное затухание к краю так чтобы места обрезания букв не было видно. Сложно применять в случае неоднородного фона. Приходится вручную прятать затухание, когда текст имеет ширину меньше или равную ширине блока.
  5. Укорачивать текст, вставляя вконце многоточие.
О реализации последней стратегии и пойдёт далее речь...

В trident, presto и webkit есть родная поддержка, которая включается следующим образом:

overflow: hidden;<br>text-overflow: ellipsis;<br>-o-text-overflow: ellipsis;

Gecko к сожалению поддерживает эллипсинг только для однострочных xul:label и xul:description. Кроме того, он поддерживает замечательную технологию xbl с помощью которой можно реализовать поддержку эллипсинга и для других элементов:

<?xml version="1.0"?><br><bindings xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"><br><br><binding id="none"><br>    <content><children/></content><br></binding><br><br><binding id="ellipsis"><br>    <content><br>        <xul:label crop="end"><children/></xul:label><br>    </content><br>    <implementation><br>        <field name="label"> document.getAnonymousNodes( this )[ 0 ] </field><br>        <field name="style"> this.label.style </field><br>        <property name="display"><br>            <getter> this.style.display </getter><br>            <setter> if( this.style.display != val ) this.style.display= val </setter><br>        </property><br>        <property name="value"><br>            <getter> this.label.value </getter><br>            <setter> if( this.label.value != val ) this.label.value= val </setter><br>        </property><br>        <method name="update"><br>            <body><br>                var strings= this.textContent.split( /\s+/g )<br>                if( !strings[ 0 ] ) strings.shift()<br>                if( !strings[ strings.length - 1 ] ) strings.pop()<br>                this.value= strings.join( ' ' )<br>                this.display= strings.length ? '' : 'none'<br>            </body><br>        </method><br>        <constructor> this.update() </constructor><br>    </implementation><br>    <handlers><br>        <handler event="DOMSubtreeModified"> this.update() </handler><br>    </handlers><br></binding><br><br></bindings>

Тут два бинда: ellipsis включает эллипсинг, а none выключает. Подключаются они соответственно:

-moz-binding: url( 'bindings.xml#ellipsis' );
-moz-binding: url( 'bindings.xml#none' );

Когда мы включаем эллипсинг, создаётся «анонимный» элемент xul:label, который не видится обычными дом-методами, но располагается аккурат между исходным элементом и его детьми. К сожалению, xul:label укорачивает текст только если он задан через аттрибут value, поэтому приходится копировать в него текстовое содержимое из исходного элемента при каждом изменении дочернего поддерева.

Кроме того, приходится бороться с некоторыми особенностями:
  1. Вручную нормализовывать пробелы.
  2. Скрывать xul:label когда у него пустое содержимое.
Также приходится мириться и с некоторыми недостатками:
  1. Кроссбраузерно можно эллипсить только текст, принудительно вытянутый в одну строку.
  2. Внутри исходного элемента должен быть только текст, ибо мозилла всё-равно вырежет все тэги.
  3. В мозилле нельзя выделить текст, подвергшийся омноготочиванию.
Если есть идеи как побороть эти недостатки — милости прошу в комменты.

Чтобы не заниматься копипастом и избежать возможных конфликтов, предлагаю заготовку css-правил:

.v-ellip, v\:ellip {<br>    text-overflow: ellipsis;<br>    -o-text-overflow: ellipsis;<br>    -moz-binding: url( 'bindings.xml#ellipsis' );<br>    white-space: nowrap;<br>    overflow: hidden;<br>    display: inline-block;<br>    max-width: 100%;<br>}

А вот примеры её использования:

<body xmlns:v="urn:markup:visual"><br><br>    <p><br>        <a href="#"><v:ellip><!-- А тут ничего нет :-Р --></v:ellip></a><br>    </p><br>    <br>    <p><br>        <a href="#" class="v-ellip"> Какой-то текст </a><br>    </p><br>    <br>    <p><v:ellip><br>        Ооооочеееееееенььдлиииинноооооееееслооовоооо<br>        Ееееещёёёёёёооооодноооооо<br>    </v:ellip></p><br><br></body>

Попробовать прямо сейчас всего за 99.9 центов!
Tags:
Hubs:
+38
Comments55

Articles