jquery background image scroll effect speed issue - javascript
I have purchased a template for my shopify store that scrolls a site wide absolutely positioned background image at a slower speed than what the user scrolls for a neato perspective effect.
I have found the script used in the template that animated the scrolling effect for the background image. It is as follows:
<script type="text/javascript">
(function($) {
if(device.desktop()){
// PARALLAX INIT
$(window).bind('scroll',function(e){
parallaxScroll1();
});
function parallaxScroll1(){
var scrolled = $(window).scrollTop();
$('#wrapper .wrapper_bg').css('top',(0+(scrolled*.75))+'px');
}
// SMOOTHSCROLL 4 WEBKIT
var platform = navigator.platform.toLowerCase();
if (platform.indexOf('win') == 0 || platform.indexOf('linux') == 0) {
if ($.browser.webkit) {
/* jquery.simplr.smoothscroll - https://github.com/simov/simplr-smoothscroll */
;(function(e){"use strict";e.srSmoothscroll=function(t){var n=e.extend({step:85,speed:600,ease:"linear"},t||{});var r=e(window),i=e(document),s=0,o=n.step,u=n.speed,a=r.height(),f=navigator.userAgent.indexOf("AppleWebKit")!==-1?e("body"):e("html"),l=false;e("body").mousewheel(function(e,t){l=true;if(t<0)s=s+a>=i.height()?s:s+=o;else s=s<=0?0:s-=o;f.stop().animate({scrollTop:s},u,n.ease,function(){l=false});return false});r.on("resize",function(e){a=r.height()}).on("scroll",function(e){if(!l)s=r.scrollTop()})}})(jQuery);
/* jquery.mousewheel - https://github.com/jquery/jquery-mousewheel */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})});
$.srSmoothscroll({
step: 55,
speed: 100,
ease: 'swing'
});
}
};
};
})(jQuery);
</script>
The issue that I am having is that the scrolling effect moves to quickly, and by the time the user has reached the bottom of the page they are viewing, the background image has prematurely cut off.
I have been fidling around with the values in this script, trying to slow down the effect, with no success. Any insights?
Thanks! You can view this script in action on our site at:
http://ts8276eb.myshopify.com/
the password is: yandasmusic
That code is way too complicated for me to even consider trying to debug.
So I made a much simpler version.
var wrapper = document.getElementById('wrapper'),
checkbox = document.getElementById('scrolleffect');
function parallax() {
if( checkbox.checked) {
wrapper.style.backgroundPosition = "center " + (this.scrollTop / (this.scrollHeight - window.innerHeight) * 100) + "%";
}
else {
wrapper.style.backgroundPosition = "";
}
}
document.body.onscroll = function() {parallax.call(document.body);};
document.documentElement.onscroll = function() {parallax.call(document.documentElement);};
#wrapper {
background: #333 url('http://cdn.shopify.com/s/files/1/0810/2125/t/21/assets/body_bg_img.png?677044079657970527') no-repeat scroll center top;
color: white;
padding: 8px;
}
.spacer {
height: 800px;
}
body {
margin: 0;
}
<div id="wrapper">
<p>Content!</p>
<p style="position: fixed;"><label><input type="checkbox" id="scrolleffect" /> Toggle background scroll effect</label></p>
<div class="spacer"></div>
<p>More content!</p>
<div class="spacer"></div>
<p>Content ends</p>
</div>
The important part here is that the background position is updated according to how far down the page we've scrolled. It ranges from center 0% to center 100%. The convenient thing about background image positioning is that 0% means "align top of image with top of element", and 100% means "align bottom of image with bottom of element". Values are interpolated in-between, so 25% would be "align the top quarter mark of the image with the top quarter mark of the element".
Much simpler.
The numbers appear to be crunched here:
$('#wrapper .wrapper_bg').css('top',(0+(scrolled*.75))+'px');
So it currently scrolls 25% slower than the page. If you lower this number, it will go more slowly...
$('#wrapper .wrapper_bg').css('top',(0+(scrolled*.25))+'px');
Related
Change image shown in fixed div when another div is in viewport
I have a fixed div containing an image that scrolls with the user from the top of the page. As new content divs enter the viewport I want the image to change. I found a related piece of code that will change the image based on how far a user scrolls in pixels. This works, but only if the viewport is a specific size, else the image changes too early/late: Example I'm trying to modify this so that the change is instead based on when another div comes into view so that it works no matter the screen size (content div heights are set with relative units). I think this can be done if the other divs positions are saved to a variable and then used in place of the pixel values in the above code. However I can't seem to get this right, probably because I've not calculated the other div positions correctly. $("#display1").fadeIn(1000); $(window).scroll(function() { var pos = $(window).scrollTop(); var first = $("#first").offset(); var second = $("#second").offset(); if (pos < first) { hideAll("display1"); $("#display1").fadeIn(1000); } if (pos > first && pos < second) { hideAll("display2"); $("#display2").fadeIn(1000); } etc... }); function hideAll(exceptMe) { $(".displayImg").each(function(i) { if ($(this).attr("id") == exceptMe) return; $(this).fadeOut(); }); }
You should try getBoundingClientRect() JS method, since It gets the position of the elements relative to the viewport. Check this answer: https://stackoverflow.com/a/7557433/4312515
Here is a quick proof of concept of changing a background image based on an element getting into view. There are three divs. When the third div reaches the bottom of the viewport it will change the color of the background. When the third divs scroll out of the view again the background color is reset to its initial color. Normally you should debounce the scroll event to prevent slowing down the UI. For this example I didn't debounce the event so you get a better sense of when the background is changed. const card3 = document.getElementById('card3'), background = document.getElementById('background'); let isCardVisible = false; function checkDivPosition() { const cardTopPosition = card3.getBoundingClientRect().top, viewportHeight = document.documentElement.clientHeight, isInView = cardTopPosition - viewportHeight < 0; if (isInView && !isCardVisible) { background.style.backgroundColor = 'rebeccapurple'; isCardVisible = true; } else if (!isInView && isCardVisible) { background.style.backgroundColor = 'orange'; isCardVisible = false; } } function onWindowScroll(event) { checkDivPosition(); } window.addEventListener('scroll', onWindowScroll); body { margin: 0; } .background { height: 100vh; opacity: .2; position: fixed; transition: background-color .3s ease-out; width: 100vw; } .card { border: 1px solid; height: 100vh; width: 100vw; } .card + .card { margin-top: 5vh; } <div id="background" class="background" style="background-color:orange"></div> <div class="card"> Card 1 </div> <div class="card"> Card 2 </div> <div id="card3" class="card"> Card 3. </div>
Play animation when content get into view
I've been searching on many posts but almost all of them are confusing. I'm working with animate.css into a which is at the middle of my page. For default the animation is played when the page is loaded, but i want that it play when i reach the (when i'm scrolling). Please, don't say about JS Reveal, i'd like to use the animation from animate.css What i was trying: HTML <!-- Others div above --> <div class="row sf-medida" id="sf-medida" onscroll="Animar();"> <!-- Others div below --> JS function Animar() { setTimeout(function(){ document.getElementById("sf-medida").style.visibility = "visible"; $("#titulo-general").addClass("animated fadeInLeft"); $(".sub-titulo").addClass("animated bounceInRight"); $(".titulo-izquierda").addClass("animated swing"); $(".texto-1").addClass("animated fadeIn"); $(".texto-2").addClass("animated fadeIn"); },1000) } But it doesn't work, however, i've tried adding window.addEventListener("scroll", Animar); But what it does is that the animation is played whenever i scroll on the page,
This can be very easily done using little jquery. All you need to do is listen to the scroll event, then check if user have scrolled to the target element. If the user did, then add animation class from your animate.css. Adjust your if condition according to your desires. Check the below code and fiddle https://jsfiddle.net/15z6x5ko/ for reference $(document).ready(function(){ $(document).scroll(function(evt){ var v2 = Math.abs($('.box').position().top - $(window).height()/2); var v1 = $(this).scrollTop(); if( v1 > v2 ){ console.log('in'); $('.box').addClass('animated flip') } }); }); So as per your request, let me try to explain the code line by line $(document).ready(function(){ This is easy to understand. It just waits for browser to load all HTML & CSS first and when everything is loaded, the javascript code inside this function will run. $(document).scroll(function(evt){ This is an event handler, our callback function will run whenever user scrolls on document. Remember change $(document) according whatever the parent is of your target element. So if your target div is inside another div whose class is .parent then use $('.parent').scroll . As for my code I am listening the event on document. When my document scrolls, my event will trigger. var v1 = $(this).scrollTop(); This code will get the amount of scrolling user had done in pixels. var v2 = Math.abs($('.box').position().top - $(window).height()/2); This is a simple math that checks the position of my target div from its parent element subtracting the half of the size of window from it. This will return the pixel positing of your target div. So when user reaches this pixel positing while scrolling, your animation will start. $('.box').addClass('animated flip') Now this code simply adds the animation css classes into the target div as soon as user scrolls to the target div.
I'm using "WoW.js" for my scroll reveal library. It's pretty easy to use, like for real. One line of code <div class="wow fadeIn">content</div> Here, take a look: http://mynameismatthieu.com/WOW/docs.html
Here's an example using Jquery. In it we use .scrollTop and .height to measure the videos container from the top of the page so that we know when it comes into view when scrolling. (it's actually set to load when it reaches 100px below the bottom of the viewable area, a sort of preload. you can adjust it to whatever you like.) The video load is done by copying the url from data-src= into src= when the video container is at the desired spot on the page. (in this case, 100px below the viewable area) fiddle note, the video won't load on stack so be sure to view the fiddle https://jsfiddle.net/Hastig/xszu6b1p/ I scraped it together from these two answers.. Youtube Autoplay Ladyload Images $(window).scroll(function() { $.each($('iframe'), function() { if ( $(this).attr('data-src') && $(this).offset().top < ($(window).scrollTop() + $(window).height() + 100) ) { var source = $(this).data('src'); $(this).attr('src', source); $(this).removeAttr('data-src'); } }) }) body { margin: 0; } .filler { display: flex; justify-content: center; align-items: center; height: 800px; } .filler-top { background-color: blue } .filler-btm { background-color: green; } .video-container { /* css tricks - responsive iframe video */ /* https://css-tricks.com/NetMag/FluidWidthVideo/Article-FluidWidthVideo.php */ position: relative; padding-bottom: 56.25%; /* 16:9 */ padding-top: 25px; height: 0; display: flex; justify-content: center; background-color: red; } .video-container iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="filler filler-top">filler top</div> <div class="video-container"> <iframe data-src="https://www.youtube.com/embed/f0JDs4FY8cQ?rel=0&autoplay=1"></iframe> </div> <div class="filler filler-btm">filler bottom</div>
Javascript: Sticky menu scroll glitch
Hello I have a shopify website and trying to implement a sticky header which changes the image position and location when some one scrolls down from header. For that I have added the following Javascript. window.onscroll = function() {scrollFunction()}; function scrollFunction() { if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) { document.getElementById("siteheader").classList.add("sticky_header"); } else { document.getElementById("siteheader").classList.remove("sticky_header"); } } I am targeting the id of logo image and togelling the sticky_header class <img id="siteheader" class="header__logo-image"> I have added the following css for moving the logo to left hand side and changing its size .sticky_header { float: left; height: 45px; width: auto; margin-bottom: 0; } the above setup is working fine and its the desired requirement but while scrolling to bottom the image size is fighting between the non sticky_header and sticky_header state and Having the glitch of sudden change and not change in header size. And that is happening very fast on the point where .scrollTop > 20 can some one help me to smoothen this process.
Single page webapp screen transitions with maintaining the scroll position
I'm build a single page web application for mobile phones. The application should implement transitions between "screens" (like any other mobile app e.g. Facebook, Twitter) and these transitions should be animated (slide left-right). Each screen has to preserve its scroll position between transitions. One obvious solution that comes in mind is this: Viewport +----------+ |+--------+| +--------+ +--------+ +--------+ || DIV1 || | DIV2 | | DIV3 | | DIV4 | || || | | | | | | || || | | | | | | || || | | | | | | || || | | | | | | |+--------+| +--------+ +--------+ +--------+ +----------+ The different screens are put into containers (DIV1, DIV2, ...) which are styled to fit the screen (position: absolute; width: 100%; height: 100%; top: 0) and have overflow-x: scroll. The containers are positioned next to each other and the transition is as easy as animating their left property. Easy so far. The problem is the following: in this implementation the address bar doesn't disappear in the mobile browser when the user scrolls down. I'm talking about this feature: It's because mobile browsers do this only if the user scrolls the body - not a container in the body. There are several suggestions for solution but they don't work in all targeted platforms (Android Chrome and native browser, iPhone Safari) and are quite hacky. I'd like to preserve the original behavior of the browser as it is. For that reason - apparently - need to leave the scrolling on the body. This means that containers have to be "full-length" (and not overflow-scroll), still positioned next to each other. This is where transitions become difficult if you think about it. My current solution has the following steps when transitioning from DIV1 to DIV2: position top of DIV2 to the current scrollTop of the window animate DIV1's and DIV2's left property so that DIV2 fills the screen move DIV2's top to 0 once the animation has finished so that the user can't scroll back further than the top of this screen Move the window's scrollTop to 0 Hide DIV1 (in case it's longer than DIV2) Transitioning back to DIV1 is similar, in reverse. This actually works quite nice (although it's insanely complex and uses transition event listeners) but unfortunately there's a really ugly flickering effect between step 3 and 4 under iOS Safari because it renders the page right after step 3 without waiting for step 4. I am looking for a framework-independent (vanilla JS) solution.
your approach was quite right. you probably get the flickering due to the scroll change position. the trick is to change the div's to position: fixed when scrolling and, than change them back afterwards. the steps are: save the current scroll vertical position change the div's to position: fixed change the div's scrollTop to 0 - scrollPosition start horizontal transition after the transition: change the window's scroll position with scrollTo() revert position: fixed on the div's so the natural browser behavior works. here is a plain vanilla javascript example (also as fiddle): <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title></title> <style type="text/css"> body { margin: 0; padding: 0; } .container { position: absolute; overflow: hidden; width: 320px; height: 5000px; } .screen { position: absolute; width: 320px; height: 5000px; transition: left 0.5s; } #screen1 { background: linear-gradient(red, yellow); } #screen2 { left: 320px; background: linear-gradient(green, blue); } #button { position: fixed; left: 20px; top: 20px; width: 100px; height: 50px; background-color: white; color: black; } </style> </head> <body> <div class="container"> <div id="screen1" class="screen"></div> <div id="screen2" class="screen"></div> </div> <div id="button">transition</div> <script type="text/javascript"> var screenActive = 1; var screen1 = document.getElementById('screen1'); var screen2 = document.getElementById('screen2'); var screen1ScrollTop = 0; var screen2ScrollTop = 0; function onClick() { console.log('getting the event'); if ( screenActive === 1 ) { // will show screen 2 screen1ScrollTop = document.body.scrollTop; screen1.style.position = 'fixed'; screen2.style.position = 'fixed'; screen1.style.top = (0 - screen1ScrollTop) + 'px'; screen2.style.top = (0 - screen2ScrollTop) + 'px'; screenActive = 2; screen1.style.left = '-320px'; screen2.style.left = '0px'; } else { // will show screen 1 screen2ScrollTop = document.body.scrollTop; screen1.style.position = 'fixed'; screen2.style.position = 'fixed'; screen1.style.top = (0 - screen1ScrollTop) + 'px'; screen2.style.top = (0 - screen2ScrollTop) + 'px'; screenActive = 1; screen1.style.left = '0px'; screen2.style.left = '320px'; } } function onTransitionEnd(event) { if ( screenActive === 1 ) { window.scrollTo(0, screen1ScrollTop); } else { window.scrollTo(0, screen2ScrollTop); } screen1.style.position = 'absolute'; screen1.style.top = '0px'; screen2.style.position = 'absolute'; screen2.style.top = '0px'; } screen1.addEventListener('webkitTransitionEnd', onTransitionEnd); document.getElementById('button').addEventListener('click', onClick); </script> </body> </html> in this example i used the transitionEnd event. have in mind that if you have this event on both animating div's the event will fire twice. solutions to this are: if the timings are identical just use the event on one div (used in the example) use the event an all div's but just do changes respective to the event's div animate a container with all the div's inside. so you will just need one event. if you can not use the transitionEnd event use requestAnimationFrame() and animate manually via js i also use a fixed height container for the transitions in this example. if you have div's with different height's you will have to change the containers height after the transition. ideally before reverting from position: fixed. have in mind that changing a div to position: fixed will show it even if it is in a container with overflow: hidden. in the case of a mobile webapp this will not be an issue because the div's are outside of the screen. on a pc you might have to put another div over the other to hide the one transitioning in.
You can do something like this if you jquery is loaded $(document).ready(function() { if (navigator.userAgent.match(/Android/i)) { window.scrollTo(0,0); // reset in case prev not scrolled var nPageH = $(document).height(); var nViewH = window.outerHeight; if (nViewH > nPageH) { nViewH -= 250; $('BODY').css('height',nViewH + 'px'); } window.scrollTo(0,1); } }); For Iphone you have to do something like mentioned in below link http://matt.might.net/articles/how-to-native-iphone-ipad-apps-in-javascript/ and for safari https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html Hope it helps you somehow!!
Using window.scrollTo(0,1); you can make the navigation bar disappear. It's a hack, but it works.
Why not: <body> <div id=header>Header</div> <div id=content>Scrollable Content</div> <div id=footer>Footer</div> </body> Then the CSS: #header,#footer,#content{ left:0%; right:0%; } #header,#footer{ position:fixed; } #header{ top:0%; height:30px; } #footer{ bottom:0%; height:30px; } #content{ position:absolute; top:30px; height:1000px; /*Whatever you need it to be*/ } The touch screen responds to the <body> tag, not the <div>, so setting position:fixed on #header and #footer allow them to maintain position relative to the window, regardless of scroll position, and then when the user scrolls the content, they scroll the <body> EDIT: I have implemented this as an example: https://www.museri.com/M Visit on your mobile device.
I think I figured it out, it's tricky. In short: in the question I describe my current solution that flickers in iOS. At point 3 you need to add position: fixed to DIV2. That way it's gonna "stick" and you avoid the flickering at point 4. Then you need to delay point 4 a couple of milliseconds (setTimeout, 500ms worked for me but probably could be smaller) and set position: absolute again to DIV2 right after window.scrollTo. I'm not sure that's the reason you need the delay, but without it the screen still flickers. If there's interest I can post a PoC later. As a side note, I found it pretty disappointing that most if the people who answered did not read the question entirely or just completely ignored some criteria (framework-independence, keeping original scroll behavior). Most of them suggested solutions that I already specifically linked in the question as not acceptable. Some of them even reclaim when get downvoted. EDIT: dreamlab answered just a couple of minutes before I posted my solution. Both solutions use position: fixed. His solution is more detailed too. He deserves the bounty.
Scrolling News Ticker Jquery - Issues
Original Source & Example: http://www.htmldrive.net/items/show/397/Vertical-Scrolling-News-Ticker-With-jQuery-jCarouse Hello Again!! Scrolling News Ticker Jquery with some issues: First Issue : Internet Explorer Error Message " Object doesn't support this property or method " Line: 269: Line 269) ticker.mouseenter(function() { // <---Line: 269 //stop current animation ticker.children().stop(); }); Second Issue : The only way of clicking on a news option (to be directed to the link of a page) is through the text title that in the website example is in blue color. I would like for the user to be able to click on the whole section of the option that includes the image aswell. Third Issue : When the news scrolls it looks all in one, is there a way to add a line to separate each section. Forth Issue: Is there a way to pause the automatic scrolling when a user puts the mouse over a section? Is there a way to add more text under the title and category? Here is the script itself with the IE issue highlighted with an arrow on the right hand side below: <script type="text/javascript"> $(function() { //cache the ticker var ticker = $("#ticker"); //wrap dt:dd pairs in divs ticker.children().filter("dt").each(function() { var dt = $(this), container = $("<div>"); dt.next().appendTo(container); dt.prependTo(container); container.appendTo(ticker); }); //hide the scrollbar ticker.css("overflow", "hidden"); //animator function function animator(currentItem) { //work out new anim duration var distance = currentItem.height(); duration = (distance + parseInt(currentItem.css("marginTop"))) / 0.020; //animate the first child of the ticker currentItem.animate({ marginTop: -distance }, duration, "linear", function() { //move current item to the bottom currentItem.appendTo(currentItem.parent()).css("marginTop", 0); //recurse animator(currentItem.parent().children(":first")); }); }; //start the ticker animator(ticker.children(":first")); //set mouseenter ticker.mouseenter(function() { ticker.mouseenter(function() { // <---Line: 269 //stop current animation ticker.children().stop(); }); //set mouseleave ticker.mouseleave(function() { //resume animation animator(ticker.children(":first")); }); }); </script> I would deeply appreciate it!!
to add line to separate each items add border-bottom:1px solid black; to the css. after read your question i would like to show you the javascript method that i used in my site and stops when mouse over. <div id="marqueecontainer" onMouseover="copyspeed=pausespeed" onMouseout="copyspeed=marqueespeed"> <div id="vmarquee" style="position: absolute; width: 98%;"> <!--YOUR SCROLL CONTENT HERE--> <!--YOUR SCROLL CONTENT HERE--> </div> </div><style type="text/css"> #marqueecontainer{ position: relative; width: 200px; /*marquee width */ height: 200px; /*marquee height */ background-color: white; overflow: hidden; border: 3px solid orange; padding: 2px; padding-left: 4px; } </style> <script type="text/javascript"> var delayb4scroll=2000 //Specify initial delay before marquee starts to scroll on page (2000=2 seconds) var marqueespeed=2 //Specify marquee scroll speed (larger is faster 1-10) var pauseit=1 //Pause marquee onMousever (0=no. 1=yes)? var copyspeed=marqueespeed var pausespeed=(pauseit==0)? copyspeed: 0 var actualheight='' function scrollmarquee(){ if (parseInt(cross_marquee.style.top)>(actualheight*(-1)+8)) cross_marquee.style.top=parseInt(cross_marquee.style.top)-copyspeed+"px" else cross_marquee.style.top=parseInt(marqueeheight)+8+"px" } function initializemarquee(){ cross_marquee=document.getElementById("vmarquee") cross_marquee.style.top=0 marqueeheight=document.getElementById("marqueecontainer").offsetHeight actualheight=cross_marquee.offsetHeight //height of marquee content (much of which is hidden from view) if (window.opera || navigator.userAgent.indexOf("Netscape/7")!=-1){ //if Opera or Netscape 7x, add scrollbars to scroll and exit cross_marquee.style.height=marqueeheight+"px" cross_marquee.style.overflow="scroll" return } setTimeout('lefttime=setInterval("scrollmarquee()",30)', delayb4scroll) } if (window.addEventListener) window.addEventListener("load", initializemarquee, false) else if (window.attachEvent) window.attachEvent("onload", initializemarquee) else if (document.getElementById) window.onload=initializemarquee </script> you can view the demo at here