Firefox adds undesired thin line above a logo animated using JavaScript - javascript

Well it seems that I'm having some sort of a problem with Firefox, I've added a logo to my website and styled it through this CSS block:
#splash div.logo > a {
background-image: url("../../---.png");
background-size: 280px;
height: 85px;
width: 280px;
}
When I open the web page with Chrome or any other browser other than Firefox it displays it in the right way,unless I zoomed in it will show a thin line,
while opening the web page from Firefox will show a thin line above the image with or without zooming in.
The Logo is animated through this code:
IndexPage: {
Splash: {
init: function() {
var $splash = $('#splash'),
$logo = $splash.find('#logo'),
frame = 1,
frameCount = 46
framesPerSecond = 50;
function animateLogo() {
var lastTime = 0;
var currTime = new Date().getTime();
// var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var timeToCall = 25;
if (typeof requestAnimationFrame == "undefined")
requestAnimationFrame = function (callback, element) {
return setTimeout(function () { callback(currTime + timeToCall); }, timeToCall);
};
if (frame <= frameCount) {
setTimeout(function() {
requestAnimationFrame(animateLogo, $logo);
$logo.css('background-position', '0 -' + (frame * 85) + 'px');
frame += 1;
}, timeToCall);
// lastTime = currTime + timeToCall;
}
}
$('form.search').on({
close: function() { $splash.removeClass('searching'); },
open: function() { $splash.addClass('searching'); }
});
if ($window.width() >= 532) {
$window.scroll(function() {
var top = $window.scrollTop();
$splash.find('div.logo').css('opacity', top > 150 ? 0 : (150 - top) / 150);
});
}
$window.resize(function() {
if ($splash.width() < 768) {
$logo.css('background-position', '0 0');
} else {
$logo.css('background-position', '0 -3910px');
}
});
if ($window.width() >= 768)
animateLogo();
}
}
}
Any Ideas?

