Как я могу сделать div не больше его содержимого?

2071

У меня есть макет, похожий на:

<div>
    <table>
    </table>
</div>

Я хотел бы, divчтобы только расширился до того, насколько мой tableстановится.

Питер Мортенсен
источник
90
эффект называется «shrinkwrapping», и, как ответили, есть несколько способов сделать это (float, inline, min / max-width), у каждого из которых есть побочные эффекты
annakata

Ответы:

2426

Решение состоит в том, чтобы установить divTo display: inline-block.

user473598
источник
239
@ leif81 Вы можете использовать spanили, divили ulили что-нибудь еще, важная часть для контейнера, минимальная ширина которого вы хотели бы иметь, это свойство CSSdisplay: inline-block
miahelf
10
если кто-то задается вопросом: можно затем отцентрировать родителя таблицы, установив «text-align: center» на его родительском элементе и «text-align: left» на нем (например, <body style = "text-align: center"> < span style = "text-align: left; display: inline-block;"> <таблица> ... </ table> </ span> </ body>)
Бернштейн
12
Это не работает на Chrome для меня с span, но работает с использованием пробела: nowrap;
albanx
57
Пожалуйста, обратите внимание, что после того, как вы установили display: inline-blockсвойство margin: 0 auto;, оно не будет работать должным образом. В этом случае, если родительский контейнер имеет, text-align: center;тогда inline-blockэлемент будет горизонтально центрирован.
Савас Ведова
12
inline-blockне работал для меня, но inline-flexсделал.
mareoraft
331

Вы хотите, чтобы элемент блока имел то, что CSS называет шириной сжатия, чтобы соответствовать, и спецификация не предоставляет благословенный способ получить такую ​​вещь. В CSS2 сжатие по размеру не является целью, но означает, что нужно иметь дело с ситуацией, когда браузер «должен» получить ширину из воздуха. Эти ситуации:

  • поплавок
  • абсолютно позиционированный элемент
  • элемент встроенного блока
  • элемент таблицы

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

Решение не раскрывать эту функцию напрямую может показаться странным, но на то есть веская причина. Это дорого. Сжатие по размеру означает форматирование как минимум дважды: вы не можете начать форматирование элемента, пока не узнаете его ширину, и не можете рассчитать ширину без прохождения всего содержимого. Кроме того, элемент не нуждается в усадке так часто, как может показаться. Зачем вам нужен дополнительный div вокруг вашего стола? Возможно, заголовок таблицы - это все, что вам нужно.

Бути-окса
источник
34
Я бы сказал, inline-blockчто именно для этого и прекрасно решает проблему.
Миахельф
6
я думаю, что они добавляют в css4, и это будетcontent-box, max-content, min-content, available, fit-content, auto
Мухаммед Умер
4
Новое fit-contentключевое слово (не существующее, когда этот ответ был впервые написан, и все еще не полностью поддерживаемое ) позволяет вам явно применять к размеру элемент «подгонка к размеру», устраняя необходимость в любом из предложенных здесь хаков, если вы повезло, что он ориентирован только на браузеры с поддержкой. +1 тем не менее; они остаются полезными на данный момент!
Марк Амери
floatсделал то, что мне нужно было сделать!
Нипунасудха,
228

Я думаю, используя

display: inline-block;

будет работать, однако я не уверен в совместимости браузера.


Другое решение было бы заключить вас divв другое div(если вы хотите сохранить поведение блока):

HTML:

<div>
    <div class="yourdiv">
        content
    </div>
</div>

CSS:

.yourdiv
{
    display: inline;
}
mbillard
источник
23
Чтобы ответить на вопрос совместимости браузера: это не будет работать с IE7 / 8 на элементах DIV. Вы должны использовать элементы SPAN.
Мэтт Брок
@feeela - я всегда ставлю * перед зумом, например *display: inline; *zoom: 1;. Я не тестировал эту конкретную ситуацию, но в прошлом я всегда обнаруживал, что взлом hasLayout требуется только для IE7 или IE8 в режиме IE7 (или IE8 в причудах!).
Робокат
@robocat Да, это действительно обходной путь для inline-blockвключения в IE 7.
feeela
@feela - ваш комментарий для меня не имеет смысла! Я предлагал также поставить * перед зумом, т. е. * zoom: 1;
Робокат
4
Пожалуйста, объясните, почему ваше решение inline-block работает.
HelloWorldNoMore
220

