Подтвердить что ты не робот

Класс таблицы для таблиц, которые при слишком широком распределении всех своих ячеек в строки

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

Пример 1:

  • Достаточно горизонтального пространства для всей строки текста:

    введите описание изображения здесь

  • Недостаточно горизонтального пространства для всей строки (но даже если есть место для первых двух элементов, все заканчивается в собственной строке) введите описание изображения здесь

Пример 2: Это то же самое, что и в предыдущем примере, но это показывает, что я хотел бы также использовать его вложенным образом:

  • Достаточно горизонтального пространства для всей строки текста:

    введите описание изображения здесь

  • Просто недостаточно горизонтального пространства для всей строки, поэтому каждая ячейка переходит в свою собственную строку

    введите описание изображения здесь

  • Недостаточно горизонтального пространства для второй ячейки

    введите описание изображения здесь

Я ищу решение, которое использует только HTML и CSS (или просто использует JavaScript очень легко), поскольку мой предполагаемый прецедент - это очень сильно использовать это в автоматически созданных страницах документации HTML.

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

Редактирование Clarfiying

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

4b9b3361

Ответ 1

Как я уже говорил в комментариях, то, что ищет OP, не может быть достигнуто без использования Javascript, поэтому вот что я придумал.

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

При изменении размера, как только каждая таблица будет длиннее ширины окна, она изменит отображение содержимого с table-cell на block, тем самым уложив все дочерние элементы.

Как только ширина окна расширяется, он сравнивается с каждым атрибутом таблицы data-width, и когда он подходит, он расширяется.

edit: Я подумал, что по некоторым причинам он не будет работать в некоторых случаях, но он действительно работает, поэтому я удаляю раздувание!

HTML:

<div class="table">
  <div class="cell">
    Content 1
  </div>
  <div class="cell">
    <div class="table">
      <div class="cell">
        Content 1
      </div>
      <div class="cell">
        Cont
      </div>
      <div class="cell">
        Content 3
      </div>    
    </div>
  </div>
  <div class="cell">
    Content 3Content 3Content 3
  </div>

</div>

CSS

.table {
  display: table;
  border: 1px solid #e4e5e7;
  white-space: nowrap;
}

.cell {
  display: table-cell;
  vertical-align: middle;
  padding: 10px;
  border: 1px solid #e4e5e7;
}

.cell .table {
  margin-bottom: -2px;
}

.table.wrap {
  white-space: normal;
}

.table.wrap > .cell {
  display: block;
}

JavaScript:

$('.table').each(function(i) {
  tw = 0;
  $(this).children('.cell').each(function() {
    tw += $(this).outerWidth(true);
  });
  $(this).attr('data-width', tw);
});

$(window).on('load resize', function() {
  w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  $('.table').each(function(i) {
    if ($(this).width() >= w) {
      $(this).addClass('wrap');
    } else if (w >= $(this).attr('data-width')) {
      $(this).removeClass('wrap');    
    }
  });
}).resize();

И здесь работает fiddle

Ответ 2

Другой вариант с чистым JS

window.addEventListener('load', collapse);
window.addEventListener('resize', collapse);

function collapse() {
  var parents = document.querySelectorAll('.parent');
  var children;
  var width;
  for (var i = 0; i < parents.length; i++) {
    parents[i].classList.remove('collapsed');
    width = 0;
    children = parents[i].children;
    for (var j = 0; j < children.length; j++) {
      width += children[j].offsetWidth;
    }
    if (width > parents[i].offsetWidth) {
      parents[i].classList.add('collapsed');
    }
  }
}
.parent,
.child {
  border: 1px solid gray;
  margin: 5px;
  padding: 5px;
}

.parent {
  display: flex;
  flex-wrap: wrap;
}

.collapsed {
  display: block;
}

.child {
  flex-grow: 1;
}
<div class="parent">
  <div class="child">Some thing one</div>
  <div class="parent child">
    <div class="child">Some inner</div>
    <div class="child">long thing</div>
    <div class="child">two</div>
  </div>
  <div class="child">Thing three</div>
</div>

Ответ 3

Один подход заключается в использовании запросов @media для чередования между

display: block

и

display: inline-block

Рабочий пример:

.long-row {
display: inline-block;
width: 200px;
padding-left: 4px;
font-size: 16px;
line-height: 32px;
border: 1px solid rgb(0, 0, 0);
}

@media only screen and (min-width: 801px) {
    .long-row {
        display: inline-block;
        float: left;
    }
}

@media only screen and (max-width: 800px) {
    .long-row {
        display: block;
        border-top: none;
    }

    div:first-of-type.long-row {
        border-top: 1px solid rgb(0, 0, 0);
    }
}

@media only screen and (max-width: 600px) {
    .long-row {
    }

    .short-row {
        display: block;
        margin-left: -4px;
        padding-left: 4px;
        border-bottom: 1px solid rgb(0, 0, 0);
    }
    
    span:last-of-type.short-row {
        border-bottom: none;
    }
}
<div class="long-row">Some thing one</div>

