Reputation: 734
There are CSS tooltips (codepen is given below). They have min-width
and max-width
. They contain sometimes short phrases, sometimes very long words without breaks. This is what happens if there is white-space: nowrap
=> Short tooltips are rendered perfectly, but long ones, obviously, are not wrapped and are not fully visible:
This is what happens when I add white-space: normal
and word-break: break-word
=> Now short ones and long ones get wrapped long before getting to the max-width
:
What I would like to achieve is: Tooltips don't wrap before getting to the max-width. And start wrapping only if they don't get into the max-width. Like here:
Is it possible to get this behaviour just with CSS (no javascript)?
Here is the codepen: https://codepen.io/anon/pen/bWXobM (Uncomment lines 58-59 to change the behaviour.)
I didn't manage to achieve this with any of the found solutions. If you know how to apply them in this case, please share!
Update: apparently some kind of solution to this problem has just been added to the wg draft: https://github.com/w3c/csswg-drafts/issues/1171. It is still interesting if someone found a workaround for now.
Upvotes: 4
Views: 3380
Reputation: 71
The other answers are too verbose or insufficient. What I added was width:max-content;
which works rather intuitively since its trying to maximise the width, but will stop at the max-width
and then breaks the overflow through either word-break:break-all;
, word-wrap:break-word;
or overflow-wrap:break-word;
Here is the CSS (SCSS) to answer OP, you can test it via the codepen in OP's question, just paste it.
@keyframes show-vert {
to {
transform: translate(-50%, 0);
opacity: .9;
}
}
@keyframes show-diag {
to {
transform: translate(0, 0);
opacity: .9;
}
}
body {
background: #eaeaea;
font-family: Verdana;
}
span {
display: block;
padding: 16px 8px;
border: 1px solid;
}
[data-tooltip] {
position: relative;
z-index: auto !important;
&::before, &::after {
content: '';
display: none;
box-sizing: border-box;
position: absolute;
opacity: 0;
font-size: 14px;
line-height: 1;
user-select: none;
pointer-events: none;
}
&::before {
z-index: 1001;
border: 6px solid transparent;
}
&::after {
content: attr(data-tooltip);
z-index: 1000;
min-width: 50px;
max-width: 280px;
height: auto;
//changes - removed
//width: 100%;
border-radius: 2px;
padding: 8px 16px;
background: hsla(0, 0%, 38%, 1);
box-shadow: 0 1em 2em -.5em rgba(0, 0, 0, 0.35);
color: white;
text-align: center;
//changes - added
word-break: break-all;
width: max-content;
}
&:hover {
&::before, &::after {
display: block;
}
&::after {
//changes - removed
// width: auto;
}
}
}
[data-tooltip] {
&.tooltip-down {
&::before {
top: 100%;
left: 50%;
transform: translate(-50%, .5em);
border-top-width: 0;
border-bottom-color: hsla(0, 0%, 38%, 1);
}
&::after {
left: 50%;
top: calc(100% + 5px);
transform: translate(-50%, .5em);
}
&:hover {
&::before, &::after {
animation: show-vert 500ms linear 1ms forwards;
}
}
}
&.tooltip-down-left {
&::before {
left: 1em;
}
&::after {
left: 0;
}
&::before, &::after {
transform: translate(-1em, -.5em);
}
&:hover{
&::before, &::after {
animation: show-diag 500ms linear 1ms forwards;
}
}
}
}
Upvotes: 2
Reputation: 808
I had a similar problem, and was able to use a wrapping element to style it the way I wanted. I forked a previous answer's codepen and got it to work based on what I am assuming you wanted: https://codepen.io/anon/pen/BONWGG
the key changes were creating a new element for the [data-tooltip]
, giving it column flex, and letting the ::after
element scale as big as it needs to
<span class="tooltip-container">
Tooltip 1 should be on 1 line
<span data-tooltip="Short"></span>
</span>
[data-tooltip] {
position: absolute;
left: 0;
right: 0;
height: 0;
flex-direction: column;
align-items: center;
&::after {
...
flex-shrink: 0;
}
}
.tooltip-container {
...
&:hover {
[data-tooltip] {
display: flex;
...
}
}
}
Upvotes: 2
Reputation: 640
Don't use word-break: break-word
as it is breaking every word to new line, instead use overflow-wrap: break-word;
and white-space: normal
.
Upvotes: 1
Reputation: 84
I made some changed in the css code.I have commented on the lines which i have changed.(eg. //changed).Actually you already made the half solution by using
word-break: break-word;
The only thing i changed is min-width and max-width to achieve the required results.
Here is the updated link
https://codepen.io/anon/pen/ZyGpaL
Upvotes: 0