Как отобразить акценты над словами разными цветами в HTML/CSS?

У меня есть такой текст, отображаемый в HTML:

pīng​pāng​qiú​pāi

Как я могу изменить цвет текста, чтобы текст был синим, а акценты выше - красным?

2 ответа

CSS рассматривает букву как единое целое и поэтому может быть только одного цвета.

Вот хакерская версия:

Это будет работать, только если контент останется прежним.

span{
  font-size:48px;
  color:blue;
  position:relative;
}
span:after{
  content:'pīng​pāng​qiú​pāi';
  position:absolute;
  left:0;
  height:20px;
  overflow:hidden;
  z-index:9999;
  color:red;
}
<span>pīng​pāng​qiú​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 чтобы скрыть утечку сглаживания, которая, очевидно, возникает в таких ситуациях.

Пример размытия цвета сглаживания по краям текста. Обратите внимание на мягкий красный ореол / свечение вокруг черных символов.

Вы также можете просто установить для текста с диакритическими знаками другую непрозрачность, если хотите, чтобы они были "серыми", тем самым ограничивая эффект кровотечения.

Применяются некоторые предостережения:

  1. Если вы хотите раскрасить точку iвам нужен символ U+0131 ЛАТИНСКАЯ СТРОЧНАЯ БУКВА БЕЗ ТОЧЕК I (см. пример "Spinal Tap")

  2. Все решения в настоящее время по этому вопросу основаны на том факте, что символы не меняют свои метрики при добавлении или удалении диакритических знаков. Это не всегда верно, например, сi а также ï (см. последний пример).

  3. Иногда к основной форме буквы добавляются диакритические знаки, например ç. Это нарушает нашиtext-shadow трюк очень плохо.

  4. С помощью 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>

Другие вопросы по тегам