display: inline-block добавляет дополнительный запас к вашему элементу.

Я бы порекомендовал это:

#element {
    display: table; /* IE8+ and all other modern browsers */
}

Бонус: теперь вы также можете легко отцентрировать это новое, #elementпросто добавив margin: 0 auto.

Салман фон Аббас
источник
14
+1 - это лучшее и самое чистое решение для современных браузеров, которое также позволяет центрировать элемент. Условный комментарий с position: absoluteнеобходим для <IE8.
2012 г.
21
Указание display: inline-blockне добавляет полей. Но CSS обрабатывает пробелы, которые будут показаны между встроенными элементами.
feeela
Пожалуйста, объясните, почему ваше решение отображения: таблица работает.
HelloWorldNoMore
2
inline-block делает невозможным позиционирование элемента в его родительском элементе (например, если есть text-align: center, вы не можете заставить его придерживаться слева) display: table is perfect :)
FlorianB
1
Это путь, если у вас естьposition: absolute
m4heshd
90

Вы можете попробовать fit-content(CSS3):

div {
  width: fit-content; 
  /* To adjust the height as well */ 
  height: fit-content;
}
Виталий Федоренко
источник
1
@BartlomiejSkwira Любая замена, работающая в IE или Eclipse? другое решение, как встроенный блок не работает для меня .. \
DAVIDBALAS1
8
Это имеет слишком много смысла, конечно, ему не хватает поддержки.
Сава Б.
86

Что работает для меня это:

display: table;

в div. (Проверено на Firefox и Google Chrome ).

Sony Santos
источник
4
Да, особенно если вам нужно центрировать с полем: auto. В этом случае inline-block не является решением.
Жолт Сатмари
1
Также обратите внимание, что если вы хотите, чтобы внутри этого элемента работали отступы, вы должны установить border-collapse: separate;стиль. Это по умолчанию во многих браузерах, но часто CSS-фреймворки, такие как начальная загрузка, сбрасывают его значение collapse.
Руслан Стельмаченко
Протестировано на MSIE 6 на телефоне с Windows Mobile 6.5, сделанном в 2009 году: оно изящно ухудшается до полноразмерного div (что вряд ли будет проблемой для телефона). Если кто-то использует версию Internet Explorer менее 8 на настольном компьютере, он использует неподдерживаемую операционную систему (IE6 поставлялся с XP, IE7 шел с Vista); Я бы перенаправил их на страницу с указанием перейти на GNU / Linux, если они хотят продолжать безопасное использование Интернета на этой машине.
Сайлас С. Браун
85

Есть два лучших решения

  1. display: inline-block;

    ИЛИ

  2. display: table;

Из этих двух display:table;лучше, потому что display: inline-block;добавляет дополнительный запас.

Для display:inline-block;вы можете использовать метод отрицательной маржи, чтобы исправить дополнительное пространство

Шуво Хабиб
источник
2
Не могли бы вы объяснить, почему display:tableлучше?
Натаниэль Форд
1
Для отображения: inline-block, вы должны использовать метод отрицательного поля, чтобы исправить дополнительный интервал.
Шуво Хабиб
8
@NathanielFord display:tableоставляет элемент в контексте форматирования блока, чтобы вы могли контролировать его положение с полями и т. Д. Как обычно. display:-inline-*с другой стороны, помещает элемент в контекстное форматирование Inline, заставляя браузер создать вокруг него анонимную обертку блока, содержащую строковый блок с унаследованными настройками font / line-height и вставлять блок в этот линейный блок (выравнивание по умолчанию по вертикали). Это включает в себя больше "магии" и, следовательно, потенциальных сюрпризов.
Илья Стрельцын
43

Не зная, в каком контексте это будет выглядеть, но я верю, что свойство стиля CSS floatлибо будет, leftлибо rightбудет иметь этот эффект. С другой стороны, у него будут и другие побочные эффекты, такие как разрешение текста плавать вокруг него.

Пожалуйста, поправьте меня, если я ошибаюсь, я не уверен на 100%, и в настоящее время не могу проверить это сам.

