#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
-это важный бит.