问题
I'm guessing these two attributes don't actually work together, but my situation:
I'm trying to create a tooltip component. My tooltip is positioned absolutely, and as I don't know what the length of the content would be, has no width. So with width-related css, text just forms a tall, skinny column. I tried max-width
, but on it's own, that does nothing. So I decided to try white-space: nowrap
, and while it nicely doesn't wrap text, it also doesn't seem to honor max-width in a useful way, with text instead going out of the boundaries of the element.
I can't think of how to solve my problem, if there is a clean solution. I'd like to have an absolutely positioned div that expands to fit it's content until a maximum, at which point it wraps. One suggestion I saw was making the element a flexbox, but from what I can tell, that's not great with IE, so I don't think is viable in my situation. Any advice?
.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:
Avoid using white-space:nowrap
as that will constrain your text to one line. max-width
should work with a block level element with display absolute but not inside an inline element. To resolve this, I place the tooltip outside of your wrapper block and use javascript to position it at the mouse location.
Here is a simple solution for your issue. Click on "open tooltip" to display the tooltip and move the slider to change the value of 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:
I'm not exactly sure what your goal is as there are a lot of contradictory things going on. But I'll try and hopefully you can guide me towards your desired solution:
https://jsfiddle.net/q7dyf6xh/
.wrapper {
position: relative;
display: run-in;
}
.info {
position: absolute;
max-width: 200px;
white-space: pre-line;
}
Have a look at this fiddle, as you can see the tooltip now has a max-width. Have a look at what I'm using:
display: run-in;
: Displays an element as either block or inline, depending on context
white-space: pre-line;
: Sequences of whitespace will collapse into a single whitespace. Text will wrap when necessary, and on line breaks
For a better understanding of how things work look here:
white-space: If you use nowrap text will never wrap to the next line. The text continues on the same line until a tag is encountered!
This said your max-width
is still working but with nowrap you overflow your element now. Try and give your element a background-color
and you'll see that it actually is only as wide as your max-width
defines.
See here how it overflows the element: https://jsfiddle.net/fcnh1qeo/
And now width overflow: hidden
only the text inside your box will be displayed. Everything else is cut off! See here: https://jsfiddle.net/0qn4wxkg/
What I used now is display: run-in;
and white-space: pre-line;
as well as max-width: 200px
which will give you hopefully your desired solution. Not knowing the context and code you using it is more of a guess than it is a answer. But maybe I can guide you towards a solution which fits your needs
Cheers!
回答3:
Add a min-width:100%
and 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:
Not that ling ago i had a very similar problem myself. I fixed it using flexbox what is already suggested in the comments here.
My code looks like this:
.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%)
}
I also copied this into this fiddle just in case you want to have a look at it. (:
回答5:
You are correct that this does not work.
Here's a solution that works if you are allowed to use BR tags. I have worked on tooltips many times and this is the best solution that I have.
Codepen: https://codepen.io/btn-ninja/pen/JNJrgp
It works by using white-space nowrap with a 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%); }
The translate allows the absolutely-positioned tooltip to horizontally or vertically center itself vs the content. White space with a BR achieves wrapping for long content while allowing shorter tooltips to match width of the tooltip text.
Here's the full 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"
The element generates a run-in box. Run-in elements act like inlines or blocks, depending on the surrounding elements. That is:
If the run-in box contains a block box, same as block.
If a block box follows the run-in box, the run-in box becomes the first inline box of the block box.
If an inline box follows, the run-in box becomes a block box.
pre-line
Sequences of whitespace are collapsed. Lines are broken at newline characters, at <br>
, and as necessary to fill line boxes.
The following table summarizes the behavior of the various white-space
values:
The max-width
CSS property sets the maximum width of an element. It prevents the used value of the width property from becoming larger than the value specified by 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;
}
来源:https://stackoverflow.com/questions/45949322/trouble-with-nowrap-and-max-width-on-an-absolutely-positioned-element