falstro
источник
1
Да, в CSS 2.1. (CSS2.0 сделает float полноразмерным, но на самом деле это делает только IE5 / Mac). Таблицы и числа с плавающей запятой - единственные типы отображения, которые могут сжиматься, чтобы соответствовать их содержимому.
bobince
41

Ответ на ваш вопрос лежит в будущем мой друг ...

а именно «встроенный» идет с последним обновлением CSS3

width: intrinsic;

к сожалению, IE с этим не согласен, поэтому пока не поддерживает

Подробнее об этом: модуль внутреннего и внешнего определения размера CSS уровня 3 и могу ли я использовать? Внутренняя и внешняя калибровка .

Пока вы должны быть довольны <span>или <div>настроены на

display: inline-block;
троянский
источник
12
intrinsicкак значение нестандартно. Это на самом деле width: max-content. См. Страницу MDN об этом или уже связанный проект.
maryisdead
34

CSS2-совместимое решение заключается в использовании:

.my-div
{
    min-width: 100px;
}

Вы также можете плавать ваш div, что сделает его как можно меньше, но вам нужно будет использовать clearfix, если что-то внутри вашего div плавает:

.my-div
{
    float: left;
}
Soviut
источник
3
Должно. Какой тип документа вы используете?
Совут
34
width:1px;
white-space: nowrap;

у меня отлично работает :)

Daft Wullie
источник
Но с другой стороны, мой случай был текст внутри div, а не таблица, как OP.
Руи Маркиз
для пользовательского слайдера jquery это здорово, потому что вам не нужно устанавливать ширину элемента контента
CoffeJunky
26

Хорошо, во многих случаях вам даже не нужно ничего делать, как по умолчанию у div heightи widthкак auto, но если это не ваш случай, применение inline-blockdisplay будет работать для вас ... посмотрите на код, который я создаю для вас, и он сделает что вы ищете:

div {
  display: inline-block;
}
<div>
  <table>
    <tr>
      <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ultrices feugiat massa sed laoreet. Maecenas et magna egestas, facilisis purus quis, vestibulum nibh.</td>
      <td>Nunc auctor aliquam est ac viverra. Sed enim nisi, feugiat sed accumsan eu, convallis eget felis. Pellentesque consequat eu leo nec pharetra. Aenean interdum enim dapibus diam.</td>
      <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ultrices feugiat massa sed laoreet. Maecenas et magna egestas, facilisis purus quis, vestibulum nibh.</td>
    </tr>
  </table>
</div>

Алиреза
источник
22

Это было упомянуто в комментариях и трудно найти в одном из ответов так:

Если вы используете display: flexпо какой-либо причине, вы можете вместо этого использовать:

div {
    display: inline-flex;
}

Это также широко поддерживается в разных браузерах.

youngrrrr
источник
Это то, что мне было нужно, когда я уже используюdisplay: flex;
Денни
19

Вы можете сделать это просто с помощью display: inline;(или white-space: nowrap;).

Я надеюсь, что вы найдете это полезным.

miksiii
источник
18

Вы можете использовать inline-blockкак @ user473598, но остерегайтесь старых браузеров.

/* Your're working with */
display: inline-block;

/* For IE 7 */
zoom: 1;
*display: inline;

/* For Mozilla Firefox < 3.0 */
display:-moz-inline-stack;

Mozilla вообще не поддерживает inline-block, но у них -moz-inline-stackпримерно такая же

Некоторые кросс-браузер вокруг inline-blockатрибута отображения: https://css-tricks.com/snippets/css/cross-browser-inline-block/

Вы можете увидеть некоторые тесты с этим атрибутом в: https://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/

RPichioli
источник
1
О чем ты говоришь? Mozilla Firefox поддерживает inline-blockс 3.0 (2008). Источник: developer.mozilla.org/en-US/docs/Web/CSS/…
Чези Чаз
18

Просто поместите стиль в свой файл CSS

div { 
    width: fit-content; 
}
Хамза
источник
1
Я не думаю, что это кросс-браузерная опция.
Дэвид Ректор
2
В настоящее время не работает в Edge: caniuse.com/#search=fit-content
molsson
Вы можете использовать -moz-fit-contentдля FF, предположительно, префиксы других поставщиков позволят свои собственные ...
Benj
1
Это то же самое, что ответ Виталия Федоренко
mfluehr
18
<table cellpadding="0" cellspacing="0" border="0">
    <tr>
        <td>
            <div id="content_lalala">
                this content inside the div being inside a table, needs no inline properties and the table is the one expanding to the content of this div =)
            </div>
        </td>
    </tr>
