Как отобразить акценты над словами разными цветами в HTML/CSS?
У меня есть такой текст, отображаемый в HTML:
pīngpāngqiúpāi
Как я могу изменить цвет текста, чтобы текст был синим, а акценты выше - красным?
2 ответа
CSS рассматривает букву как единое целое и поэтому может быть только одного цвета.
Вот хакерская версия:
Это будет работать, только если контент останется прежним.
span{
font-size:48px;
color:blue;
position:relative;
}
span:after{
content:'pīngpāngqiúpāi';
position:absolute;
left:0;
height:20px;
overflow:hidden;
z-index:9999;
color:red;
}
<span>pīngpāngqiúpāi</span>
Лично я бы не стал этим пользоваться. Это ужасный способ сделать это.
Я думаю, что у вас нет чистого решения с использованием чистого CSS. Как сообщает BeatAlex, для вас будет хорошей идеей реализовать какой-нибудь скрипт, который прекрасно решит вашу проблему. Фактически я подумал об использовании 2 оверлеев для создания желаемого эффекта, однако отличие от идеи BeatAlex в том, что верхним оверлеем будут не акцентированные версии акцентированных букв. Это требует от нас преобразования букв с акцентом в соответствующие буквы без акцента. Однако я обнаружил, что идея использования overflow:hidden
применяется в этом случае действительно хорошо. Я хотел бы позаимствовать эту идею и реализовать скрипт, выполняющий решение (которое полностью пригодно для использования). Идея в том, что вам просто нужно найти все акцентированные буквы (в оригинальном тексте), заверните каждую span
элемент, а затем применить стиль к этим элементам span. Я хотел бы упомянуть, что я не реализовал правильный код, чтобы иметь возможность фильтровать / обнаруживать все возможные акцентированные буквы, наконец, это все еще начало для вас, чтобы завершить его. Детали кода:
CSS:
.distinct-accent {
font-size:30px;
color:blue;
}
.with-accent {
position:relative;
display:inline-block;
}
.with-accent:before {
content:attr(data-content);
position:absolute;
left:0;
top:0;
height:0.4em;
width:100%;
padding-right:0.1em;
color:red;
overflow:hidden;
}
JS:
$(".distinct-accent").html(function(i, oldhtml){
var newhtml = "";
for(var i = 0; i < oldhtml.length; i++){
var nextChar = "";
var code = oldhtml.charCodeAt(i);
if((code > 64 && code < 90) ||
(code > 96 && code < 123) || code == 32) nextChar = oldhtml[i];
else {
nextChar = "<span class='with-accent' data-content='" + oldhtml[i] + "'>" + oldhtml[i] + "</span>";
}
newhtml += nextChar;
}
return newhtml;
});
Demo.
Обновление: ПРИМЕЧАНИЕ. Приведенный выше код хорошо работал раньше во всех браузерах на основе webkit (таких как Chrome), но теперь он не работает по неизвестной причине (content:attr
неправильно применяется с динамически обновляемым контентом через настройки innerHtml
). Должно быть какое-то изменение (которое можно считать ошибкой) в Chrome, что приводит к тому, что он не работает. Особенно вы увидите, что вывод HTML будет правильно отображаться после открытия и закрытия панели инспектора).
Чтобы исправить эту проблему, я просто добавил простой хак (удалив элемент и вставив обратно, чтобы принудительно применить правило CSS). Почти приведенный выше код остается неизменным.
Просто добавьте этот скрипт:
.each(function(){
$(this).replaceWith($(this).clone(true));
});
Расширяя другие решения здесь, вы действительно можете достичь решения, которое не требует размещения диакритических знаков только в верхней части буквы.
Вы можете сделать это, просто перекрыв две версии (с диакритическими знаками и без них) и используяtext-shadow
чтобы скрыть утечку сглаживания, которая, очевидно, возникает в таких ситуациях.
Пример размытия цвета сглаживания по краям текста. Обратите внимание на мягкий красный ореол / свечение вокруг черных символов.
Вы также можете просто установить для текста с диакритическими знаками другую непрозрачность, если хотите, чтобы они были "серыми", тем самым ограничивая эффект кровотечения.
Применяются некоторые предостережения:
Если вы хотите раскрасить точку
i
вам нужен символ U+0131 ЛАТИНСКАЯ СТРОЧНАЯ БУКВА БЕЗ ТОЧЕК I (см. пример "Spinal Tap")Все решения в настоящее время по этому вопросу основаны на том факте, что символы не меняют свои метрики при добавлении или удалении диакритических знаков. Это не всегда верно, например, с
i
а такжеï
(см. последний пример).Иногда к основной форме буквы добавляются диакритические знаки, например
ç
. Это нарушает нашиtext-shadow
трюк очень плохо.С помощью
text-shadow
не идеальное решение. Для этого требуется, чтобы фон был одновременно сплошным и известным во время разработки.
В следующем фрагменте я также использую настраиваемые свойства CSS (также известные как переменные CSS), чтобы не повторять цвет фона внутри text-shadow
, а при наведении курсора можно увидеть, что происходит, когда text-shadow
устранен.
:root {
--body-bg: white;
}
body {
display: flex;
min-height: 100vh;
justify-content: center;
align-items: center;
font-family: sans-serif;
font-size: 30px;
flex-direction: column;
background: var(--body-bg);
}
.setting {
font-size: 14px;
display: flex;
align-items: baseline;
}
body>* {
padding: 10px;
}
[data-with-diacritics] {
display: inline-block;
position: relative;
text-shadow: -1px -1px 0px var(--body-bg), 1px -1px 0px var(--body-bg), -1px 1px 0px var(--body-bg), 1px 1px 0px var(--body-bg);
}
[data-with-diacritics]::before {
content: attr(data-with-diacritics);
position: absolute;
color: red;
}
[data-with-diacritics]>span {
position: relative;
}
[data-with-diacritics]:hover {
text-shadow: none;
outline: 1px solid red;
}
<span data-with-diacritics="Spın̈al Tap">
<span>Spınal Tap</span>
</span>
<span data-with-diacritics="España">
<span>Espana</span>
</span>
<span data-with-diacritics="Français">
<span>Francais</span>
</span>
<span data-with-diacritics="äëïiöü ãõ">
<span>aeııou ao</span>
</span>