Чистое решение HTML/CSS для выравнивания 3 элементов, когда 2 имеют динамический размер?

Этот вопрос требует пояснения. Пожалуйста, потерпите меня:

Несколько месяцев назад я создал заголовок из трех частей для раздела на веб-сайте. С левой стороны этого заголовка есть заголовок, содержание которого может меняться. Справа находится логотип, который всегда будет иметь ширину 150 пикселей и высоту 60 пикселей. Между ними множество двойных линий. Что-то вроде этого:

[ЭТО НАЗВАНИЕ] ============================================= [Логотип здесь]

Этот сайт отзывчивый, поэтому общая ширина заголовка является переменной.
Заголовок всегда должен быть на одной строке. Элемент div, содержащий двойные строки, должен изменить размер, чтобы заполнить пространство между заголовком и логотипом.

Первоначально я настроил его так, чтобы строки изменялись с помощью медиа-запросов и calc(); функция. Тем не менее, веб-сайт должен быть полностью совместим с IE 8, поэтому я написал несколько JS, чтобы заставить его работать.

Вот скрипка JS, которая по сути отражает это поведение: http://jsfiddle.net/55u5mpu2/2/

function sizeLines() { 
var logoSize = document.getElementById("the-logo").offsetWidth; 
var titleWidth = document.getElementById("the-h2-Title").offsetWidth; 
var totalWidth = document.getElementById("entire-Header").offsetWidth; 
var offsetWidth = (logoSize + titleWidth); 
var linesWidth = (totalWidth - offsetWidth - 20) + "px"; 
document.querySelector("#the-lines").style.width = linesWidth;   }

window.onresize = sizeLines; 
#entire-Header{
  position: relative;
  width: 100%;
  height:40px;
}

#the-h2-Title {
  position: relative;
  float: left;
  width: auto;
    padding-right: 10px;
}

#the-lines {
  border-top: 4px solid #000000 !important;
  border-bottom: 4px solid #000000 !important;
  height: 1px;
  float: left;
  margin-top: 23px;
  min-width: 40px;
}

#the-logo {
  position: relative;
  max-width: 160px;
  max-height: 50px;
  float: right;
  width: auto;
  height: auto;
  top: 0;
}
<div id="entire-Header">
   <h2 id="the-h2-Title">
      <div id="headlineTextbox">This is a Test Headline</div>
   </h2>
   <div id="the-lines"> &nbsp;</div>
   <img id="the-logo" src="http://placehold.it/150x60">
</div>

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

Здесь есть связанные вопросы, но ни один из них не подходит. Я не могу указать ширину ни заголовка, ни строк, потому что они оба динамические.

Кажется, что таблицы работают нормально, но если я добавлю width: auto; на двух из tds вещи терпят неудачу.

Вот пример хорошего макета таблицы, который я создал: http://jsfiddle.net/d40a429s/1/

table {width: 100%;}
#test-title {width:20%;}
#lines-here {width:auto;}
#lines-here > div {border-top:4px solid #2a2a2a; border-bottom:4px solid #2a2a2a;height: 1px;}
#test-logo {width: 160px; padding-left: 10px;}
<div id="test-Section-Header">
   <table>
      <tbody>
         <tr>
             <td id="test-title"><h2>Test Title</h2></td>
            <td id="lines-here">
               <div></div>
            </td>
            <td id="test-logo">
               <img src="http://placehold.it/150x60" alt="150 x 60 placeholder logo image">
            </td>
         </tr>
      </tbody>
   </table>
</div>

Я пытался поставить позицию: абсолют; и верхний / левый или верхний / правый на логотипе и заголовке, но я не могу заставить этот средний div правильно изменить размер.

Итак: если кто-то сделал это здесь: есть идеи о том, как я могу заставить это работать без JS? Или, может быть, способ привести в порядок мой JS, чтобы он работал быстрее?

Спасибо!

3 ответа

Ваша проблема может быть полностью решена с использованием HTML и CSS, слегка изменив их, без необходимости использования JavaScript.

Вот моя вилка скрипки Данилда - Поддерживает IE8+

