Есть ли обходной путь CSS для ошибки Firefox: inline-block + first-letter с измененным размером - PullRequest
18 голосов
/ 26 сентября 2011

Лучше увидеть ошибку в Firefox: http://jsfiddle.net/kizu/btdVd/

Картинка, показывающая ошибку:

enter image description here

И ошибка , заполненная в 2007 году на bugzilla .

Ошибка появляется, когда вы добавляете ::first-letter псевдоэлемент с помощью display: inline-block, а затем изменяете font-size этого first-letter.

Больше букв в слове после первого: добавлено больше свободного места (или вычтено - если размер шрифта меньше, чем у блока).

Добавление float: left к first-letter инвертирует ошибку: при увеличении размера шрифта ширина inline-block уменьшается.

Итак, вопрос: есть ли обходной путь только для CSS для этой ошибки? Это несколько убивает меня.

Ответы [ 4 ]

15 голосов
/ 26 сентября 2011

Я обнаружил, что запуск перекомпоновки на всей странице (или любом блоке с проблемой) решает проблему, поэтому я нашел способ вызвать его на каждом таком блоке с помощью одноразовой CSS-анимации: http://jsfiddle.net/kizu/btdVd/23/

Тем не менее, хотя у этого исправления нет недостатков в рендеринге, у него есть и другие:

  • , оно будет работать только для Fx5 + (который поддерживает анимацию);
  • он по-прежнему мигает исходную ошибку в течение нескольких мс, так что, возможно, он несколько мигает.

Итак, это не идеальное решение, но в некоторой степени поможет, если Fx4- устареет.Конечно, вы можете запускать такое исправление при помощи JS, но это не так приятно.

7 голосов
/ 26 сентября 2011

Не думаю, что есть хорошее решение.

Я придумала для вас нестабильное решение:

.test:first-letter {
    font-size: 2em;
    letter-spacing: -0.225em;
}

Добавьте стиль letter-spacing к :first-letter селектор в вашей скрипке, и вы обнаружите, что блоки возвращаются к примерно нужного размера.

Объяснение:

По сути,ошибка вызвана тем, что весь блок берет его размер из шрифта, указанного в first-letter.

То, что я делаю здесь с letter-spacing, пытается отрегулировать размер этого шрифта, не затрагиваяэто внешность.Подобная корректировка межбуквенного интервала в обычном тексте приведет к тому, что буквы будут перекрывать друг друга на 0,225 ширины символов с обеих сторон.

Сначала я надеялся, что будет достаточно значения -0,25.то есть четверть символа на каждой стороне уменьшит ширину каждого символа вдвое, что было бы тем, что мы хотим, потому что первая буква font-size:2em, поэтому она в два раза больше.

Однако расчетне настолько чист, как это, потому что первый и последний символы в строке будут перекрываться только с одной стороны, и потому что первая буква действительно хочет быть двойной ширины, даже если остальные символы неt.

Все это означает, что точное значение letter-spacing, необходимое для противодействия ошибке, будет варьироваться в зависимости от длины текста, а также размеров шрифта исходного текста и первой буквы.Вот почему мне пришлось немного поэкспериментировать со значением межбуквенного промежутка, чтобы заставить его работать, а также объяснить, почему я не смог идеально вписаться во все строки текста в вашей скрипке.Мне бы понадобилось немного другое значение для каждого блока.

Кажется, значение -0,225 самое близкое к нему, которое я могу найти, которое подходит для всех ваших примеров, но на практике вам нужно настроитьон подходит для вашего сайта.

Не забывайте также, что это ошибка Firefox, и поэтому вам нужно будет записать ее в качестве специфического взлома для браузера.И будьте осторожны, чтобы следить за сообщением об ошибке Firefox, которое вы связали;когда это все исправят, вам нужно будет найти способ сохранить взлом для пользователей старых версий, но удалить его для пользователей с исправлением.

[EDIT]

Единственное другое рабочее решение, которое я придумал, - просто не использовать функции, которые вызывают ошибку.т. е. отбросьте селектор :first-letter и используйте отдельный <span> для первой буквы вашего текста, если вы хотите по-разному его оформить.

Это действительно очевидный ответ, который, конечно, решит проблему.(и также означало бы, что ваша стилизованная первая буква работает в более старых браузерах), но она не была бы идеальной с семантической точки зрения и, что более важно, на самом деле не отвечает на вопрос, поэтому я не предложил ее в качестве решенияв моем первоначальном ответе.

Я также пытался найти альтернативное решение проблемы, но варианты ограничены, и ничто из того, что я пробовал, не дало таких хороших результатов, как мое первоначальное предложение.

Я попытался сделать :first-letter невидимым и использовать :before для отображения большой заглавной буквы.Тем не менее, это не сработало для меня.Я не задерживался на этом слишком долго, поэтому вы можете заставить его работать, но есть проблема с ним в том, что вам придется определить начальную букву в вашем CSS, что не было бы идеально.

Другим возможным решением является использование свойства font-stretch: condensed; CSS в :first-letter.Это уменьшит ширину первой буквы до 1em и, таким образом, решит проблему ширины остальной части текста.Недостатки этого, однако, заключаются в том, что, во-первых, начальная буква будет выглядеть сжатой, что, вероятно, не то, что вам нужно, а во-вторых, этот стиль работает только для шрифтов, которые поддерживают свойство condensed.Оказывается, что это не очень хорошо поддерживается стандартными шрифтами, поэтому может оказаться неприемлемым для вас.

В конце концов, оригинальное решение letter-spacing по-прежнему является единственным способом, который я нашел, чтобы действительно обойти эту ошибку.

0 голосов
/ 20 марта 2018

Я знаю, что эта тема довольно старая, но, видимо, эта ошибка еще не исправлена.

Использование animation работает, но есть заметный FOUT (Flash of Unstyled Text). Я смог обойти эту проблему, обернув first-letter в span. Это работает как с проблемой определения размера, так и с FOUT, оно добавляет дополнительные элементы к разметке, поэтому зависит ли это от потребностей вашего сайта / приложения, если это лучше всего подходит.

.test {
    background: rgba(0,0,0,0.15); /* For visualisation */
    display: inline-block;
}

.test:first-letter {
    font-size: 2em;
}

.test2:first-letter {
    float: left;
}
.test3:first-letter {
    font-size: .5em;
}
<h1>Inline-block with bigger first-letter</h1>

<span class="test">Broken</span>
<br><br>
<span class="test"><span>F</span>ixed</span>


<h1>+ floating to first-letter</h1>

<span class="test test2">Broken</span>
<br><br>
<span class="test test2"><span>F</span>ixed</span>
 

<h1>small size for first-letter</h1>

<span class="test test3">Broken</span>
<br><br>
<span class="test test3"><span>F</span>ixed</span>

<h1>small size, floating first-letter</h1>

<span class="test test2 test3">Broken</span>
<br><br>
<span class="test test2 test3"><span>F</span>ixed</span>
0 голосов
/ 24 января 2014

Эта ошибка все еще существует, но некоторые исправления больше не работают.Даже после запуска перекомпоновки с анимацией, встроенный блок вернулся к тому же размеру для меня.Я не мог использовать трюк letter-spacing, потому что я уже использую его в первой букве, это то, что вызывает у меня проблему.Я решил проблему, добавив это в CSS для затронутого селектора:

-moz-padding-end: *number of pixels to compensate*;

В данный момент moz-padding-end, кажется, относится к Firefox, и он может добавлять или удалять ширину в концевстроенный блок.Поскольку это ошибка, специфичная для Firefox, это помогло мне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...