<div class="long-row">
<span class="short-row">Some inner</span>
<span class="short-row">long thing</span>
<span class="short-row">two</span>
</div>

<div class="long-row">Thing three</div>

Ответ 4

Прежде чем перейти к script, есть пары заметок, которые следует учитывать:

В моем фактическом состоянии, о котором я знаю, это невозможно сделать, используя только CSS. Итак, вопрос в том, как это сделать, используя чистый JavaScript с лучшей производительностью? И я придумал некоторые рекомендации:

  • используя циклы for, поскольку они являются наиболее быстрыми с использованием кеша количества итераций
  • минимизация вызовов функций по возможности

    Избегать:

  • рекурсивные функции

  • []. foreach constructs

  • Доступ DOM по возможности

В дополнение к этому он может быть вложен на любой уровень

Идея:

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

Он делает это каждый раз при загрузке разметки документа и при изменении размера окна.

https://jsfiddle.net/nasdao/qzdtr9ym/

Ура!

Ответ 5

Как я упоминал в своем комментарии, вы можете использовать flexbox, вот демонстрация того, как вы хотели. Надеюсь, это поможет.

.flex-container {
  display: flex;
  align-items: center;
  flex-direction: row;
  flex-wrap: wrap;
  flex-flow: row wrap;
  align-content: flex-end;
}

.flex-item {
  background: gray;
  color: white;
  margin: 2px;
  height: 80px;
  text-align: center;
  font-size: 30px;
  border:3px solid black;
}
<div>
<div class="flex-container">
  <div class="flex-item">Something One</div>
  <div class="flex-container" style="border:2px solid black">
     <div class="flex-item">Something 2</div>
     <div class="flex-item">Something random3</div>
     <div class="flex-item">Some 4</div>
  </div>
  <div class="flex-item">Something Five</div>
</div>

Ответ 6

Вы можете сделать это с помощью дисплея: flex;

Например:

 .horz_cont {
        display: flex;
        align-items: center;
        flex-direction: row;
        flex-wrap: wrap;
        flex-flow: row wrap;
        align-content: flex-end;
        border: 1px solid #000;
        padding: 4px;
    }
    
    .horz_cont .horz_cont {
       border: none;
       padding: 0;
    }
    
    .item {
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 4px;
        padding: 4px;
        height: 50px;
        font-size: 34px;
        font-weight: bold;
        border: 1px solid #000;
    }
<div class="horz_cont">
  <div class="item">Some thing one</div>
  <div class="horz_cont">
     <div class="item">Some inner</div>
     <div class="item">long thing</div>
     <div class="item">two</div>
  </div>
  <div class="horz_cont">
     <div class="item">Thing three</div>
  </div>
</div>

Ответ 7

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

Важно также добавить тег viewport к заголовку html:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

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

Надеюсь, это вам поможет.

Ура!

.flex-container {
  display: flex;
  align-items: center;
  flex-direction: row;
  flex-wrap: wrap;
  flex-flow: row wrap;
  align-content: flex-end;
}
.flex-item, .inner-flex-item {
  background: white;
  color: black;
  padding: 5px;
  margin: 2px;
  height: 100px;
  text-align: center;
  line-height: 100px;
  font-size: 50px;
  border:3px solid black;
}
@media screen and (max-width: 1180px) {
  .flex-item {
    width: 80%;
}
@media screen and (max-width: 640px) {
  .inner-flex-item {
    width: 80%;
}
<div>
  <div class="flex-container">
  <div class="flex-item">Something One</div>
  <div class="flex-container" style="border:2px solid black">
    <div class="inner-flex-item">Some inner</div>
    <div class="inner-flex-item">long thing</div>
    <div class="inner-flex-item">two</div>
  </div>
  <div class="flex-item">Thing three</div>
</div>

Ответ 8

Я не знаю, как это сделать при каждом размере экрана в чистом css. Мне нужно немного javascript (проще с jquery)

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

Хорошо работает с n-вложенными уровнями, и это достаточно легкий javascript. (плюс никаких запросов к мультимедиа, никакого количества элементов на уровне, без циклов с "попыткой подгонки", возможно, самой широкой поддержки браузера...)

$(function() {
 $('div.line:first-child ~ div.line:last-child').each(
  function(){
    if( $(this).position().top != $(this).siblings(":first-child").position().top ){
      $(this).parent().addClass("breaks")
    }
  }
 );
});
div{outline:1px solid red;}

.line{display:inline-block;}
.breaks > .line{display:block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="line">Some thing one</div>
<div class="line">
  <div class="line">Some inner</div>
  <div class="line">longest thing</div>
  <div class="line">two</div>
</div>
<div class="line">this is long Thing three</div>
</div>