2

I have a rounded div tooltip of a variable height that contains some scrolling content. On the left of it is an arrow that points to the element that triggered it being shown. The arrow can be located anywhere on the left side and the height of the tooltip container varies. Currently I have the arrow implemented as a css triangle with ::before and ::after pseudo-elements for the background and border.

I'm trying to extend the scrolling content of the tooltip div into the background of the arrow on the left side and am at a loss as to how to do it. I've looked at the css clip property but it only works with rectangles. -webkit-mask-image seems interesting but can't account for the dynamic placement of the arrow and variable height of the tooltip container. Maintaining a border and shadow around everything is important to me too.

I'm looking for a solution that will at very least work in the latest Chrome, Safari, and Firefox. I'm willing to fallback to something else in other browsers that can't support the effect.

Any ideas on how this can be done? I've been thinking about this for a while and really been at a loss.

Below is how I'm trying to make the tooltip look. The content inside scrolls and that scrolling can be seen inside the arrow.

How I'm trying to clip the div element.

Community
  • 1
  • 1
  • I would use an image, this can't be done in CSS and I am not sure if it can be done with JavaScript either. –  Nov 03 '13 at 23:19
  • Good description, but the CSS you used for the element would aid us greatly in recreating it. Care to add it? – Zach Saucier Nov 04 '13 at 02:54
  • Also, how do you want to handle the change in content width? Meaning is the whole content made larger and shifted left? – Zach Saucier Nov 04 '13 at 03:07
  • I’ve also spend some time thinking how I could achieve this but I didn't find any solution, even without your scrolling problem. I suppose it’s simply technically impossible today. – LeBen Dec 22 '13 at 18:34

1 Answers1

0

Here's a possibility, whose success would depend on some JS:

body {
  background: gray;
}

.test {
  background: white;
  position: absolute;
  top: 2em;
  left: 10em;
  width: 20em;
  &:before {
    content: "";
    position: absolute;
    top: 1em;
    left: -4em;
    border-width: 2em;
    border-style: solid;
    border-color: transparent;
    border-right-color: white;
  }
}

.test-inner {
  position: relative;
  margin-left: -1.5em;
}

.padder {
  float: left;
  clear: both;
  &.m-1 {
    width: 2em;
    height: 1em;
  }
  &.m-2 {
    width: 1.1em;
    height: 1em;
  }
  &.m-3 {
    width: 0.2em;
    height: 1.6em;
  }
  &.m-4 {
    width: 1.1em;
    height: 1em;
  }
  &.m-5 {
    width: 2em;
    height: 3em;
  }

}
<div class="test">
  <div class="test-inner">
    <div class="padder m-1"></div>
    <div class="padder m-2"></div>
    <div class="padder m-3"></div>
    <div class="padder m-4"></div>
    <div class="padder m-5"></div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate blanditiis ex consectetur suscipit eos ipsa nulla obcaecati provident repellat minima vel reprehenderit dignissimos sed sapiente voluptas nesciunt quo non molestiae.
  </div>
</div>

<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus pariatur veniam laboriosam sapiente aut aspernatur optio aperiam mollitia explicabo ut vero praesentium excepturi natus voluptatem atque adipisci porro voluptatum libero!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus pariatur veniam laboriosam sapiente aut aspernatur optio aperiam mollitia explicabo ut vero praesentium excepturi natus voluptatem atque adipisci porro voluptatum libero!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus pariatur veniam laboriosam sapiente aut aspernatur optio aperiam mollitia explicabo ut vero praesentium excepturi natus voluptatem atque adipisci porro voluptatum libero!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus pariatur veniam laboriosam sapiente aut aspernatur optio aperiam mollitia explicabo ut vero praesentium excepturi natus voluptatem atque adipisci porro voluptatum libero!</p>

The principle is this: You can add floating divs (or pseudo-elements) of varying heights and widths to fake a text shape (assuming that text is what you want to extend into the triangle).

The Pen I made is just a demo of that principle, not made to fit your specific situation. If you were going to use this method of shaping text, it sounds like you would have to write some JS that would programmatically create the floating divs and assign them widths and heights depending on where the arrow falls for any given bubble.

Kauê Gimenes
  • 1,278
  • 1
  • 13
  • 30
davidtheclark
  • 4,666
  • 6
  • 32
  • 42