Не допускайте переноса текста в таблицу до тех пор, пока не будет достигнута «максимальная ширина»

#html #css

Вопрос:

Я использую Java для создания HTML-файла (обычного текстового файла с расширением .html) с таблицей, а также для ее заполнения во время выполнения. Каждый столбец должен быть шириной не более 300 пикселей (на данный момент), но, кроме этого, текст должен занимать все необходимое пространство: столбец только с коротким текстом, например «123», во всех ячейках должен быть довольно узким, в то время как столбец с 200-символьным текстом должен занимать все 300 пикселей и заключать текст в несколько строк.

Текст передается другим классом Java, который я не контролирую, поэтому я заранее не знаю, какой текст и сколько его будет в таблице. Там может быть 3 столбца или 30, и это нормально, если отображается горизонтальная полоса прокрутки браузера.

В настоящее время у меня возникают проблемы с коротким текстом:

Если он содержит пробелы (например, пробел»»), ширина столбца уменьшается, и текст переносится в следующую строку, как только таблица становится шире доступной ширины экрана и отображается горизонтальная полоса прокрутки. Если ячейка не содержит пробелов, то ее ширина не меняется.

Я знаю об white-space: nowrap; этом, но с таким длинным текстом, который перетекает в следующую ячейку, вместо того, чтобы обертываться в 300 пикселей.

Если я использую , например min-width: 100px , только текст, который превышает 100 пикселей, завернут, но тогда столбцы с небольшим количеством текста также имеют ширину 100 пикселей, даже если они могут занимать меньше места.

Вопрос: Как предотвратить перенос короткого текста, содержащего пробелы, до тех пор, пока он не достигнет отметки столбца max-width (без переполнения/усечения)? Я знаю , что мог бы (вероятно) проверить длину текста в Java и изменить стиль CSS ячейки на тот, который использует white-space: normal или другой white-space: nowrap , как только он превысит определенное количество символов, но меня интересует решение, которое использует только ванильный HTML и CSS (возможно ли это вообще?).

Вы можете изменить ширину правой части экрана в этом jsfiddle, чтобы увидеть проблему.

Вот мой код:

 table {
  border: 1px solid black;
  border-collapse: collapse;
}

table td,
table th {
  border: 1px solid black;
  word-wrap: break-word;
  white-space: normal;
  /* min-width: 100px; */
  max-width: 300px;
} 
 <table>
  <tr>
    <th>Col1</th>
    <th>Col2</th>
    <th>Col3</th>
    <th>Col4</th>
  </tr>
  <tr>
    <td>A</td>
    <td>This is a long text!</td>
    <td>short</td>
    <td>12345678901234567890</td>
  </tr>
  <tr>
    <td>short</td>
    <td>short</td>
    <td>longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong</td>
    <td>11111111111111111111</td>
  </tr>
  <tr>
    <td>This</td>
    <td>is</td>
    <td>text!</td>
    <td>09876543210987654321</td>
  </tr>
</table> 

Комментарии:

1. Я этого не понимаю. Можете ли вы объяснить это, сославшись на свой образец? Много говорят о пробелах, но в образце нет пробелов.

2. @wazz <td>This is a long text!</td> содержит пробелы («пробел»). Протестируйте его с помощью jsfiddle, который я связал, там его легче увидеть: измените размер нижней правой панели, чтобы таблица не помещалась полностью. Это изменяет размер «Col2», поэтому «Это длинный текст!» отображается до 4 строк (ширина столбца = ширина самого длинного слова). Теперь удалите пробелы -> он больше не изменяет размер «Col2». Я не хочу, чтобы он изменялся с пробелами, а вместо этого просто использовал одну строку, если только столбец не должен быть шире 300 пикселей, чтобы вместить весь текст. Только после этого он должен отобразить остальную часть текста в следующей строке.

3. Я говорю о символах пробела (именно такое написание предлагает редактор здесь, в Stackoverflow, википедия описывает его одним словом «пробелы»), таких как пробелы/пробелы ( «» ), вкладки,…

4. Я подумал, что вы, должно быть, говорите о дополнительном пробеле после текста или о чем-то подобном. Пространства .

5. @wazz Я отредактировал вопрос, надеюсь, теперь все ясно. Любой вклад, как все это можно было бы сделать?

Ответ №1:

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

В демонстрационных целях я поместил весь html-код в <div> класс .page с ограниченной шириной и переполнением прокрутки, чтобы эмулировать ограниченное пространство на странице.

Затем я оборачиваю всю таблицу внутри a <div class="container"> , которая имеет ширину 1000 пикселей. Это позволяет таблице изменять размер своих столбцов только в соответствии с их max-width содержанием и содержанием.

Проблема в том, что это создает очень большой свиток для небольшой таблицы, которая на самом деле едва переполняется… Это может быть решено с помощью javascript, хотя (исправьте ширину .container в соответствии с table фактической шириной).

 .page { /* not required: emulates page flow with limited width */
  max-width: 500px;
  height: 90vh;
  overflow-x: scroll;
  background: gainsboro;
  padding: 5px;
}

.container {
  width: 1000px;
}

table {
  border: 1px solid black;
  border-collapse: collapse;
}

