CSS/JQuery powered sideways scrolling text on hover
Asked Answered
T

6

9

I have a twitter feed on a website I run. However, it gets cut off on small screens. I have a bar tall enough for 1 line of text in which I have the latest tweet. I want the tweet to ellipsize or fade out at the end if it is too long. But on hover, I want the text to slide slowly to the left, thus exposing the hidden part.

This effect is used on the iPod classic when you highlight a song that has a title that is wider than the screen. (I hope you understand what I'm going for.)

I'm just curious how I would go about implementing something like this? How can I force the text to stay on one line?

Tier answered 21/1, 2011 at 5:8 Comment(0)
B
7

Here's a fairly simple way to do it. First, set up a div containing your long text:

<div id="container">
Here is the long content, long long content. So long. Too long.
</div>

You can use some css to automatically handle the truncation and ellipsis:

div#container {
    /* among other settings: see fiddle */
    width: 200px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

If you then determine the native, untruncated width of the content, you can use jQuery's .animate() to move that content at a consistent speed -- even if you don't know the length of the text until runtime (as would be the case with a twitter feed). Here's a somewhat mechanical way of getting the measurement:

var true_width = ( function(){
  var $tempobj = $('#container') // starting with truncated text div container
      .clone().contents() // duplicate the text
      .wrap('<div id="content"/>') // wrap it in a container
      .parent().appendTo('body') // add this to the dom
      .css('left','-1000px'); // but put it far off-screen
  var result = $tempobj.width(); // measure it
  $tempobj.remove(); // clean up
  return result;
})();

Finally, some animation:

$('#container').one('mouseenter', function(){ // perhaps trigger once only
  var shift_distance = true_width - $(this).width(); // how far to move
  var time_normalized = parseInt(shift_distance / 100, 10) * 1000; // speed
  $(this).contents().wrap('<div id="content">').parent() // wrap in div
    .animate({
        left: -shift_distance,
        right: 0
    }, time_normalized, 'linear'); // and move the div within its "viewport"
});

Regardless of the length of the text, you'll get a consistent speed of about one second per 100 pixels (adjust as desired). Resetting or rewinding content on mouseleave is left as an exercise. This approach has some naïve bits, but may give you some ideas.

Here's a working example: http://jsfiddle.net/redler/zdvyj/

Bruyn answered 21/1, 2011 at 6:28 Comment(0)
B
13

At last, here's my entry: http://jsfiddle.net/sdleihssirhc/AYYQe/3/

Cool stuff:

  1. Library agnostic
  2. Uses scrollLeft instead of absolute positioning, so it's smoother and faster
  3. Uses text-overflow:ellipsis instead of adding any DOM elements
Binns answered 21/1, 2011 at 6:58 Comment(2)
very neat example! and without jquery!Carbine
@sdleihssirhc: Your demo link is down.Pawn
B
7

Here's a fairly simple way to do it. First, set up a div containing your long text:

<div id="container">
Here is the long content, long long content. So long. Too long.
</div>

You can use some css to automatically handle the truncation and ellipsis:

div#container {
    /* among other settings: see fiddle */
    width: 200px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

If you then determine the native, untruncated width of the content, you can use jQuery's .animate() to move that content at a consistent speed -- even if you don't know the length of the text until runtime (as would be the case with a twitter feed). Here's a somewhat mechanical way of getting the measurement:

var true_width = ( function(){
  var $tempobj = $('#container') // starting with truncated text div container
      .clone().contents() // duplicate the text
      .wrap('<div id="content"/>') // wrap it in a container
      .parent().appendTo('body') // add this to the dom
      .css('left','-1000px'); // but put it far off-screen
  var result = $tempobj.width(); // measure it
  $tempobj.remove(); // clean up
  return result;
})();

Finally, some animation:

$('#container').one('mouseenter', function(){ // perhaps trigger once only
  var shift_distance = true_width - $(this).width(); // how far to move
  var time_normalized = parseInt(shift_distance / 100, 10) * 1000; // speed
  $(this).contents().wrap('<div id="content">').parent() // wrap in div
    .animate({
        left: -shift_distance,
        right: 0
    }, time_normalized, 'linear'); // and move the div within its "viewport"
});

Regardless of the length of the text, you'll get a consistent speed of about one second per 100 pixels (adjust as desired). Resetting or rewinding content on mouseleave is left as an exercise. This approach has some naïve bits, but may give you some ideas.

Here's a working example: http://jsfiddle.net/redler/zdvyj/

Bruyn answered 21/1, 2011 at 6:28 Comment(0)
K
3

My solution on jsfiddle or here at the end, it uses CSS3 Animations. I borrowed ideas from here and here. My idea was to let the container div, i.e. div.s to grow wide enough so that it can contain all the text, thus enabling the use of percentages for the left property in the @keyframes rule, hence the:

.s {
   display: inline-block;
}
.t:hover, .s:hover {
  width: auto;
}

Here is the code:

.t {
    white-space: nowrap;
    position: relative;
    overflow: hidden;   
    text-overflow: ellipsis;
    display: block;
    width: 100%;
}
.s {
  display: inline-block;
  width: 100%;
}
.t:hover, .s:hover {
  width: auto;
}
.s:hover .t { 
  animation: scroll 15s;
}
.f {
  width: 100px;
  background: red;
  overflow: hidden;
}
@keyframes scroll {
    0% {left: 0px;}
    100% {left: -100%;}                   
}
<div class="f">
  <div class="s">
    <div class="t">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id impedit accusamus nulla facilis unde sed ipsum maiores adipisci, eius excepturi saepe perspiciatis sequi optio ipsam odio quibusdam quo libero repudiandae.
    </div>
  </div>
</div>
Kronfeld answered 28/4, 2016 at 5:42 Comment(0)
L
2

There are a few plugins out there that do this (Remy Sharp: http://remysharp.com/demo/marquee.html for example), but if you were building from scratch:

The item being scrolled needs to have "white-space: nowrap;" (to keep it on one line), "position:absolute" (to allow it scroll left and right) and wrapped in a relatively positioned element that has "overflow:hidden" (to make it appear like only the width you want shows).

Using jQuery, you could use .animate() to move the scroll item from left to right on the hover event

Lively answered 21/1, 2011 at 5:57 Comment(0)
L
0

Steffen Rusitschka has written a jQuery script, RUZEE.Ellipsis, for doing this.

Lavernalaverne answered 21/1, 2011 at 5:33 Comment(0)
R
0

You can give a look to jRollingNews
Use the code generator to customize the bars and to preview the result.

Disclaimer: I made it.

Rosinweed answered 20/3, 2012 at 9:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.