Отображение: Flex теряет правый отступ при переполнении?
У меня возникла проблема с flexbox в CSS3.
Когда я устанавливаю элемент flexbox с атрибутом overflow
и задаю значение min-width
для дочерних элементов, правый отступ у родительского элемента исчезает. Это происходит во всех поддерживающих браузерах.
Вот пример данной ошибки. Если вы прокрутите контейнер вправо, вы увидите, что последний дочерний элемент находится вплотную к правому краю контейнера, вместо того чтобы учитывать значение отступа.
.outer {
display: flex;
flex-direction: row;
width: 300px;
height: 80px;
border: 1px #ccc solid;
overflow-x: auto;
padding: 5px;
}
.outer > div {
flex: 1 1 auto;
border: 1px #ccc solid;
text-align: center;
min-width: 50px;
margin: 5px;
}
<div class="outer">
<div>text1</div>
<div>text2</div>
<div>text3</div>
<div>text4</div>
<div>text5</div>
<div>text6</div>
<div>text7</div>
<div>text8</div>
<div>text9</div>
<div>text10</div>
</div>
Кто-нибудь знает, почему это происходит и как это исправить? Я пробовал различные комбинации значений padding
и margin
, но без успеха.
5 ответ(ов)
Вы можете добавить еще один уровень обертки, если хотите использовать как "overflow-x: auto", так и прокручиваемый отступ в конце.
Вот как это может выглядеть:
.scroll {
overflow-x: auto;
width: 300px;
border: 1px #ccc solid;
}
.outer {
display: flex;
flex-direction: row;
box-sizing: border-box;
min-width: 100%;
height: 80px;
padding: 5px;
float: left; /* Чтобы адаптироваться по содержимому и не быть ограниченным доступной шириной. (Предпочтительно использовать префиксы для ключевых слов дискретного размера для "width"). */
}
.outer > div {
flex: 1 1 auto;
border: 1px #ccc solid;
text-align: center;
min-width: 50px;
margin: 5px;
}
И соответствующая разметка:
<div class="scroll">
<div class="outer">
<div>text1</div>
<div>text2</div>
<div>text3</div>
<div>text4</div>
<div>text5</div>
<div>text6</div>
<div>text7</div>
<div>text8</div>
<div>text9</div>
<div>text10</div>
</div>
</div>
Таким образом, с помощью обертки .scroll
вы сможете добавить горизонтальную прокрутку, а также отступы, которые будут видны при прокрутке.
Вы можете создать отступы с помощью псевдоэлементов, как показано в следующем примере:
.outer::before { content: ''; min-width: 5px; }
.outer::after { content: ''; min-width: 5px; }
Основной код для элемента .outer
будет выглядеть следующим образом:
.outer {
display: flex;
flex-direction: row;
width: 300px;
height: 80px;
border: 1px #ccc solid;
overflow-x: auto;
padding: 5px;
}
.outer::after { content: ''; min-width: 5px; }
.outer > div {
flex: 1 1 auto;
border: 1px #ccc solid;
text-align: center;
min-width: 50px;
margin: 5px;
}
Вот HTML-код, который вам нужен:
<div class="outer">
<div>text1</div>
<div>text2</div>
<div>text3</div>
<div>text4</div>
<div>text5</div>
<div>text6</div>
<div>text7</div>
<div>text8</div>
<div>text9</div>
<div>text10</div>
</div>
Таким образом, вы можете использовать псевдоэлементы ::before
и ::after
, чтобы добавить необходимые отступы с обеих сторон контейнера. Это позволяет добиться желаемого эффекта без необходимости добавлять дополнительные элементы в разметку.
Проблема, на которую вы указываете, действительно была исправлена в последних версиях браузеров, так как правый отступ теперь заметен:
.outer {
width: 500px;
display: flex;
padding: 20px;
overflow: auto;
background: #ccc;
}
.inner {
width: 600px;
height: 50px;
flex-shrink: 0;
background: darkblue;
}
<div class="outer">
<div class="inner"></div>
</div>
Тем не менее, проблема по-прежнему существует, когда переполнение применяется к оборачивающему элементу (также обратите внимание, что серый фон не заполняет обертку, когда прокручивается вправо):
.wrapper {
width: 500px;
overflow: auto;
border: 1px solid red;
}
.outer {
display: flex;
padding: 20px;
background: #ccc;
}
.inner {
width: 600px;
height: 50px;
flex-shrink: 0;
background: darkblue;
}
<div class="wrapper">
<div class="outer">
<div class="inner"></div>
</div>
</div>
Но это можно исправить, добавив width: fit-content
к элементу outer
:
.wrapper {
width: 500px;
overflow: auto;
border: 1px solid red;
}
.outer {
width: fit-content;
display: flex;
padding: 20px;
background: #ccc;
}
.inner {
width: 600px;
height: 50px;
flex-shrink: 0;
background: darkblue;
}
<div class="wrapper">
<div class="outer">
<div class="inner"></div>
</div>
</div>
Таким образом, добавление width: fit-content
решает проблему отображения правого отступа в таких случаях.
Обе предложенные Артуром Кэппом и dholbert решения работают. Однако если вы выберете любое значение свойства align-items
(кроме stretch
) в главном флекс-контейнере, это приведет к поломке. У меня ушло некоторое время, но в итоге я нашел решение, которое отлично работает.
Это решение использует псевдоэлементы:
.outer {
display: flex;
flex-direction: row;
width: 300px;
height: 80px;
border: 1px #ccc solid;
overflow-x: auto;
padding: 5px;
align-items: center;
position: relative;
}
.outer > div {
flex: 1 1 auto;
border: 1px #ccc solid;
text-align: center;
min-width: 50px;
margin: 5px;
}
.outer > div:last-child::after {
content: '';
position: absolute;
height: 100%;
width: 10px;
display: inline-block;
margin-left: 10px;
}
<div class="outer">
<div>text1</div>
<div>text2</div>
<div>text3</div>
<div>text4</div>
<div>text5</div>
<div>text6</div>
<div>text7</div>
<div>text8</div>
<div>text9</div>
<div>text10</div>
</div>
Обратите внимание, что в некоторых случаях margin-left: 10px
в псевдоэлементе может не сработать. Вы можете использовать right: -10px
, что также будет работать.
Есть и другой способ:
Вы можете добавить еще один элемент DIV с классом item-flex
- это будет TEXT_11
, а затем установить margin-left
равным padding-right
, который вам нужен.
Пример кода:
<div class="outer">
<div>text1</div>
<div>text2</div>
<div>text3</div>
<div>text4</div>
<div>text5</div>
<div>text6</div>
<div>text7</div>
<div>text8</div>
<div>text9</div>
<div>text10</div>
<div style="margin-left: 5px" class="TEXT_11"> </div>
</div>
Таким образом, вы сможете управлять отступами между элементами, используя этот дополнительный DIV.
Как вертикально выровнять текст внутри flexbox?
Заполнение оставшейся высоты или ширины в flex-контейнере
Как расположить div внизу своего контейнера?
Перенос строки в HTML с использованием '\n'
Как сделать перенос строки с помощью CSS, не используя <br />?