It looks like Firefox does some extrapolation of your image before rendering it (for perf I guess). It calculate the pixel to display using the neighbourhood of the one on your image, and some pixels on the top of your image are near black pixel resulting in a black/grey line.
EDIT: You can disable this behavior using image-rendering: optimizequality; in your CSS.
Snippet to test this:
var frame = 1,
frameCount = 46;
function animateLogo() {
$logo=$('.logo');
var lastTime = 0;
var currTime = new Date().getTime();
var timeToCall = 25;
if (typeof requestAnimationFrame == "undefined") {
requestAnimationFrame = function (callback, element) {
return setTimeout(function () {
callback(currTime + timeToCall);
}, timeToCall);
}
}
if (frame <= frameCount) {
setTimeout(function() {
requestAnimationFrame(animateLogo, $logo);
$logo.css('background-position', '0 -' + (frame * 85) + 'px');
frame += 1;
}, timeToCall);
}
}
.logo {
background-image: url('data:image/png;base64,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CAgICAgICAgICAgICAgICAgICAgICAgICAgIiDiIN841BAQEBAQEBMQrZlq6yX0TdyAgICAgICAqQbQFD4OAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIJoICAgICAgnLEhIMaF+BcEBASEQywEBAQEBAQEBAQEBATEDhANBAQEBAQEBATEuBCW4hAQEBAQEBCBEMfHv9aPiD0QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBCvQbx9OggICAgICAiI0ine3pPASycICAgICAiIOhCXZQssCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiASIn5SAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiKCD4QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEPEQPzQ9BAQEBAQEBETRzEo39izwyulLKeI8MEIJJZRQQgklRlDiquBRk+glChFKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEs0kQ4mJEkFKvHd0cnRSQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgklmupnlgGhhBJKKKHEjku8y1DinRJKODo5TyihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoosVHiR6ePUCIBQgkllFBCCSWSl3hXvKnzuCsnCAgICAgIiEoQFwUP+wwBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAZEN8eH4uKkeEXsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiI7YwLQQEBAQEBATEd+Zz6WZ2gZdOP2dAKKGEEkooocQYSpQtsIKXKHjUeyWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEKJUZeYZygxz1DipKDE6enfYpdom9rn5wwIJZRQQgkllBhDiZMMJU4ylJhnKDHPUKLJUKJRQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZSIU2Ir0x24RP0IJZRQQgkllMhe4mvpRraBl04QEBAQEBAQdSD6gkcdQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQGRAXGdAlGxefMRlBsR1BkTB9kFAQCREBB8ICAgICIgRIK4hgiCuICC2h+ghICAgHGIhsiOsYl0UQUBAQEBAQEBAHAgxT4C4ahIgXvrBhn+uBXGSAPHis6kWRJ8e0UBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBUhtjazCEgICAgICAgnp1p6QZGXmBBQEBAQEBAVIJoCx4GAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQExRkQDAbFfROyBgIB408kOAgICAgICAgICAgLClR0EBAQEBAQEBIS74hAQEBAQEBAQEBAQEBAQe0L8kgHReTpBQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA7BmxxTmDgICAgICAgHhmZqWbF/k7kEBAQEBAQEBUgih41AQCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmLEiOADAQEBAQEBAbE/xKcMiBYCAgICAgICAmJciLnrCQgICAgICAgICAgICAgICAgIiLyIHgICAgICAgICYlwIS3EICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiF0gtjpXGRDXSiihhBJKKKHE9qd4404CL50gICAgICAg6kBcFjxqCgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBARER8eH4uKkeEXwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIJIitj7nEBAQEBAQEBAbMy3dsIvAK6dixGUGhBJKKKGEEkpUXGJe/X2dG8RJEUIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEKJvZU4Pv61/hKxp7BEeIQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihxIEQO5geAgICAgICAuLRfCndrLPASycICAgICAiIOhBXBY/6CAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQGRBfH+9PSkekTwgYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBIixggILaHuLZjQ0BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBwasaNpISAgICAgICDW5mPpJvWBV05HpYjIq0QllFBCCSWUGEOJkjXOl+glyhBKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSoUv85b//qb9E7DnKgFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQImWJJkOJRgkllFBCCSWUUEIJJZRQQgkllFBiWaLNUKJVQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBiBCV2Nt0eS9SPUEIJJZRQQonsJb6WblDkBRYEBAQEBAREHYi+/ptTEBAQEBAQEBAQEBAQELUPBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBMS+EFdKKKEEBAQEBAQEBAQEBAQEhGvsaIgBAgICAgLiJUSrBAQEBASEy1MICAgICAgICAgICAgI19gQEBAQENUifP0EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAREBYhdTg8BAQEBAQEBcTuT4s0JvHKCgICAgICAqATRFTxsBgEBAQGxK0TsgYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgFhD9BAQ9gkICAgIiP0gLpSAgICAgICAgICAgICAODyihYCAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgvBiPAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBATEC4gdTwsBAQEBAQEBcTPT0k2J/FPKICAgICAgICpBtE3tAwEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQHxOsTO5woCAgICAgICoinaiC740gkCAgICAgKiDsRl9TdsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBeh9jLzCEgICAgICBGjph8/9134VdOEBAQEBAQEJUgzqq/YXODOM+AUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEKJEZbwdIqC6DIg+gyI6wyIAQICIt/RCQICIiEixQLQlZ0SSiihhBJKKKGEEkocBNFCQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQGwgOggICAgICAgIiHEhzjMgfIayEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJLxJ7mIgPiUgkllFBCCSWUeOt8+c57bmtYOkFAQEBAQEDUgbiq/oYNBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBER4RA8BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAbFnhFeKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIL6D2N9cQ0BAQEBAQIwX8e7Fd9rWsXKCgICAgICAqATRVX/D5gZxkQGhhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkoooYQSSiihhBJKKKGEEkrsC7HX6SAgICAgICBGijh6/t211SydICAgICAgICpB1LOxEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEPERRxkQ//R0goCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuEOcQ0BAODpBQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDkRex7ICAgICAgIEaJ2N9Ha4cDAQEBAQEBUQeir/6GDQQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBMQhEYMSEBAQEBDZER0EBAQEBAQEBAQExCEQLQQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAREToRPUIGAgICAgICAgKgV8VPdiB4CYtuIBgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLJTyrf/7QQEBAQEBAQo0NMnnwfla2cICAgICAgICpB1P9tACEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgqkDMlYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgzjI9BAQEBAQEBAjQ0w333x9SycICAgICAiIShAn1d+xgYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNgCooWAgMiHOMuAOM+A6CAgIB4gLiAgICBc2UFAQEBAQEBAQEBsBdG6ngiC6JUIgji3Y0M4T0BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEC8GnGoaSEgICAgICDGhHj0duv8Hm4QEBAQEBAQdSDq/0arN4jLDAgllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgkllFBCCSWUUEIJJZRQQgklnkZcZ0AMEBAQzhNKKKGEEkoooYQSSiihhBKpSvQQEBD5EM4TSiihhBJKKKGEEkoooYQSSiihRC6E+04Q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ICAgICAgICAgICAgICAgICB2gggzHQQEBAQEBERyhAUgBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQExE4QYaaDgICAgICASI6wAISAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDYCSLMdBAQEBAQEBDJERaAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDtBhJkOAgICAgICIjnCAhACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiJ4gw00FAQEBAQEAkR1gAQkBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQOwEEWY6CAgICAgIiOQIC0AICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiInSDCTAcBAQEBAQGRHGEBCAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAbETRJjpICAgICAgIDIjpsPQVr92goCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4n6F//JgWAuJViMX39ekzIG43v3bE4g/VI7oMiAHi8Iib/82ePH9Xhmie/O5ptSFmGRDTx/tDjYgJRBjE8AJideyaPvW4KIjFL99qzG7/elFmunYqaZf/KpLiOcT09jC1+OUOMV1b565+Gxlxt3MsgtwhZssz+vK7goZH3J/87veJyWqZO60WMV0tc2e1IBZPpNsn1S1isa4a7oCLXT8+4m6X7u4Rw+1fDPeH2lno88QCMbn9aK8j7h92u9NPQp+x1xHtErF2uJoEOrq+jLh9Yg3NCtEtfz+J9tMenlrF3n/M7z7k07WTxbe9JDpisRO8hJhUgBhWiJuP+XT1FFoeUStA3F5j3x18hn62fAqtEM0CEXfHvl9WrK3ymk1EXwGieQ7R3yOaaK9pvHAHcLZcbU/X8twh+tCIdoWYLu/f3CKW06/xYiLW74pPVtdxm4hQihden3geMfmhn1Gw+1XsQ0TzNKIZYl9jF5W4vUDqakA82rEf7ASz0DcKmgeH2GcRC0UliP5ZxDOvAoRDPDxjbzx7qkDcrJCGtQXgxrNnVgPiZh3+1Cp27V92VSCeuJ5YzaQGxKMru41nTxWIm7944vK0NkT/4G7Hxi5QA+LxfaeNV/NqQDy+jXm/HGzvbv3VcHSarZ5Dy9uYt8fbG0RXy3li4674cPcsaxf/1XHG3nh9YrEeXCzPF/+bVrAA3Hy5a3p/FT4Zgr/IskJ0jxCTx4j41xNPvHp6/yLX5Ad/EODeEE+8jj1d3Ziq5Bp7+cdvvy5XHLMHr2NHvNtRMqv9INZP1fYJ7xAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBABEWGmhYCAgICAgEiG+D/PDx7oyy0cAgAAAABJRU5ErkJggg==');
background-size: 280px;
height: 85px;
width: 280px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="logo"></div>
<button onclick="frame=0;$('.logo').css('image-rendering','auto');animateLogo()">Without CSS property (default)</button>
<button onclick="frame=0;$('.logo').css('image-rendering','optimizeQuality');animateLogo()">With CSS property</button>
Old answer:
You can separate sprites on your image by a few transparent pixels (or of the color of what is behind your logo) so the effect would not be visible anymore.

Well, if all else fails, you could always attempt to place a div over the thin line. Also try adding a border attribute to your code and set it to 0px solid whatever your background-color is. If all of these don't work, then try adding another border over the red line.

Try loading the image as is in the browser and check if the line is still placed. Also, in Firefox, right-click, choose inspect and see where it points to. For example, the line might be coming from div or some other html element.

i think creating an empty 'content' and using a background to show the image: works nicely in Chrome, Firefox, Safari and IE8+9
.googlePic:before {
content: '';
background: url('../../img/googlePlusIcon.PNG');
margin-top: -6.5%;
padding-right: 53px;
float:right;
height: 19px;
}
you could try if this would fix the issue

I think it just renders the size of image or block incorrectly, I played on your website with the CSS and and it seems that if you change background size to
background-size: 279.8px auto;
it solves the issue.
UPDATE:
As an additional solution, you might wrap the logo in a div, give the div hidden overflow, and then lift the block with your image up to 1px. It will hide the line as well.

Try like this:
#match div.logo > a {
background-image: url("../../---.png");
background-size: 280px;
height: 85px;
width: 280px;
outline: 0;
}