</table>

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

Эдвард
источник
2
Это не «правильный» способ, но IE6 / 7/8 часто просто не играют хорошо, когда все становится немного сложнее, поэтому я полностью понимаю, почему вы так поступили. Вы получили мой голос.
Крейго,
Я бы сделал это, но я должен окружить каждое поле ввода, так что это много лишних HTML.
NickSoft
15

Рабочая демо здесь

.floating-box {
    display:-moz-inline-stack;
    display: inline-block;

    width: fit-content; 
    height: fit-content;

    width: 150px;
    height: 75px;
    margin: 10px;
    border: 3px solid #73AD21;  
}
<h2>The Way is using inline-block</h2>

Supporting elements are also added in CSS.

<div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
</div>

Абрар Джахин
источник
13

Мое CSS3-решение flexbox в двух вариантах: одно сверху ведет себя как промежуток, а другое снизу ведет себя как div, занимая всю ширину с помощью оболочки. Их классы "top", "bottom" и "bottomwrapper" соответственно.

body {
    font-family: sans-serif;
}
.top {
    display: -webkit-inline-flex;
    display: inline-flex;
}
.top, .bottom {
    background-color: #3F3;
    border: 2px solid #FA6;
}
/* bottomwrapper will take the rest of the width */
.bottomwrapper {
    display: -webkit-flex;
    display: flex;
}
table {
    border-collapse: collapse;
}
table, th, td {
    width: 280px;
    border: 1px solid #666;
}
th {
    background-color: #282;
    color: #FFF;
}
td {
    color: #444;
}
th, td {
    padding: 0 4px 0 4px;
}
Is this
<div class="top">
	<table>
        <tr>
            <th>OS</th>
            <th>Version</th> 
        </tr>
        <tr>
            <td>OpenBSD</td>
            <td>5.7</td> 
        </tr>
        <tr>
            <td>Windows</td>
            <td>Please upgrade to 10!</td> 
        </tr>
    </table>
</div>
what you are looking for?
<br>
Or may be...
<div class="bottomwrapper">
    <div class="bottom">
    	<table>
            <tr>
                <th>OS</th>
                <th>Version</th> 
            </tr>
            <tr>
                <td>OpenBSD</td>
                <td>5.7</td> 
            </tr>
            <tr>
                <td>Windows</td>
                <td>Please upgrade to 10!</td> 
            </tr>
        </table>
    </div>
</div>
this is what you are looking for.

Ллойд Доминик
источник
слава для display: inline-flex;. Кстати, это работает без префикса для Chrome 62, Firefox 57 и Safari 11
Орасио
12
<div class="parentDiv" style="display:inline-block">
    // HTML elements
</div>

Это сделает ширину родительского div такой же, как наибольшая ширина элемента.

Джаймин Дэйв
источник
Есть ли способ, которым я могу применить это только для вертикального размера, чтобы минимизировать и сохранить горизонтальный большой?
Gobliins
12

Попробуй display: inline-block;. Для того, чтобы он был кросс-браузерным, пожалуйста, используйте приведенный ниже код CSS.

div {
  display: inline-block;
  display:-moz-inline-stack;
  zoom:1;
  *display:inline;
  border-style: solid;
  border-color: #0000ff;
}
<div>
  <table>
    <tr>
      <td>Column1</td>
      <td>Column2</td>
      <td>Column3</td>
    </tr>
  </table>
</div>

Джеймс
источник
11

Вмешавшись в Firebug, я нашел значение свойства, -moz-fit-contentкоторое точно соответствует желаемому OP и может быть использовано следующим образом:

width: -moz-fit-content;

Хотя он работает только в Firefox, я не смог найти аналога для других браузеров, таких как Chrome.

Хамед Момени
источник
По состоянию на январь 2017 года IE (все версии, включая Edge и мобильные телефоны) и Opera Mini не поддерживают fit-content. Firefox поддерживает только ширину. Другие браузеры поддерживают это хорошо.
Гэвин
11