table td,
table th {
  border: 1px solid black;
  word-wrap: break-word;
  white-space: normal;
  /* min-width: 100px; */
  max-width: 300px;
} 
 <div class="page"> <!-- not required: emulates page flow with limited width -->
  <div class="container">
    <table>
      <tr>
        <th>Col1</th>
        <th>Col2</th>
        <th>Col3</th>
        <th>Col4</th>
      </tr>
      <tr>
        <td>A</td>
        <td>This is a long text!</td>
        <td>short</td>
        <td>12345678901234567890</td>
      </tr>
      <tr>
        <td>short</td>
        <td>short</td>
        <td>longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong</td>
        <td>11111111111111111111</td>
      </tr>
      <tr>
        <td>This</td>
        <td>is</td>
        <td>text!</td>
        <td>09876543210987654321</td>
      </tr>
    </table>
  </div>
</div> 

Комментарии:

1. Спасибо за ваш ответ! Я протестировал его на JSFiddle (без «страницы»), и столбцы сохраняют свой размер, как и ожидалось. К сожалению, я не могу использовать JS с этим (HTML/CSS только в классе Java), и мне, вероятно, потребуется более 1000 пикселей, чтобы вместить 30 (или более) возможных столбцов — я протестировал его с 5000 пикселей, а область прокрутки действительно большая и, вероятно, будет немного запутанной для всех остальных. :/

2. @Nep, мне жаль, если это не поможет. Это лучшее, что я могу придумать без Джей Си. Возможно, вы могли бы просто использовать оценку конечной ширины таблицы, например, 70% от всех максимальных ширин вместе взятых. В противном случае css grid должен позволить создать ваш макет, но это создаст ряд других проблем, начиная с управления границами ячеек…

3. Я не буду знать ширину, пока не создам таблицу. Набор данных, который я в настоящее время использую для тестирования, содержит почти пустые столбцы (3-значное число), а также столбцы, содержащие 200 слов (максимальная ширина), плюс много промежуточных. В моем случае это просто слишком большая игра в угадайку, с риском получить слишком мало места или длинную полосу прокрутки. В настоящее время я работаю над подходом с несколькими стилями (<40 символов/<300 пикселей/nowrap, <=300/300 пикселей и >300/500 пикселей), и, хотя он работает, он не слишком велик из-за фиксированных значений. Я действительно удивлен, что никто не пытался сделать это раньше.

4. TBH Я пробовал несколько раз раньше и в итоге решил псевдо-проблему с white-space: nowrap помощью или решений, подобных тому, которое я представил здесь, или вообще отказался, так как это не имело большого значения для того, что я делал….

Ответ №2:

Я еще не нашел способа установить ширину (таким образом, чтобы пробелы не мешали этому) автоматически — по крайней мере, без дополнительного контейнера, ширину которого я не могу знать заранее — вот почему я использую Java для назначения одного из 3 стилей css:

 if(text.length()>40) {
    if(text.length()>300) {
        stringBuilder.append("<td class="long2">");
    } else {
        stringBuilder.append("<td class="long1">");
    }
} else {
    stringBuilder.append("<td class="short">");
}
 

Протестируйте стили HTML/CSS (созданные вручную, jsfiddle здесь):

 table {
  border: 1px solid black;
  border-collapse: collapse;
}

table th {
  border: 1px solid black;
  word-wrap: break-word;
  text-align: center;
}

table td {
  border: 1px solid black;
  word-wrap: break-word;
  max-width: 300px;
  white-space: normal;
  vertical-align: top;
  text-align: left;
}

table td.short {
  white-space: nowrap;
}

table td.long1 {
  min-width: 300px;
}

table td.long2 {
  min-width: 500px;
  max-width: 500px;
} 
 <table>
  <tr>
    <th>Col1</th>
    <th>Col2</th>
    <th>Col3</th>
    <th>Col4</th>
    <th>Col5</th>
    <th>Col6</th>
  </tr>
  <tr>
    <td>A</td>
    <td class="short">This is a long text!</td>
    <td class="long1">short</td>
    <td class="long2">This is an even longer text!</td>
    <td>12345678901234567890</td>
    <td>12</td>
  </tr>
  <tr>
    <td>short</td>
    <td class="short">short</td>
    <td class="long1">longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong</td>
    <td class="long2">long long long long long long long long long long long long long long long long long long long long long long long long long long long long long</td>
    <td>11111111111111111111</td>
    <td>345</td>
  </tr>
  <tr>
    <td>This</td>
    <td class="short">is</td>
    <td class="long1">text!</td>
    <td class="long2">Something something something!!!</td>
    <td>09876543210987654321</td>
    <td>0</td>
  </tr>
</table> 

Краткое объяснение:

  • .short : <300 пикселей в ширину и используется no-wrap , потому что в любом случае будет не более одной строки. При шрифте по умолчанию и размере шрифта он может вмещать около 45 обычных символов без перетекания (тестировался только с латинским алфавитом!), Но, конечно, это придется изменить с помощью других настроек/содержимого шрифта.
  • .long1 : Ровно 300 пикселей в ширину. Без этого break-word столбец будет соответствовать ширине самого длинного слова, если текст содержит пробелы.
  • .long2 : Ровно 500 пикселей в ширину. Если бы я также не установил min-width , столбец был бы шириной только с самое длинное слово, если текст содержит пробелы. В принципе: с пробелами min-width задает размер столбца, без max-width -это важный бит.