Related

Add and Remove class on window scroll [duplicate]

So basically I'd like to remove the class from 'header' after the user scrolls down a little and add another class to change it's look.
Trying to figure out the simplest way of doing this but I can't make it work.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll <= 500) {
$(".clearheader").removeClass("clearHeader").addClass("darkHeader");
}
}
CSS
.clearHeader{
height: 200px;
background-color: rgba(107,107,107,0.66);
position: fixed;
top:200;
width: 100%;
}
.darkHeader { height: 100px; }
.wrapper {
height:2000px;
}
HTML
<header class="clearHeader"> </header>
<div class="wrapper"> </div>
I'm sure I'm doing something very elementary wrong.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
//>=, not <=
if (scroll >= 500) {
//clearHeader, not clearheader - caps H
$(".clearHeader").addClass("darkHeader");
}
}); //missing );
Fiddle
Also, by removing the clearHeader class, you're removing the position:fixed; from the element as well as the ability of re-selecting it through the $(".clearHeader") selector. I'd suggest not removing that class and adding a new CSS class on top of it for styling purposes.
And if you want to "reset" the class addition when the users scrolls back up:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
});
Fiddle
edit: Here's version caching the header selector - better performance as it won't query the DOM every time you scroll and you can safely remove/add any class to the header element without losing the reference:
$(function() {
//caches a jQuery object containing the header element
var header = $(".clearHeader");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
header.removeClass('clearHeader').addClass("darkHeader");
} else {
header.removeClass("darkHeader").addClass('clearHeader');
}
});
});
Fiddle
Pure javascript
Here's javascript-only example of handling classes during scrolling.
const navbar = document.getElementById('navbar')
// OnScroll event handler
const onScroll = () => {
// Get scroll value
const scroll = document.documentElement.scrollTop
// If scroll value is more than 0 - add class
if (scroll > 0) {
navbar.classList.add("scrolled");
} else {
navbar.classList.remove("scrolled")
}
}
// Use the function
window.addEventListener('scroll', onScroll)
#navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 60px;
background-color: #89d0f7;
box-shadow: 0px 5px 0px rgba(0, 0, 0, 0);
transition: box-shadow 500ms;
}
#navbar.scrolled {
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.25);
}
#content {
height: 3000px;
margin-top: 60px;
}
<!-- Optional - lodash library, used for throttlin onScroll handler-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
<header id="navbar"></header>
<div id="content"></div>
Some improvements
You'd probably want to throttle handling scroll events, more so as handler logic gets more complex, in that case throttle from lodash lib comes in handy.
And if you're doing spa, keep in mind that you need to clear event listeners with removeEventListener once they're not needed (eg during onDestroy lifecycle hook of your component, like destroyed() for Vue, or maybe return function of useEffect hook for React).
Example throttling with lodash:
// Throttling onScroll handler at 100ms with lodash
const throttledOnScroll = _.throttle(onScroll, 100, {})
// Use
window.addEventListener('scroll', throttledOnScroll)
Add some transition effect to it if you like:
http://jsbin.com/boreme/17/edit?html,css,js
.clearHeader {
height:50px;
background:lightblue;
position:fixed;
top:0;
left:0;
width:100%;
-webkit-transition: background 2s; /* For Safari 3.1 to 6.0 */
transition: background 2s;
}
.clearHeader.darkHeader {
background:#000;
}
Its my code
jQuery(document).ready(function(e) {
var WindowHeight = jQuery(window).height();
var load_element = 0;
//position of element
var scroll_position = jQuery('.product-bottom').offset().top;
var screen_height = jQuery(window).height();
var activation_offset = 0;
var max_scroll_height = jQuery('body').height() + screen_height;
var scroll_activation_point = scroll_position - (screen_height * activation_offset);
jQuery(window).on('scroll', function(e) {
var y_scroll_pos = window.pageYOffset;
var element_in_view = y_scroll_pos > scroll_activation_point;
var has_reached_bottom_of_page = max_scroll_height <= y_scroll_pos && !element_in_view;
if (element_in_view || has_reached_bottom_of_page) {
jQuery('.product-bottom').addClass("change");
} else {
jQuery('.product-bottom').removeClass("change");
}
});
});
Its working Fine
Is this value intended? if (scroll <= 500) { ... This means it's happening from 0 to 500, and not 500 and greater. In the original post you said "after the user scrolls down a little"
In a similar case, I wanted to avoid always calling addClass or removeClass due to performance issues. I've split the scroll handler function into two individual functions, used according to the current state. I also added a debounce functionality according to this article: https://developers.google.com/web/fundamentals/performance/rendering/debounce-your-input-handlers
var $header = jQuery( ".clearHeader" );
var appScroll = appScrollForward;
var appScrollPosition = 0;
var scheduledAnimationFrame = false;
function appScrollReverse() {
scheduledAnimationFrame = false;
if ( appScrollPosition > 500 )
return;
$header.removeClass( "darkHeader" );
appScroll = appScrollForward;
}
function appScrollForward() {
scheduledAnimationFrame = false;
if ( appScrollPosition < 500 )
return;
$header.addClass( "darkHeader" );
appScroll = appScrollReverse;
}
function appScrollHandler() {
appScrollPosition = window.pageYOffset;
if ( scheduledAnimationFrame )
return;
scheduledAnimationFrame = true;
requestAnimationFrame( appScroll );
}
jQuery( window ).scroll( appScrollHandler );
Maybe someone finds this helpful.
For Android mobile $(window).scroll(function() and $(document).scroll(function() may or may not work. So instead use the following.
jQuery(document.body).scroll(function() {
var scroll = jQuery(document.body).scrollTop();
if (scroll >= 300) {
//alert();
header.addClass("sticky");
} else {
header.removeClass('sticky');
}
});
This code worked for me. Hope it will help you.
This is based of of #shahzad-yousuf's answer, but I only needed to compress a menu when the user scrolled down. I used the reference point of the top container rolling "off screen" to initiate the "squish"
<script type="text/javascript">
$(document).ready(function (e) {
//position of element
var scroll_position = $('div.mainContainer').offset().top;
var scroll_activation_point = scroll_position;
$(window).on('scroll', function (e) {
var y_scroll_pos = window.pageYOffset;
var element_in_view = scroll_activation_point < y_scroll_pos;
if (element_in_view) {
$('body').addClass("toolbar-compressed ");
$('div.toolbar').addClass("toolbar-compressed ");
} else {
$('body').removeClass("toolbar-compressed ");
$('div.toolbar').removeClass("toolbar-compressed ");
}
});
}); </script>

Changing position background in JavaScript, strange issue

I have a simple question, I would like to change one picture when a user scroll the page (to make an illusion of 3d picture)
the first approach was changing the image src every time (making like 8 different pictures) but I could see the lag on the browser when I was scrolling, the effect was not good.
So that, I had the idea to make one single image, anche change the background-position while the user scroll.
This works perfect (when everything is loaded), the only problem is when the user scroll, each time the background-position is changing, the browser reload the picture. So that, the waiting will be to much. Looks like load different picture, but it's only one.
I don't understand why, the picture is always the same, why there is this problem? did someone know another solution?
this is the script:
<script type="text/javascript">
jQuery('.qty-cart-btn2').hide();
jQuery('.shoes-360-2').css('backgroundImage','url(shoes_img1/360.png)');
require(['jquery', 'jquery/ui'], function($){
jQuery(function(){
jQuery(window).scroll(function(){
if(jQuery(this).scrollTop() >= 30) {
jQuery('#back-shoes')
.css({'background-position-y':'-264px'})
}
if(jQuery(this).scrollTop() >= 45) {
jQuery('#back-shoes')
.css({'background-position-y':'-528px'})
}
if(jQuery(this).scrollTop() >= 60) {
jQuery('#back-shoes')
.css({'background-position-y':'-792px'})
}
if(jQuery(this).scrollTop() >= 75) {
jQuery('#back-shoes')
.css({'background-position-y':'-1056px'})
}
if(jQuery(this).scrollTop() >= 90) {
jQuery('#back-shoes')
.css({'background-position-y':'-1320px'})
}
if(jQuery(this).scrollTop() >= 105) {
jQuery('#back-shoes')
.css({'background-position-y':'-1584px'});
}
if(jQuery(this).scrollTop() >= 120) {
jQuery('#back-shoes')
.css({'background-position-y':'-1848px'});
}
});
});
});
</script>
Thank you very much
Use IF condition in greather than and smaller than, like:
jQuery(function(){
jQuery(window).scroll(function(){
var Scroll = jQuery(this).scrollTop();
if(Scroll >= 30 && Scroll < 45){
jQuery('#back-shoes').css({'background-position-y':'-264px'})
}
});
});
I solved by this example:
<div id="rotator"></div>
$(function() {
var rotator = $('#rotator');
var container = $(document);
var viewport = $(window);
var images = 72;
var imageHeight = 30000 / images;
var scrollHeight = container.height() - viewport.height() + imageHeight;
var step = images / scrollHeight;
viewport.scroll(function(event) {
var x = -Math.floor(step * viewport.scrollTop()) * imageHeight;
rotator.css('background-position', x + 'px 0');
});
body {
height: 2000px;
}
#rotator {
font-size: 416px;
width: 1em;
height: 1em;
position: fixed;
top: 0;
right: 0;
z-index: -1;
background: transparent url(http://www.3sessanta.it/images/polaroid/sprite_polaroid_total.jpg) no-repeat 0 0;
}
http://jsfiddle.net/coma/sBTzG/13/
Thanks everyone

How can I make my setTimeouts get stopped here?

The behavior I'm trying to achieve is this:
On hover/mouseenter, change the background image from the placeholder to a gif whose positions changes in order to achieve an animated effect, then go back to the placeholder when the mouse leaves.
My code is
$('.filmstrip').mouseenter(function(){
var $that = $(this),
w = $that.width(),
fr = $that.attr('data-framerate');
$that.css('background-image','url('+$that.attr('data-gifurl')+')');
for ( var i = 1, n = $that.attr('data-ticks'); i <= n; ++i )
{
(function(j){
setTimeout(function(){
$that.css('background-position-x','-'+(w*j)+'px');
}, j*fr);
})(i);
}
$that.bind('mouseleave',function(){
$that.css('background-image','url('+$that.attr('data-placeholder')+')').css('background-position-x','0');
});
});
and the bug I'm having is that if the gif hasn't finished animating, then the
.css('background-position-x','0')
part of
$that.css('background-image','url('+$that.attr('data-placeholder')+')').css('background-position-x','0');
});
doesn't work because the background position is still being moved by the animation. So I need some way to first stop the setTimeout stuff if it isn't finished running. Any idea how I can do that?
This may be something better done with CSS rather than javascript.
Option #1 - Use an actual GIF
You could compile the frames which you want animated into an actual GIF file, and then have the background image change based on hover:
<div class="filmstrip"></div>
And then CSS
.filmstrip { background:transparent url('static_image.jpg') no-repeat 0 0 }
.filmstrip:hover { background-image:url( 'animated_image.gif' ) }
Option #2 - Use CSS3 Animation
You could keep the animated image as a strip of frames (of a known length) and then use something like:
<div class="filmstrip"></div>
With CSS
.filmstrip { background:transparent url('static_image.jpg') no-repeat 0 0 }
#keyframes animate-bg {
0% { background-position: 0 0 }
100% { background-position: -1000px 0 }
/* where 1000px is the length of the strip */
}
.filmstrip:hover { animation: animate-bg 5s steps(50) infinite }
/* where 5s is the overall loop length time and 50 is the number of frames in the strip */
Option #3 - Use Spritely
Spritely is a jQuery plugin which seems to manage all elements of turning a filmstrip/sprite image into an animation, including being able to start/stop the animation, reset to the first frame, change FPS, etc.
Add a stop variable :
$('.filmstrip').mouseenter(function(){
var isStopped = false;
var $that = $(this),
w = $that.width(),
fr = $that.attr('data-framerate');
$that.css('background-image','url('+$that.attr('data-gifurl')+')');
for ( var i = 1, n = $that.attr('data-ticks'); i <= n && !isStopped; ++i )
{
(function(j){
setTimeout(function(){
if (!isStopped) {
$that.css('background-position-x','-'+(w*j)+'px');
}
}, j*fr);
})(i);
}
$that.bind('mouseleave',function(){
isStopped = true;
$that.css('background-image','url('+$that.attr('data-placeholder')+')').css('background-position-x','0');
});
});
If isStopped is not accessible (because not tested) from the timeout, then just create a new variable in a inner scope which you affect isStopped value.
You can use an interval based solution like
$('.filmstrip').mouseenter(function() {
var $that = $(this),
w = $that.width(),
fr = +$that.attr('data-framerate'),
ticks = +$that.attr('data-ticks');
$that.css('background-image', 'url(' + $that.attr('data-gifurl') + ')');
var counter = 0;
var interval = setInterval(function() {
$that.css('background-position-x', '-' + (w * ++counter) + 'px');
if (counter >= ticks) {
clearInterval(interval);
}
}, fr);
$(this).data('bg-interval', interval)
}).mouseleave(function() {
clearInterval($(this).data('bg-interval'));
$(this).css('background-image', 'url(' + $(this).attr('data-placeholder') + ')').css('background-position-x', '0');
});
.filmstrip {
height: 64px;
border: 1px solid grey;
background-position: right;
background-position-y: inherit;
display: inline-block;
width: 64px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filmstrip" data-framerate="400" data-ticks="10" data-gifurl="//cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg?v=bc7c2f3904bf">
</div>
U can use clearTimeout to stop setTimeOut.
Working Demo-
var myVar;
function myFunction() {
myVar = setTimeout(function(){ alert("Hello"); }, 3000);
}
function myStopFunction() {
clearTimeout(myVar);
}
<p>Click the first button to alert "Hello" after waiting 3 seconds.</p>
<p>Click the second button to prevent the first function to execute. (You must click it before the 3 seconds are up.)</p>
<button onclick="myFunction()">Try it</button>
<button onclick="myStopFunction()">Stop the alert</button>
More-
Mozilla Developer Network
and
W3School

HTML - Body Rotation Affecting Fixed Elements

I have a Javascript function which is used to shake the screen for about a second.
function shakeScreen() {
var degrees = 0;
var goal = 0;
var goals = [5,-5,4,-4,3,-4,2,-2,1,-1,0];
function frame() {
if(goals[goal] < 0) {
degrees -= 1;
} else {
degrees += 1;
}
get('body','tag');
current[0].style.transform = 'rotate(' + degrees + 'deg)';
if(degrees === goals[goal]) {
goal += 1;
if(goal === goals.length) {
clearInterval(intervalId);
}
}
}
var intervalId = setInterval(frame,16);
}
Inside my HTML body, my first element has a fixed position. This element is a pop-up that displays messagers to users, and it has a fixed position so it appears in the same position on the screen if the end user has scrolled down or up the page. Here is a snippet of the HTML:
<body>
<div id='fade' onclick="fade('out')"><div id='alert'></div></div>
<!-- more unrelated content -->
Here is the CSS for the specified element above:
#fade {
z-index: 2750;
position: fixed; /*important*/
display: none;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: rgba(0, 0, 0, 0);
text-align: center;
}
#fade:hover {
cursor: pointer;
}
When the Javascript function shakeScreen() is executed, the fade element gets misaligned and moves to the top of the body rather than remaining in the center of the end user's screen. Here is the JSFiddle: https://jsfiddle.net/turkey3/ug9zx1d2/3/ Scroll down halfway and you'll see a button. Click that button to shake the screen. You'll notice a split second where the fade element starts appearing at the center of the screen, but then it moves to the top after it starts shaking. Also, to see how I want it to be, comment out the shakeScreen function that's inside the setup function and then run the code.
Edit: The fade element is simply a dark background. The alert element is a white box with the message that shows to the user.
Solution
I found out the best method was, rather than rotating the body element, was to wrap all the other code insider a div and shake the division rather than the entire body. After that, the alert message properly showed in the center of the screen. Here is the fixed code: https://jsfiddle.net/turkey3/ug9zx1d2/4/
Here is the HTML wrapped in the div:
<body>
<div id='fade' onclick="fade('out')"><div id='alert'></div></div>
<div id='shake'>
<!-- more unrelated content -->
</div>
And updated JS:
function shakeScreen() {
var degrees = 0;
var goal = 0;
var goals = [5,-5,4,-4,3,-4,2,-2,1,-1,0];
function frame() {
if(goals[goal] < 0) {
degrees -= 1;
} else {
degrees += 1;
}
get('shake','id');
current.style.transform = 'rotate(' + degrees + 'deg)';
if(degrees === goals[goal]) {
goal += 1;
if(goal === goals.length) {
clearInterval(intervalId);
}
}
}
var intervalId = setInterval(frame,16);
}

Resizing a web page dynamically

I am developing a bunch of small web applications that have an unknown window size as target. To solve this problem, I am developing very large layouts and scaling them according to the window size.
My solution however has an inconvenience. When I resize everything, things get a little bit out of place (mainly when scaling text) and it is noticeable. My code is very simple, everything in my page is absolutely positioned so I just get the scaling factor and apply it to all the positions and width / height of every div/img/span/input in the page. The code is as follows:
function resize()
{
var wh = $(window).height();
var h = maxHeight;
var ww = $(window).width();
var w = maxWidth;
var wProp = ww / w;
var hProp = wh / h;
if (wProp < hProp) prop = wProp;
else prop = hProp;
if (prop > 1) prop = 1;
console.log(prop);
$("div").each (applyNewSize);
$("img").each (applyNewSize);
$("span").each (applyNewSize);
$("input").each (applyNewSize);
}
//this is run when the page is loaded
function initializeSize (i)
{
this.oX = $(this).position().left;
this.oY = $(this).position().top;
this.oW = $(this).width();
this.oH = $(this).height();
if ($(this).css("font-size") != undefined)
{
this.oFS = Number($(this).css("font-size").split("px")[0]);
}
}
function applyNewSize (i)
{
if (this.oFS != undefined) $(this).css("font-size", Math.round(this.oFS * prop) + "px");
$(this).css("left", Math.round(this.oX * prop) + "px");
$(this).css("top", Math.round(this.oY * prop) + "px");
$(this).width(Math.round(this.oW * prop));
$(this).height(Math.round(this.oH * prop));
}
This problem has been tormenting me for the past week. Do you have any workaround or solution for this?
I recommend you to read about Responsive Web design.
It works putting % instead the exact pixels :
<div class="container">
<section>
THIS IS THE SECTION
</section>
</div>
CSS::
.container{
width: 80%; // 80% instead pixels
background: gainsboro;
border: 3px inset darkgrey;
height: 200px;
margin:auto;
text-align:center;
}
section{
width: 80%; // 80% instead pixels
height: 80%; // 80% instead pixels
background: darkgrey;
margin:auto;
}
Then you can use media queries as well, to reallocate the blocks or applying different styles on different widths :
example tutorial : http://css-tricks.com/css-media-queries/

Categories