Flaxbeard
Flaxbeard

Reputation: 501

Pseudo-element positioned outside parent line wraps early

I've created a simple tooltip system for my website using a tooltip attribute and an ::after pseudoelement. Unfortunately, because the pseudoelement is positioned outside of its parent, it wants to wrap to the size of the parent element. Is there a way to prevent this without preventing wrapping altogether?

Fiddle: https://jsfiddle.net/v5zhf2nu/1/

CSS:

[tooltip]
{
    position: relative;
    cursor: help;
}

[tooltip]::after
{
    pointer-events: none;
    position: absolute;
    content: attr(tooltip);
    left: 100%;
    top: 50%;

    margin-left: 3px;
    background-color: #111111;
    color: white;
    width: auto;
    padding: 3px;
    border-radius: 3px;
    font-size: 12px;
    font-weight: normal;
    padding-left: 6px;
    padding-right: 6px;
    display: none;
    z-index: 3;
    max-width: 1000px;
}

[tooltip]:hover::after
{
    display: inline-block;
}

HTML:

<span tooltip = "This is some information! Unfortunately, it seems to want to line break very early.">Mouse over me!</span>

Upvotes: 1

Views: 551

Answers (3)

Oriol
Oriol

Reputation: 287980

Don't make the element relatively positioned. This way the containing block of the pseudo-element will be the viewport (or, hopefully, a wide enough element).

[data-tooltip] { position: static; } /* default value */

Don't set the left property of the pseudo-element. auto will compute to the static position, which is the end of the element because it's an ::after pseudo-element.

[data-tooltip]::after { left: auto; } /* default value */

Use some margin instead of top, e.g.

[data-tooltip]::after {
  top: auto; /* default value */
  margin-top: .75em;
}

The width of the pseudo-element won't be limited by the width of the element, only by the viewport (or the nearest positioned ancestor). You can reduce (but not increase) that limit by using max-width:

[data-tooltip]::after { max-width: 1000px; }

[data-tooltip] {
  cursor: help;
}
[data-tooltip]::after {
  pointer-events: none;
  position: absolute;
  content: attr(data-tooltip);
  margin-top: .75em;
  margin-left: 3px;
  background-color: #111111;
  color: white;
  width: auto;
  padding: 3px;
  border-radius: 3px;
  font-size: 12px;
  font-weight: normal;
  padding-left: 6px;
  padding-right: 6px;
  width: auto;
  z-index: 3;
  max-width: 1000px;
}
<span data-tooltip="This is some information! Unfortunately, it seems to want to line break very early.">Mouse over me!</span>
<br /><br /><br />
<span data-tooltip="This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. ">Mouse over me!</span>

Upvotes: 2

Carol McKay
Carol McKay

Reputation: 2424

Replace:

[tooltip]::after
{
    position: absolute;
    left: 100%;
} 

With:

[tooltip]::after
{
    position: relative;
    left: 0;
}

Also, I don't think you need the max-width.

https://jsfiddle.net/v5zhf2nu/2/

Upvotes: 0

Oriol
Oriol

Reputation: 287980

Set right to a small enough value, at least minus the maximum width minus paddings, borders and margins:

right: -1015px;

If you don't want to do the calculations, you can use a tiny value like -100000000000px, but then you will need max-width. If you used the exact value you can remove max-width if you want

max-width: -1000px;

Finally, use one of these:

width: fit-content;
width: max-content;

Note they are not widely supported yet, so you may need vendor prefixes.

[data-tooltip] {
  position: relative;
  cursor: help;
}
[data-tooltip]::after {
  pointer-events: none;
  position: absolute;
  content: attr(data-tooltip);
  left: 100%;
  top: 50%;
  margin-left: 3px;
  background-color: #111111;
  color: white;
  width: auto;
  padding: 3px;
  border-radius: 3px;
  font-size: 12px;
  font-weight: normal;
  padding-left: 6px;
  padding-right: 6px;
  width: auto;
  z-index: 3;
  right: -100000000000px; /* Tiny value */
  max-width: 1000px;
  width: -moz-fit-content;
  width: -webkit-fit-content;
  width: fit-content;
}
<span data-tooltip="This is some information! Unfortunately, it seems to want to line break very early.">Mouse over me!</span>
<br /><br /><br />
<span data-tooltip="This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. This is some information! Unfortunately, it seems to want to line break very early. ">Mouse over me!</span>

Upvotes: 0

Related Questions