html (+ css): oznacza preferowane miejsce na koniec wiersza

109

Powiedzmy, że mam ten tekst, który chcę wyświetlić w komórce tabeli HTML:

Honey Nut Cheerios, Wheat Chex, Grape-Nuts, Rice Krispies, Some random cereal with a very long name, Honey Bunches of Oats, Wheaties, Special K, Froot Loops, Apple Jacks

i chcę, aby wiersz był preferencyjnie przerywany po jednym z przecinków.

Czy istnieje sposób, aby powiedzieć modułowi renderującemu HTML, aby spróbował złamać w jakimś wyznaczonym miejscu i zrobić to najpierw przed próbą przerwania po jednej ze spacji, bez używania nierozdzielających spacji? Jeśli używam nierozdzielających spacji, bezwarunkowo zwiększa to szerokość. Chcę, aby podział wiersza następował po jednej ze spacji, jeśli algorytm zawijania wierszy wypróbował go najpierw z przecinkami i nie może dopasować wiersza.

Próbowałem zawijać fragmenty tekstu w <span>elementy, ale to nie wydaje się pomagać.

<html>
  <head>
      <style type="text/css">
        div.box { width: 180px; }
        table, table td { 
          border: 1px solid; 
          border-collapse: collapse; 
        }
      </style>
  </head>
  <body>
    <div class="box">
      <table>
      <tr>
          <td>lorem ipsum</td>
          <td>lorem ipsum</td>
          <td>lorem ipsum</td>
      </tr>
      <tr>
          <td>lorem ipsum</td>
          <td>
            <span>Honey Nut Cheerios,</span>
            <span>Wheat Chex,</span>
            <span>Grape-Nuts,</span>
            <span>Rice Krispies,</span>
            <span>Some random cereal with a very long name,</span>
            <span>Honey Bunches of Oats,</span>
            <span>Wheaties,</span>
            <span>Special K,</span>
            <span>Froot Loops,</span>
            <span>Apple Jacks</span>
          </td>
          <td>lorem ipsum</td>
      </tr>
      </table>
    </div>
  </body>
</html>

uwaga: Wygląda na to, że zachowanie CSS3text-wrap: avoid jest tym, czego chcę, ale nie mogę go zmusić do działania.

Jason S.
źródło
w przęsłach można używać nierozdzielających spacji .
Gabriele Petrioli
3
Ale ja nie chcę używać non przestrzenie -breaking. Chciałbym użyć spacji „nie chcę-tu-łamać-ale-zrobię-jeśli-muszę-”, ale o ile wiem, one istnieją.
Jason S
@Jason .. czuję cię .. ale to nie jest możliwe .. dodałem odpowiedź.
Gabriele Petrioli
Drat, tak właśnie się dzieje, gdy informatycy piszą algorytmy renderowania bez danych wejściowych od typografów.
Jason S
1
powinieneś przyjąć odpowiedź od @ EggertJóhannesson, ponieważ zapewnia ona dobre obejście!
Gabriele Petrioli,

Odpowiedzi:

156

Używając

span.avoidwrap { display:inline-block; }

i zawijając tekst, w którym chcę być razem

<span class="avoidwrap"> Text </span>

będzie najpierw zawinięty w preferowane bloki, a następnie w razie potrzeby w mniejsze fragmenty.

Eggert Jóhannesson
źródło
16
Działa świetnie! Jeszcze jedna dodatkowa uwaga: spacje na początku i na końcu bloku inline-block są ignorowane, więc aby rozgraniczać tekst w blokach spacjami, musisz umieścić go między blokami inline. Na przykład, jeśli rozpiętości zostały stylizowane na bloki liniowe, to <span>Hello </span><span> world</span>będą Helloworldi <span>Hello</span> <span>world</span>będą normalne Hello world.
użytkownik
2
<wbr> jest bardziej semantyczny i pozostawia kontrolę w przeglądarce, co ogólnie jest dobre. W tym przypadku umożliwia złamanie, gdy jest to niezbędne.
Lodewijk
Działa świetnie - gdy jest to ważne, znaki takie jak „-” nie są przerywane. Przykład: Perikles <span class = "uniquewrap"> (um & nbsp; 500-429 & nbsp; v.Chr.) </span>
Sarah Trees
10
@Lodewijk: <wbr>nie wskazuje preferowanego miejsca na przerwanie linii, ale możliwe .
Dan Dascalescu
1
Zauważ, że ta technika działa również dla zagnieżdżonych <span>s, więc możesz (w efekcie) określić hierarchię preferowanych punktów przerwania.
Michael Dyck,
24

