Плавающий блок на всю оставшуюся ширину

Довольно часто в верстке приходится создавать такую структуру, при которой в родительском блоке горизонтально размещается несколько блоков, чаще всего плавающих. И обычно требуется, чтобы последний блок занимал всё оставшееся место по ширине. До недавнего времени вполне устраивал следующий способ, при котором у нас известна ширина первого блока:

HTML


<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container clearfix"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"fixed"</span>&gt;</span>Блок с известной шириной<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"stretch"</span>&gt;</span>Блок, заполняющий оставшееся место<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

CSS


<span class="hljs-selector-class">.clearfix</span><span class="hljs-selector-pseudo">:before</span>,
<span class="hljs-selector-class">.clearfix</span><span class="hljs-selector-pseudo">:after</span> {
    <span class="hljs-attribute">content</span>: <span class="hljs-string">" "</span>;
    <span class="hljs-attribute">display</span>: table;
}
<span class="hljs-selector-class">.clearfix</span><span class="hljs-selector-pseudo">:after</span> {
    <span class="hljs-attribute">clear</span>: both;
}

<span class="hljs-selector-class">.container</span> {
    <span class="hljs-attribute">position</span>: relative;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">40px</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#ddd</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#999</span>;
    <span class="hljs-attribute">overflow</span>: hidden;
}

<span class="hljs-selector-class">.fixed</span> {
    <span class="hljs-attribute">float</span>: left;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">200px</span>;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">40px</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#eee</span>;
}

<span class="hljs-selector-class">.stretch</span> {
    <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">210px</span>;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">40px</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#aaa</span>;
    <span class="hljs-attribute">text-overflow</span>: ellipsis;
    <span class="hljs-attribute">overflow</span>: hidden;
}

Пример

Недостатки этого способа лишь:

  • Нужно задать ширину первому блоку, соответственно такой же отступ второму.

Но недавно столкнулся с такими требованиями:

  • Может быть любое количество плавающих блоков;
  • Не все блоки с фиксированной шириной (есть с минимальным или максимальным значением ширины);
  • Ну и как обычно последний блок должен занимать всё оставшееся место по ширине.

Решение было следующим.

HTML


<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container clearfix"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"element"</span>&gt;</span>
        Плавающий блок
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"element"</span>&gt;</span>
        Плавающий блок
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"element"</span>&gt;</span>
        Плавающий блок
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"element"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"stretch-element"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"table-cell"</span>&gt;</span>
                Блок, заполняющий оставшееся место по ширине
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

CSS


<span class="hljs-selector-class">.clearfix</span><span class="hljs-selector-pseudo">:before</span>,
<span class="hljs-selector-class">.clearfix</span><span class="hljs-selector-pseudo">:after</span> {
    <span class="hljs-attribute">content</span>: <span class="hljs-string">" "</span>;
    <span class="hljs-attribute">display</span>: table;
}
<span class="hljs-selector-class">.clearfix</span><span class="hljs-selector-pseudo">:after</span> {
    <span class="hljs-attribute">clear</span>: both;
}

<span class="hljs-selector-class">.container</span> {
    <span class="hljs-attribute">position</span>: relative;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#ddd</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#999</span>;
    <span class="hljs-attribute">overflow</span>: hidden;
}

<span class="hljs-selector-class">.element</span> {
    <span class="hljs-attribute">float</span>: left;
    <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">5px</span>;
    <span class="hljs-attribute">min-width</span>: <span class="hljs-number">50px</span>;
    <span class="hljs-attribute">max-width</span>: <span class="hljs-number">100px</span>;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">40px</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#eee</span>;
}

<span class="hljs-selector-class">.stretch-element</span> {
    <span class="hljs-attribute">position</span>: absolute;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">40px</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#eee</span>;
    <span class="hljs-attribute">overflow</span>: hidden;
}

<span class="hljs-selector-class">.table-cell</span> {
    <span class="hljs-attribute">display</span>: table-cell;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">1%</span>;
}

Пример

Преимущества:

  • Количество блоков перед плавающим, растягивающимся блоком может быть любое;
  • Ширина блоков может быть неизвестной.

Недостатки:

  • Две лишние обёртки.

Share this post:

Recent Posts