Dlaczego wielokropek CSS nie działa w komórce tabeli?


150

Rozważmy następujący przykład: ( tutaj pokaz na żywo )

$(function() {
  console.log("width = " + $("td").width());
});
td {
  border: 1px solid black;
  width: 50px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tbody>
    <tr>
      <td>Hello Stack Overflow</td>
    </tr>
  </tbody>
</table>

Wynik to width = 139:, a wielokropek się nie pojawia.

Czego tu brakuje?



W jakiś sposób się powielają, ale odpowiedź nie zapewnia obejścia (jak robi to Arlen Cuss).
Florian Margaine

1
widtha heightkomórki tabeli są zawsze używane jako minimalna szerokość i wysokość. Komórki tabeli są różne!
Pan Lister

1
@FlorianMargaine Właściwie drugie pytanie pozwala obejść ten problem: umieść element div w komórce o żądanej szerokości.
Pan Lister

Jednak nadal wolę odpowiedzi wymienione na tej stronie.
Florian Margaine

Odpowiedzi:


102

Najwyraźniej dodając:

td {
  display: block; /* or inline-block */
}

rozwiązuje również problem.


Innym możliwym rozwiązaniem jest ustawienie table-layout: fixed;do stołu, a także ustawienie go width. Na przykład: http://jsfiddle.net/fd3Zx/5/


4
Dokładnie. Elementy z display: table-cell(domyślnie dla tdelementów) nie akceptują szerokości.
Michael Mior

29
display: block;w pewnym sensie niweczy cel używania stołu. Podoba mi się ta table-layout: fixed;opcja, działała dobrze.
Alex K

7
table-layout:fixedrozdziela szerokość kolumn w mniej inteligentny sposób. Czy istnieje inna opcja, która przypisze szerokość kolumny w ten sam sposób, table-layout: normala mimo to poprawnie wyświetli wielokropek?
gniazdo

To śruby z obramowaniem stołu; użycie max-width nie.
Charlie

84

Ważne jest również, aby umieścić

table-layout:fixed;

Na zawierającą tabelę, więc działa dobrze również w IE9 (jeśli używasz max-width).


7
zapewni to również, że przepełnienie tekstu działa w układach responsywnych
jao

3
Właśnie tego potrzebowałem. Mam stół o szerokości 100%. I wszystkie kolumny z wyjątkiem jednej o stałej szerokości. Dzięki temu ostatnia kolumna może zająć tyle miejsca, ile zostało.
matthew_360

78

Jak powiedziano wcześniej, możesz używać, td { display: block; }ale to przeczy celowi używania stołu.

Możesz użyć, table { table-layout: fixed; }ale może chcesz, aby zachowywał się inaczej dla niektórych kolumn.

Dlatego najlepszym sposobem na osiągnięcie tego, co chcesz, byłoby zawinięcie tekstu w a <div>i zastosowanie CSS do <div>(a nie do <td>) w następujący sposób:

td {
  border: 1px solid black;
}
td > div {
  width: 50px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

2
To najprostsza metoda, jaką widziałem i faktycznie działa w IE8.
Keith Ketterer

2
TO właściwie najlepsze rozwiązanie, jakie widziałem na wielokropkach w tabelach.
członkowie około

41

Spróbuj użyć max-widthzamiastwidth , tabela nadal automatycznie obliczy szerokość.

Działa nawet w ie11(z trybem zgodności IE8).

td.max-width-50 {
  border: 1px solid black;
  max-width: 50px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
<table>
  <tbody>
    <tr>
      <td class="max-width-50">Hello Stack Overflow</td>
    </tr>
    <tr>
      <td>Hello Stack Overflow</td>
    </tr>
    <tr>
      <td>Hello Stack Overflow</td>
    </tr>
  </tbody>
</table>

jsfiddle .


1
Dobrze zauważony. Prawdopodobnie najlepiej jest użyć obu , aby element miał stałą szerokość. W przeciwnym razie może być krótszy, jeśli pozwala na to zawartość.
LSerni

O wiele lepsze niż hack do wyświetlania śruby displayhack z obramowaniem tabeli.
Charlie

21

Strona demonstracyjna

W przypadku tabel z dynamiczną szerokością znalazłem poniższy sposób na uzyskanie zadowalających wyników. Każdy, <th>kto chce mieć możliwość przycinania tekstu, powinien mieć wewnętrzny element zawijający, który otacza zawartość <th>zezwolenia text-overflowna pracę.

Prawdziwą sztuczką jest ustawienie max-width(na <th>) w vwjednostkach .

Skutecznie spowoduje to, że szerokość elementu zostanie „powiązana” z szerokością widocznego obszaru (okna przeglądarki) i spowoduje responsywne przycinanie treści. Ustaw vwjednostki na zadowalającą wymaganą wartość.

Minimalny CSS:

th{ max-width:10vw; }
      
th > .wrap{ 
   text-overflow:ellipsis;
   overflow:hidden;
   white-space:nowrap;
}

Oto gotowe do uruchomienia demo:

table {
  font: 18px Arial;
  width: 40%;
  margin: 1em auto;
  color: #333;
  border: 1px solid rgba(153, 153, 153, 0.4);
}

table td, table th {
  text-align: left;
  padding: 1.2em 20px;
  white-space: nowrap;
  border-left: 1px solid rgba(153, 153, 153, 0.4);
}

table td:first-child, table th:first-child {
  border-left: 0;
}

table th {
  border-bottom: 1px solid rgba(153, 153, 153, 0.4);
  font-weight: 400;
  text-transform: uppercase;
  max-width: 10vw;
}

table th > .wrap {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
<table>
    <thead>
        <tr>
            <th>
                <div class="wrap" title="Some long title">Some long title</div>
            </th>
            <th>
                <div class="wrap">Short</div>
            </th>
            <th>
                <div class="wrap">medium one</div>
            </th>
            <th>
                <div class="wrap" title="endlessly super long title which no developer likes to see">endlessly super long title which no developer likes to see</div>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>-</td>
            <td>-</td>
            <td>-</td>
            <td>very long text here</td>
        </tr>
    </tbody>
</table>


3

Po prostu oferuję alternatywę, ponieważ miałem ten problem i żadna z innych odpowiedzi nie przyniosła pożądanego efektu, którego chciałem. Zamiast tego użyłem listy. Teraz semantycznie informacje, które wyświetlałem, można było traktować zarówno jako dane tabelaryczne, jak i dane wymienione.

W końcu to, co zrobiłem, to:

<ul>
    <li class="group">
        <span class="title">...</span>
        <span class="description">...</span>
        <span class="mp3-player">...</span>
        <span class="download">...</span>
        <span class="shortlist">...</span>
    </li>
    <!-- looped <li> -->
</ul>

Więc zasadniczo uljest table, lijest tri spanjest td.

Następnie w CSS ustawiłem spanelementy na be display:block;i float:left;(wolę tę kombinację, inline-blockponieważ będzie działać w starszych wersjach IE, aby wyczyścić efekt float, patrz: http://css-tricks.com/snippets/css/clear- fix / ) i mieć również elipsy:

span {
    display: block;
    float: left;
    width: 100%;

    // truncate when long
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

Następnie wszystko, co musisz zrobić, to ustawić max-widthszakresy, a to nada liście wygląd tabeli.


czy możesz zastosować ul inside td (np. <td><ul>...</ul></td>)? Wydaje mi się, że to nie działa :(
Sam

2

Zamiast używać wielokropka do rozwiązania problemu przepełnienia tekstu, odkryłem, że wyłączone i stylizowane dane wejściowe wyglądały lepiej i nadal pozwalają użytkownikowi przeglądać i wybierać cały ciąg, jeśli zajdzie taka potrzeba.

<input disabled='disabled' style="border: 0; padding: 0; margin: 0" />

Wygląda jak pole tekstowe, ale można je wyróżniać, dzięki czemu jest bardziej przyjazny dla użytkownika


2
Nie jest przyjazny dla użytkownika, ponieważ przy użyciu technologii wspomagających jest błędnie odczytywany jako dane wejściowe, więc użytkownik myśli, że może coś wprowadzić. Nadużywanie semantyki elementów nie jest w porządku.
Carlo

OMG, to jest takie sprytne! ponieważ jest częścią tabeli, po prostu ustaw wejście jako bez obramowania z przezroczystym tłem. Uwielbiam to rozwiązanie!
Sam

1

Sprawdź box-sizingwłaściwość css swoich tdelementów. Miałem problem z szablonem css, który ustawia go na border-boxwartość. Potrzebujesz zestawu box-sizing: content-box.


0

Zostaw swoje stoły tak, jak są. Po prostu zawiń zawartość wewnątrz TD za pomocą zakresu z zastosowanym obcięciem CSS.

/* CSS */
.truncate {
    width: 50px; /*your fixed width */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block; /* this fixes your issue */
}

<!-- HTML -->
<table>
    <tbody>
        <tr>
            <td>
                <span class="truncate">
                    Table data to be truncated if it's too long.
                </span>
            </td>
        </tr>
    </tbody>
</table>

Próbowałem tego, nie działa na DataTables.net. dowolny pomysł?
Sam

-2

Jeśli nie chcesz ustawiać max-width na td (jak w tej odpowiedzi ), możesz ustawić max-width na div:

function so_hack(){}

function so_hack(){} http://jsfiddle.net/fd3Zx/754/ function so_hack(){}

function so_hack(){}

Uwaga: 100% nie działa, ale 99% załatwia sprawę w FF. Inne nowoczesne przeglądarki nie potrzebują głupich hacków div.

td {
  obramowanie: 1px jednolicie czarne;
    padding-left: 5px;
    padding-right: 5px;
}
td> div {
    max-width: 99%;
    przepełnienie: ukryte;
    przepełnienie tekstu: wielokropek;
    spacja: nowrap;

}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.