Показывать дефисы только тогда, когда это действительно необходимо? (Мягкие дефисы не режут)

Можно ли использовать дефисы или мягкие дефисы в CSS таким образом, чтобы дефисы не создавались без необходимости?

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

Мой конкретный случай

Я хочу сделать текст "Привет, Супермен" таким образом, чтобы:

Если слово "Супермен" слишком длинное, чтобы поместиться в контейнере, я хочу каким-то образом дефисировать его, например:

Hi Super-
man

Но если слово "Супермен" может поместиться в контейнере, оно должно быть отображено без дефисов

Hi
Superman

Если описанный выше случай возможен ("Супермен" может быть написан без дефиса), НЕДОПУСТИМО добавлять такие ненужные дефисы, как это:

Hi Super-
man

Я могу изменить HTML, как я хочу. Мне разрешено вводить дефисы так, чтобы это имело смысл (если между каждым дефисом больше 3 букв, то все в порядке. "Суперма-н" никогда не бывает в порядке)

Что я пробовал

Я думал, что мягкие дефисы будут решением. Поэтому я использовал: Hi Super­man

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

Фрагмент, чтобы показать ошибку:

body { 
  margin-left: 30px;
}
div {
   border: solid 1px black;
}
.wide {
  border: solid 1px blue;
      width: 500px;
}
.narrow { 
  border: solid 1px red;
  width: 360px;
}
 h2 {
   font-family: 'Courier New';
    font-weight: 400;
    font-size: 87px;
  }
code {
 background-color: #eee;
}
<p> <code>Super&amp;shy;man</code> looks good in really narrow containers where the full word "Superman" would not fit</p>
<p>
<div class="narrow"><h2>Hi Super&shy;man</h2></div>

<p>But in this case the word "Superman" would fit unhypenhated on the second row. But the damn CSS decides to add hyphens anyway. Unacceptable in my case!
Again, this uses the same code as the previous example
<code>Super&amp;shy;man</code></p>
<div class="wide"><h2>Hi Super&shy;man</h2></div>

<p>I even tried adding a wordbreak tag before "Superman", like this <code>Hi &lt;wbr&gt; Super&amp;shy;man</code> but it does not help</p>
<p>  </p>
<div class="wide"><h2>Hi <wbr>Super&shy;man</h2></div>

Могу ли я решить приведенный выше пример только с помощью CSS? (Пробовал разные word-break свойства без успеха)

Я предполагаю, что это невозможно решить с помощью простого HTML и CSS из-за природы CSS. Я предполагаю, что CSS просто разбирает текст построчно, и он никогда не узнает, будет ли слово "лучше подходить" для следующей строки текста. Если он находит дефис, он попытается вписать максимальное количество символов в текущей строке текста.

Я хочу решить эту проблему только с помощью HTML и CSS или нет вообще. Редактировать: предпочтительно - нет разбора текста с помощью JavaScript.

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

-Я предпочел бы не добавлять обертки вокруг моих слов

Нет авто-переносов, которые могут привести к смехотворным переносам, таким как "Superma-n" (однако, в крайнем случае, я буду в порядке с автоавтофенированием, если между каждым дефисом будет 3 символа. Как "Sup-erman")

2 ответа

Решение

Используйте контейнер с display: inline-block вокруг длинных слов.

body { 
  margin-left: 30px;
}
div {
   border: solid 1px black;
}
.wide {
  border: solid 1px blue;
      width: 500px;
}
.narrow { 
  border: solid 1px red;
  width: 360px;
}
 h2 {
   font-family: 'Courier New';
    font-weight: 400;
    font-size: 87px;
  }
code {
 background-color: #eee;
}

.unbreakable {display:inline-block}
<p> <code>Super&amp;shy;man</code> looks good in really narrow containers where the full word "Superman" would not fit</p>
<p>
<div class="narrow"><h2>Hi <span class="unbreakable">Super&shy;man</span></h2></div>

<p>And in this case the word "Superman" would fit unhypenhated on the second row.<br/>
This uses the same code as the previous example</p>
<div class="wide"><h2>Hi <span class="unbreakable">Super&shy;man</span></h2></div>

Изменить: О, я нашел недостаток: слова, которые ломаются в обертке, занимают все две строки, а не позволяют более короткие слова в одной строке. В приведенном ниже примере текст "человек есть" поместился бы в одну строку, если бы не этот трюк.

body {
  margin-left: 30px;
}

.narrow {
  border: solid 1px red;
  width: 360px;
}

h2 {
  font-family: 'Courier New';
  font-weight: 400;
  font-size: 87px;
}

.unbreakable {
  display: inline-block
}
<div class="narrow">
  <h2><span class="unbreakable">Super&shy;man</span> is coming.</h2>
</div>

Так что нет, не идеально. Сожалею.

CSS 3 включает в себя hyphens "свойство, которое устанавливает переносы в соответствии с указанным lang приписывать. Но это едва рабочий проект, так что поддержки пока нет.

Вы можете установить его на

  • нет, поэтому дефисы не отображаются
  • ручной, поэтому он будет разбивать слова только там, где специальный символ &shy был объявлен, или
  • auto, который автоматически добавит дефисы в случае необходимости в соответствии с локализацией.

Работает как Firemax, Edge и даже IE, как шарм, но главная проблема заключается в том, что webkit не поддерживает значение "auto". За исключением Mac и Android, где это единственное значение, которое они примут. Да, это такая странная ошибка.

Вот пример, обязательно проверьте разницу между Firefox и Chrome, если вы используете Windows / Linux.

p { 
  width: 55px;
  border: 1px solid black;
 }
p.none {
  -webkit-hyphens: none;
  -ms-hyphens: none;
  hyphens: none;
}
p.manual {
  -webkit-hyphens: manual;
  -ms-hyphens: manual;
  hyphens: manual;
}
p.auto {
  -webkit-hyphens: auto;
  -ms-hyphens: auto;
  hyphens: auto;
}
<ul>
    <li><code>auto</code>: hyphen where the algorithm is deciding (if needed)
    <p lang="en" class="auto">An extremelyasdasd long English word</p>
  </li> 
  <li><code>manual</code>: hyphen only at &amp;hyphen; or &amp;shy; (if needed)
    <p lang="en" class="manual">An extreme&shy;lyasd long English word</p>
  </li>
  <li><code>none</code>: no hyphen; overflow if needed
    <p lang="en" class="none">An extreme&shy;lyasd long English word</p>
  </li>
</ul>

Обычный обходной путь для отсутствия поддержки "auto" в webkit - использование дефисов:auto вместе с work-break:break-all для webkit, поэтому текст будет дефисирован в браузерах, которые его поддерживают, и переносится без дефисов в webkit.

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