Jest bardzo zgrabne rozwiązanie RWD od Dan Mall, które wolę. Dodam to tutaj, ponieważ niektóre inne pytania dotyczące responsywnych podziałów linii są oznaczone jako duplikaty tego.
W twoim przypadku miałbyś:

<span>Honey Nut Cheerios, <br class="rwd-break">Wheat Chex, etc.</span>

I jeden wiersz CSS w zapytaniu o media:

@media screen and (min-width: 768px) {
    .rwd-break { display: none; }
}
Stephan Weinhold
źródło
7

Prostą odpowiedzią jest użycie znaku spacji o zerowej szerokości.&#8203; Jest on używany do tworzenia odstępów między wyrazami w określonych punktach .

Czy dokładnym przeciwieństwem tego non-breaking space &nbsp; (dobrze, faktycznie słowo-stolarskie &#8288; ) ( word-stolarskie jest zero-width wersja non-breaking space )

(istnieją również inne nierozdzielające kody, takie jak nierozdzielający myślnik &#8209; ) (tutaj jest obszerna odpowiedź na temat różnych „wariantów” nbsp )

Jeśli potrzebujesz rozwiązania tylko w HTML (bez CSS / JS), możesz użyć kombinacji spacji o zerowej szerokości i spacji nierozdzielającej , jednak byłoby to naprawdę niechlujne , a napisanie wersji czytelnej dla człowieka wymaga trochę wysiłku .

ctrl+ c, ctrl+ vpomaga

przykład:

   Honey&nbsp;Nut&nbsp;Cheerios,<!---->&#8203;<!--
-->Wheat&nbsp;Chex,<!---->&#8203;<!--
-->Grape&#8209;Nuts,<!---->&#8203;<!--
-->Rice&nbsp;Krispies,<!---->&#8203;<!--
-->Some&nbsp;random&nbsp;cereal&nbsp;with&nbsp;a&nbsp;very&nbsp;long&nbsp;name,<!---->&#8203;<!--
-->Honey&nbsp;Bunches&nbsp;of&nbsp;Oats,<!---->&#8203;<!--
-->Wheaties,<!---->&#8203;<!--
-->Special&nbsp;K,<!---->&#8203;<!--
-->Froot&nbsp;Loops,<!---->&#8203;<!--
-->Apple&nbsp;Jacks

nieczytelne? to jest ten sam HTML bez tagów komentarza:

   Honey&nbsp;Nut&nbsp;Cheerios,&#8203;Wheat&nbsp;Chex,&#8203;Grape&#8209;Nuts,&#8203;Rice&nbsp;Krispies,&#8203;Some&nbsp;random&nbsp;cereal&nbsp;with&nbsp;a&nbsp;very&nbsp;long&nbsp;name,&#8203;Honey&nbsp;Bunches&nbsp;of&nbsp;Oats,&#8203;Wheaties,&#8203;Special&nbsp;K,&#8203;Froot&nbsp;Loops,&#8203;Apple&nbsp;Jacks

Ponieważ jednak renderowanie HTML w wiadomościach e-mail nie jest całkowicie ustandaryzowane, jest dobre do tego rodzaju zastosowań, ponieważ to rozwiązanie nie wykorzystuje CSS / JS

Ponadto, jeśli użyjesz tego w połączeniu z którymkolwiek z <span>rozwiązań bazujących, będziesz mieć pełną kontrolę nad algorytmem łamania linii

(uwaga redakcyjna :)

Jedyny problem, jaki widzę, to to, że chcesz dynamicznie zmieniać punkty preferowanego pęknięcia. Wymagałoby to ciągłej manipulacji w JS na każdym z proporcjonalnych rozmiarów rozpiętości i konieczności obsługi tych elementów HTML w tekście.

Społeczność
źródło
1
co to są hacki span?
Jason S
Pozostałe odpowiedzi wykorzystują znaczniki span.
Chcę również zauważyć, że chociaż to rozwiązanie nie wydaje się najprostsze, jest najbardziej niezawodne, ponieważ te jednostki nie zmieniają i nie powinny często zmieniać reprezentacji semantycznej w przeglądarkach, parserach wiadomości e-mail lub innym parserze HTML.
3

Odpowiedź brzmi: nie ( nie możesz zmienić zastosowanego algorytmu łamania linii ).

Ale są pewne obejścia ( najlepszym z nich jest zaakceptowana odpowiedź )

Możesz zbliżyć się do nierozdzielającej spacji, &nbsp;ale tylko między słowami, które idą razem ( co masz w rozpiętości, ale nie po przecinku ), lub możesz użyć, white-space:nowrapjak wspomniano w @Marcel.

Oba rozwiązania robią to samo i oba nie zniszczą grupy słów, jeśli same nie będą pasować.

Gabriele Petrioli
źródło
argh. :-( to śmierdzi, to znaczy, że albo muszę z tym żyć, albo muszę sam spróbować wykryć długie linie, próbując pokonać algorytm łamania linii.
Jason S
Zredagowałem Twoją odpowiedź, aby podać link do obejścia tego problemu, ponieważ prawie nie kontynuowałem czytania z powodu sposobu, w jaki sformułowany jest Twój pierwszy wiersz.
arootbeer
@arootbeer: Popieram twoją edycję, ale Gaby ją cofnęła. Gaby: dlaczego? Chcesz wprowadzić użytkowników w błąd?
Dan Dascalescu
@DanDascalescu, czy wszystkie odpowiedzi SO powinny być zmienione tak, aby wskazywały na zaakceptowane na tej samej stronie? Moja odpowiedź ma 1 ( łącznie ) głos, a odpowiedź została zaakceptowana z 48 głosami. Jestem prawie pewien, że to akceptowany jest tym, który zwraca na siebie uwagę ( i słusznie ). Poza tym upieram się, że nie ma sposobu na zmianę zastosowanego algorytmu łamania (o co prosi PO )
Gabriele Petrioli
1
sprawdź, czy moje rozwiązanie używa Twojej własnej logiki przeciwko Tobie. w połączeniu z dowolnym rozwiązaniem zakresu, masz pełną kontrolę nad algorytmem łamania linii
2

Z marżą powyżej użyj span { white-space:nowrap }. Jest tak dobre, jak można się spodziewać.

Marcel
źródło
Dzięki, ale to nie zadziała, ponieważ w zasadzie tłumaczy spacje w spanelemencie na &nbsp;i zapobiega ich pękaniu. Chcę tylko zniechęcić moduł renderujący do włamania się między jeden z moich elementów, ale jeśli musi, chcę, aby to zrobił.
Jason S
@Jason S: Dodałem inne opcje do mojej odpowiedzi.
Marcel
czym &nbsp;<wbr>różni się od przestrzeni? Z tego co wiem, wybór jest taki, że dana postać pozwala na przerwę lub nie. Tak więc „-” i „” oraz &#8203;i <wbr>i &shy;wszystkie pozwalają na przerwę (odpowiednio wypisywanie łącznika, spacji, nic, nic i łącznika tylko przy łamaniu), podczas &nbsp;gdy nie.
Jason S
@Jason S: Dodano przykład użycia.
Marcel
Właśnie go wypróbowałem i wydaje się, że nie ma pierwszeństwa przed spacjami do łamania linii. Priorytetem jest to, czego potrzebuję. Jeśli zachowanie powodujące zerwanie dla innego znaku lub elementu to tak lub nie, to nie ma rozwiązania dla mojego problemu. Jeśli istnieją względne priorytety przełamywania linii, mogę mieć rozwiązanie.
Jason S
1

Nowa odpowiedź teraz mamy HTML5:

HTML5 wprowadza <wbr>tag. (To oznacza możliwość przełamania słów).

Dodanie znaku „ <wbr>mówi” przeglądarce, aby przerwała to miejsce wcześniej niż gdziekolwiek indziej, więc łatwo jest podzielić słowa po przecinkach:

Honey Nut Cheerios,<wbr> Wheat Chex,<wbr> Grape-Nuts,<wbr> Rice Krispies,<wbr> Some random cereal with a very long name,<wbr> Honey Bunches of Oats,<wbr> Wheaties,<wbr> Special K,<wbr> Froot Loops,<wbr> Apple Jacks

Obsługuje wszystkie moje główne przeglądarki oprócz IE.

ACarter
źródło
12
-1. Dlaczego nie przetestowałeś przed udzieleniem porady? To nie działa. <wbr>ma inny cel. Nie wspominając o tym, że ta odpowiedź jest duplikatem odpowiedzi, która istniała dawno temu.
użytkownik
1
WBR nie ma innego celu. developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr
Lodewijk,
13
<wbr>po prostu ustawia okazję do przerwy; nie „mówi przeglądarce, aby przerwała to wcześniej niż gdziekolwiek indziej”. Używane przed spacją, zwykle jest bezużyteczne, ponieważ spacje są zwykle możliwościami podziału linii.
Jukka K. Korpela
5
To w ogóle nie działa w żadnej przeglądarce. Odpowiedź jest źle: <wbr>nie nie priorytet podział wiersza nad zwykłej spacji. Tak więc w przykładzie zawijanie przebiega normalnie.
adrian
3
Aby wyjaśnić, <wbr> ma na celu zasygnalizowanie „tutaj jest miejsce, w którym możesz złamać”, kiedy w innym przypadku ta pozycja byłaby uznawana za wewnątrz słowa . Mówi „traktuj miejsce między tymi dwoma znakami tak, jakby była tam spacja”, a nie „wolę tu przerwać”. Jeśli jest już spacja, <wbr> nie ma znaczenia.
Średnik
-1

Możesz po prostu dostosować ustawienia marginesów w CSS (w tym przypadku margin-right).

text {
    margin-right: 20%;
}
gooflord
źródło
-3

Użyj <div>zamiast <span>lub określ klasę dla SPAN i nadaj jej atrybut display: block .

justacoder
źródło
-5

Jest to element HTML do tej ™: (obecnie standaryzowane) <wbr>elementem .

Radziłbym ci to wykorzystać. Może nie działać wszędzie , ale to najlepsze, co możesz zrobić bez przechodzenia przez obręcze.

Mathias Bynens
źródło
3
-1: <wbr>służy do zaznaczania punktów przerwania przy bardzo długich słowach, nie rozwiązuje problemu z preferowanymi podziałami wiersza
użytkownik
4
@ user3075942 Bezpośredni cytat ze specyfikacji : „ wbrElement reprezentuje możliwość podziału wiersza.” Właśnie o to prosił OP. Przestań głosować w dół na podstawie tego, co czytasz na wiki.
Mathias Bynens,
3
Tak, okazja . Ale przeglądarki już mają okazję przebić się na spacje. Pytanie brzmi, jak powiedzieć przeglądarce, w których przestrzeniach lepiej jest się rozbijać.
użytkownik
1
… A odpowiedzią jest użycie <wbr>.
Mathias Bynens,
8
Nie, to nie jest odpowiedź. Nie zwiększa to prawdopodobieństwa wykorzystania konkretnej istniejącej wcześniej możliwości progu; dodaje tylko nową możliwość przełamania, gdzie jeszcze nie istnieje. Posiadanie dwóch możliwości z rzędu nie ma sensu. developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr
Torin Finnemann