Объяснение:

  • перемещение #the-logo быть первым элементом в #entire-Header Контейнер позволяет нам плавать #the-logo правильно, без обтекания и опускания ниже заголовка, потому что он имеет "более высокий приоритет" при расчете макета.

  • Добавление "clearfix" к #entire-Header позволяет нам не беспокоиться о заголовке, переполняющем пространство, выделенное какими-либо фиксированными измерениями. Это освобождает нас, чтобы удалить height ограничение в целом. #entire-Header является элементом уровня блока (div), что означает, что по умолчанию его ширина будет равна 100%, и его не нужно явно устанавливать (если только он не был переопределен ранее).

  • #the-h2-Title это второй элемент внутри #entire-Header и плавает влево. Быть блок-элементом (h2), обернем ниже #the-logo в целом, прежде чем обернуть слова в себя.

  • Теперь, когда у нас есть логотип и название, расположенное по обе стороны, мы можем стилизовать #the-lines, Будучи элементом уровня блока, он будет расширяться по горизонтали в доступное пространство, которое в этом случае составляет 100%. Чтобы предотвратить его расширение под заголовком и логотипом, мы добавляем overflow: hidden или же overflow: auto в #the-lines, Это создает новый контекст форматирования блока, который делает #the-linesШирина сужается до оставшегося доступного пространства, которое рассчитывается между двумя плавающими элементами.

    Предостережение: это будет работать только до тех пор, пока высота #the-line меньше, чем у #the-logo, иначе #the-line заверну ниже #the-logo, Это потому, что это третий элемент, и на его расположение влияют первые два элемента.

CSS:

#entire-Header {
    margin: 1em 0 .5em;
}
/* http://nicolasgallagher.com/micro-clearfix-hack/ */
#entire-Header:before,
#entire-Header:after {
    content: " ";
    display: table;
}
#entire-Header:after {
    clear: both;
} 
#the-h2-Title {
    margin: .5em 0;
    float: left;
    margin-right: 10px;
}
#the-lines {
    border-top: 4px solid #000000 !important;
    border-bottom: 4px solid #000000 !important;
    height: 1px;
    /* http://www.stubbornella.org/content/2009/07/23/overflow-a-secret-benefit/ */
    overflow: hidden;
    margin-top: 23px;
}
#the-logo {
    width: 160px;
    height: 50px;
    margin-left: 10px;
    float: right;
}

Разметка:

<div id="entire-Header">
    <img id="the-logo" src="http://placehold.it/150x60" />
     <h2 id="the-h2-Title">
      <div id="headlineTextbox">This is a Test Headline</div>
   </h2>

    <div id="the-lines"></div>
</div>

Это, безусловно, можно сделать с поддержкой IE8

1) Переместите фиксированную ширину + плавающее правое изображение, чтобы быть первым дочерним

2) Хранить float:left в заголовке

3) Установить overflow:hidden (или авто) в строках (чтобы установить новый контекст форматирования блока)

4) Установить display:inline-block на контейнере (чтобы содержать поплавки)

Обновлена ​​FIDDLE ( измените размер браузера, чтобы увидеть эффект)

#entire-Header {
  display: inline-block;
  width: 100%;
  height: 40px;
}
#the-h2-Title {
  float: left;
  padding-right: 10px;
}
#the-lines {
  border-top: 4px solid #000000 !important;
  border-bottom: 4px solid #000000 !important;
  height: 1px;
  overflow: hidden;
  margin-top: 23px;
}
#the-logo {
  width: 160px;
  height: 50px;
  padding-left: 10px;
  float: right;
}
<div id="entire-Header">
  <img id="the-logo" src="http://placehold.it/150x60" />
  <h2 id="the-h2-Title">
      <div id="headlineTextbox">This is a Test Headline</div>
   </h2>
  <div id="the-lines"></div>

</div>

С поддержкой IE8

Если вы хотите сохранить поддержку IE8, вы можете исправить медленную загрузку, включив <script> тег в HTML.

      ...
    </div>
  </div>

  <script>
    // JavaScript here
  </script>
</body>

Без поддержки IE8 (IE10+)

Если вы хотите чисто CSS-решение, используйте flexbox. Сделайте заголовок флексбоксом, назначьте порядок заголовку, строке и логотипу и дайте линии сжиматься и увеличиваться при необходимости.

<!-- HTML -->
<div class="container">
  <div class="title">
    Title
  </div>
  <div class="line">
    Line
  </div>
  <div class="logo">
    Logo
  </div>
</div>

/* CSS */
.container {
  display: flex;
  width: 100%;
}
.line {
  order: 1;
  flex-shrink: 10000000;
  flex-grow: 10000000;
}
.title {
  order: 0;
  flex-shrink: 1;
}
.logo {
  order: 2;
  flex-shrink: 1;
}

Для получения дополнительной информации о flexbox см. Эту статью и эту полезную площадку flexbox.

Другие вопросы по тегам