Вы можете попробовать этот код. Следуйте коду в разделе CSS.

div {
  display: inline-block;
  padding: 2vw;
  background-color: green;
}

table {
  width: 70vw;
  background-color: white;
}
<div>
    <table border="colapsed">
      <tr>
        <td>Apple</td>
        <td>Banana</td>
        <td>Strawberry</td>
      </tr>
      <tr>
        <td>Apple</td>
        <td>Banana</td>
        <td>Strawberry</td>
      </tr>
      <tr>
        <td>Apple</td>
        <td>Banana</td>
        <td>Strawberry</td>
      </tr>

    </table>
</div>

Шоурин Баруа
источник
7

Я решил аналогичную проблему (в которой я не хотел использовать, display: inline-blockпотому что элемент был отцентрирован), добавив spanтег внутри divтега и переместив форматирование CSS из внешнего divтега в новый внутренний spanтег. Просто добавьте это как еще одну альтернативную идею, если вам display: inline blockне подходит ответ.

Джессика Браун
источник
7

Мы можем использовать любой из двух способов для divэлемента:

display: table;

или,

display: inline-block; 

Я предпочитаю использовать display: table;, потому что он обрабатывает все лишние пробелы самостоятельно. Пока display: inline-blockнуждается в некоторой дополнительной фиксации пространства.

послушник
источник
6
div{
  width:auto;
  height:auto;
}
AJchandu
источник
Это не будет работать, если div содержит встроенные (или inline-block) элементы, и они имеют разный размер шрифта и высоту строки, чем сам div.
цитируетBro
5

Если у вас есть контейнеры, разбивающие строки, после нескольких часов поисков хорошего решения CSS и не находя ни одного, я теперь вместо этого использую jQuery:

$('button').click(function(){

  $('nav ul').each(function(){
    
    $parent = $(this).parent();
    
    $parent.width( $(this).width() );
    
  });
});
nav {
  display: inline-block;
  text-align: left; /* doesn't do anything, unlike some might guess */
}
ul {
  display: inline;
}

/* needed style */
ul {
  padding: 0;
}
body {
  width: 420px;
}

/* just style */
body {
  background: #ddd;
  margin: 1em auto;
}
button {
  display: block;
}
nav {
  background: #bbb;
  margin: 1rem auto;
  padding: 0.5rem;
}
li {
  display: inline-block;
  width: 40px;
  height: 20px;
  border: solid thin #777;
  margin: 4px;
  background: #999;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button>fix</button>

<nav>
  <ul>
    <li>3</li>
    <li>.</li>
    <li>1</li>
    <li>4</li>
  </ul>
</nav>

<nav>
  <ul>
    <li>3</li>
    <li>.</li>
    <li>1</li>
    <li>4</li>
    <li>1</li>
    <li>5</li>
    <li>9</li>
    <li>2</li>
    <li>6</li>
    <li>5</li>
    <li>3</li>
    <li>5</li>
  </ul>
</nav>

cregox
источник
Это заметно в фрагменте для меня в Chrome; повторное нажатие кнопки исправления приводит к другим результатам, если щелкнуть ее в первый раз.
Марк Эмери
@MarkAmery на моем Mac Я только что попробовал его на Chrome, Safari и Firefox, и все нормально: никаких видимых ошибок, ничего на консоли, непротиворечивое поведение. Может быть, это что-то с Windows ...
Cregox
5

Пересмотрен (работает, если у вас есть несколько детей): вы можете использовать jQuery (посмотрите на ссылку JSFiddle)

var d= $('div');
var w;


d.children().each(function(){
 w = w + $(this).outerWidth();
 d.css('width', w + 'px')
});

Не забудьте включить JQuery ...

Смотрите JSfiddle здесь

Bondsmith
источник
Это нарушается, если у вашего div несколько детей; он просто устанавливает ширину div равной ширине первого потомка.
Марк Амери
@MarkAmery Прежде всего, прежде чем проголосовать за него, внимательно прочитайте вопрос, они попросили одного ребенка. Если вам действительно интересно, как это можно сделать с несколькими детьми, посмотрите пересмотренный ответ.
Бондсмит
4

Я пытался, div.classname{display:table-cell;}и это сработало!

Unloco
источник