Проблема с nowrap и max-width на абсолютно позиционированном элементе
Я предполагаю, что эти два атрибута фактически не работают вместе, но моя ситуация:
Я пытаюсь создать компонент всплывающей подсказки. Моя подсказка позиционируется абсолютно, и, поскольку я не знаю, какая длина содержимого будет, не имеет ширины. Таким образом, с помощью CSS, связанного с шириной, текст просто образует высокий, тощий столбец. Я пробовал max-width
, но сам по себе ничего не делает. Поэтому я решил попробовать white-space: nowrap
, и, хотя он красиво не обертывает текст, он также, по-видимому, не оценивает max-width полезным способом, а текст выходит из границ элемента.
Я не могу придумать, как решить мою проблему, если есть чистое решение. Я хотел бы иметь абсолютно позиционированный div, который расширяется, чтобы соответствовать его содержимому до максимума, после чего он обертывается. Одно из предложений, которое я видел, делало элемент a flexbox, но из того, что я могу сказать, это не очень хорошо с IE, поэтому я не думаю, что он жизнеспособен в моей ситуации. Любые советы?
.wrapper {
position: relative;
display: inline;
}
.info {
position: absolute;
bottom: 1.2em;
left: 0;
}
<div class="wrapper">
<span>[ ? ]</span>
<div class="info">Any long text can go in here to test what goes wrong with wrapping.</div>
</div>
Ответы
Ответ 1
Избегайте использования white-space:nowrap
, поскольку это ограничит ваш текст одной строкой. max-width
должен работать с элементом уровня блока с абсолютным отображением, но не внутри встроенного элемента. Чтобы решить эту проблему, я помещаю всплывающую подсказку за пределы вашего блока-оболочки и использую javascript для размещения ее в месте расположения мыши.
Вот простое решение для вашей проблемы. Нажмите "открыть всплывающую подсказку", чтобы отобразить всплывающую подсказку, и переместите ползунок, чтобы изменить значение max-width
.
showContext = function() {
var e = window.event;
var posX = e.clientX;
var posY = e.clientY;
var info = document.getElementById("info");
info.style.top = posY + "px";
info.style.left = posX + "px";
info.style.display = "block";
}
changeWidth = function(value) {
var info = document.getElementById("info");
info.style.maxWidth = value + "px";
}
.wrapper {
position: relative;
}
.info {
position: absolute;
max-width:300px;
display:none;
border:1px solid black;
background-color:white;
}
.range {
margin:10px 0px 10px 0px;
display:block;
}
<div class="wrapper">
max-width slider
<input id="range" class="range" type="range" min="100" max="600" oninput="changeWidth(this.value)"/>
<input type="button" value="open tooltip" onclick="javascript:showContext();" />
</div>
<div id="info" class="info">Any long text can go in here to test what goes wrong with wrapping.</div>
Ответ 2
Я не совсем уверен, какова ваша цель, так как происходит много противоречивых вещей. Но я постараюсь, надеюсь, вы можете направлять меня к вашему желаемому решению:
https://jsfiddle.net/q7dyf6xh/
.wrapper {
position: relative;
display: run-in;
}
.info {
position: absolute;
max-width: 200px;
white-space: pre-line;
}
Посмотрите на эту скрипку, поскольку вы можете видеть, что всплывающая подсказка теперь имеет максимальную ширину. Посмотрите, что я использую:
display: run-in;
: отображает элемент как блок или встроенный, в зависимости от контекста
white-space: pre-line;
: Последовательности пробелов рушится в одно пробелы. Текст будет обернут при необходимости, а при разрыве строки
Чтобы лучше понять, как выглядят работы:
белое пространство. Если вы используете nowrap, текст никогда не будет перенесен на следующую строку. Текст продолжается в одной строке до тех пор, пока не будет обнаружен тег!
Это говорит о том, что ваш max-width
все еще работает, но теперь nowrap вы переполняете свой элемент. Попробуйте и дайте элементу background-color
, и вы увидите, что он на самом деле такой же широкий, как и ваш max-width
.
См. здесь, как он переполняет элемент: https://jsfiddle.net/fcnh1qeo/
И теперь ширина overflow: hidden
будет отображаться только текст внутри вашего окна. Все остальное отрезано! См. Здесь: https://jsfiddle.net/0qn4wxkg/
То, что я использовал сейчас, это display: run-in;
и white-space: pre-line;
, а также max-width: 200px
, что даст вам, надеюсь, ваше желаемое решение. Не зная, какой контекст и код вы используете, это скорее догадка, чем ответ. Но, может быть, я смогу направить вас к решению, которое соответствует вашим потребностям.
Ура!
Ответ 3
Добавьте min-width:100%
и a white-space: nowrap;
.wrapper {
position: relative;
display: inline;
}
.info {
position: absolute;
min-width: 100%;
white-space: nowrap;
}
<div class="wrapper">
<span>[ ? ]</span>
<div class="info">Any long text can go in here to test what goes wrong with wrapping.</div>
</div>
Ответ 4
Не так давно у меня была очень похожая проблема. Я исправил его с помощью flexbox того, что уже предложено в комментариях здесь.
Мой код выглядит следующим образом:
.has-tooltip {
display: inline-flex; align-items: flex-start
}
.has-tooltip > .tooltip {
padding: 1em;
max-width: 300px;
background: #bdc3c7;
word-wrap: break-word;
transform: translate(-50%,-110%)
}
Я также скопировал это в эту скрипту, если вы хотите взглянуть на нее. (
Ответ 5
Вы правы, что это не работает.
Вот решение, которое работает, если вам разрешено использовать теги BR. Я много раз работал над подсказками, и это лучшее решение, которое у меня есть.
Codepen:
https://codepen.io/btn-ninja/pen/JNJrgp
Он работает, используя white-space nowrap с css translate:
<button type="button" class="btn btn-block hasTooltip">
Tooltip on top
<i class="tip">Most tooltips are short<br>but you can add line breaks.</i>
</button>
<button type="button" class="btn btn-block hasTooltip right">
Tooltip on the right.
<i class="tip">Tooltip on right<br>vertically centered.</i>
</button>
.hasTooltip .tip {
position: absolute;
bottom: 100%; left: 50%;
transform: translateX(-50%); }
.hasTooltip.right .tip {
bottom: auto; left: 100%; top:50%;
transform: translateY(-50%); }
Перевод позволяет абсолютно позиционируемую подсказку горизонтально или вертикально центрировать себя и содержимое. Белое пространство с BR достигает обертывания для длинного содержимого, позволяя более короткие всплывающие подсказки соответствовать ширине текста всплывающей подсказки.
Здесь полный css:
.hasTooltip {
position:relative; }
.hasTooltip .tip {
display:block;
background: #333; color: #fff;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
font-size:inherit;
font-style:normal;
line-height: 1rem;
text-align:center;
padding: 8px 16px;
border-radius:4px;
margin-bottom:5px;
pointer-events: none;
position: absolute;
bottom: 100%; left: 50%; transform: translateX(-50%);
opacity: 0;
transition: opacity .34s ease-in-out;
white-space:nowrap;
z-index:99; }
.hasTooltip .tip:before {
content: "";
display:block; position:absolute; left:0; bottom:-5px;
width:100%; height:5px; }
.hasTooltip .tip:after {
border-left: solid transparent 6px;
border-right: solid transparent 6px;
border-top: solid #333 6px;
bottom: -4px;
content: "";
height: 0;
left: 50%;
margin-left: -6px;
position: absolute;
width: 0; }
.hasTooltip:focus .tip,
.hasTooltip:hover .tip {
opacity: 1;
pointer-events: auto; }
.hasTooltip.right .tip {
bottom: auto; left: 100%; top:50%; transform: translateY(-50%);
margin-bottom:0;
margin-left:5px; }
.hasTooltip.right .tip:before {
left:-5px; bottom:auto; }
.hasTooltip.right .tip:after {
border-left: 0;
border-top: solid transparent 6px;
border-bottom: solid transparent 6px;
border-right: solid #333 6px;
bottom:auto;
left: -4px;
top:50%;
margin-left: 0;
margin-top: -6px; }
Ответ 6
display="runin"
Элемент генерирует окно ввода. Элементы запуска действуют как ряды или блоки, в зависимости от окружающих элементов. То есть:
Если поле запуска содержит блок-блок, то же, что и блок.
Если блок-блок следует за окном запуска, поле ввода становится первым встроенным полем блока.
Если появляется встроенный блок, поле ввода становится блочным блоком.
pre-line
Последовательности пробелов сбрасываются. Строки разбиты на символы новой строки, <br>
и, если необходимо, для заполнения строк.
Следующая таблица суммирует поведение различных значений white-space
:
Свойство CSS max-width
устанавливает максимальную ширину элемента. Это предотвращает, чтобы используемое значение свойства width становилось больше значения, указанного max-width.
.wrapper {
position: relative;
display: run-in;
top: 100px;
}
.info {
position: absolute;
bottom: 1.2em;
left: 0;
max-width: 200px;
white-space: pre-line;
background-color: #ddd;
}