Scrolling marquee text wrap on IE9 - javascript

I am working on a scrolling marquee SharePoint web part. The web part is using the cycle plugin here (http://jquery.malsup.com/cycle/)
The text will scrolling down to the bottom and reappear at the top. It works as expected in IE8. However, in IE9, some string will have problem. (e.g. UAT Testing on 9 May) When the text reappear at the top it wrapped by unknown reason.
fiddle link here:
http://jsfiddle.net/9PK6z/18/
See the picture below:
Here is the part of script:
<div id='ticker_10eb4222-addd-4f86-8d84-94926eae0aa2' class='ticker' style='position: relative; width: 530px; height: 60px; overflow: hidden;'>
<ul class="list-style1"><li><span>UAT Testing on 1 Aug</span></li></ul>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
for(var i =0; i<2; i++) {
$('#ticker_10eb4222-addd-4f86-8d84-94926eae0aa2')
.find("ul")
.clone()
.appendTo($('#ticker_10eb4222-addd-4f86-8d84-94926eae0aa2'));
}
$('#ticker_10eb4222-addd-4f86-8d84-94926eae0aa2')
.cycle({ fx: 'scrollVert', continuous: 1, speed: $('#ticker_10eb4222-addd-4f86-8d84-94926eae0aa2')
.find("ul:eq(0) li").size() * 3000, delay: 0, easing: 'linear', rev:0 });
});
</script>
String like "UAT Testing at 1 Aug" will not have problem. I have tried many combination still not find the pattern.
What changes in IE9 cause the problem?

Based on your fiddle it seemed to be an issue with the overflow css property.
I found that by switching the overflow from the #ticker element to the ul element, it started to work
.bochk-list-style1 {
background-color:#ffffb6;
overflow: hidden;
}
#ticker {
border:1px solid black;
}
I tested this in Chrome and IE9 and it seemed to work ok
Fiddle

Related

From smooth scroll to normal one and vice versa

I'll start linking you the website which I'm referring to.
This one instead is an Official website which has this feature already up and working, maybe you'll understand better what I mean hopefully!
I've made 2 sections, and applied a scroll that needs just a single mouse scroll to get automatically to the next section.
But in this page, I have a table in the 2nd section, a long one, so I'd prefer to disable that fixed view of the section and enable the normal scroll in order to see the whole table.
But, I'd like to be able to switch back to the other scroll when I'll scroll up til the end of the second section, ready to go back to the 1st.
This is my JS script:
$(document).ready(function() {
$('#fullpage').fullpage({
css3: true,
scrollingSpeed: 600,
autoScrolling: true,
fitToSection: true,
fitToSectionDelay: 1000,
scrollBar: false,
easing: 'easeInOutCubic',
easingcss3: 'ease',
//Design
controlArrows: true,
verticalCentered: true,
sectionsColor: ['#ccc', '#fff', '#cfc'],
fixedElements: '#header, .footer',
responsiveWidth: 0,
responsiveHeight: 0,
});
});
I am using FullPage to do this, maybe some of you already know it.
EDIT:
This is the body setup, 2 sections, #first and #second, each one inside a div of class .section, and both divs inside the div #fullpage:
<div id="fullpage">
<div class="section" id="first">
<p style="color:#fff; margin-bottom: 50px; font-size: 5em; text-align: center;">Staff</p>
</div>
<div class="section" id="second">
<!-- Capo -->
<table>
...
</table>
</div>
</div>
I can't do much more for you, this is a fiddle! with a hack to your problem, more than a solution, but hope it inspire you to find a much better aproach and solution
jQuery:
var sec=0;
$('#first').on('mousewheel', function(event) {
console.log('scroll, '+sec+", "+$("#fullpage").scrollTop());
if(sec == 0 && $("#fullpage").scrollTop()!=0){
$("#first").slideUp(300,function(){
$("#second").show(function(){
$("#second").scrollTop(1);
});
});
}
});
$('#second').on('mousewheel', function(event) {
if(sec==0){
sec=1;
}
console.log($("#second").scrollTop());
if($("#second").scrollTop() == 0){
sec=0;
$("#second").hide();
$("#first").slideDown(300, function(){
$("#fullpage").scrollTop(0);
});
}
});
and the addition to your CSS:
#first{
margin-top:0px;
margin-left:0px;
height:401px;
overflow-y: auto;
}
#second{
display:none;
margin-top:0px;
margin-left:0px;
height:100%;
overflow-y: auto;
}
#fullpage{
height:400px;
overflow: hidden;
overflow-y: auto;
}
I really love programming, but got my own software to develop and maintain ;)

Webflow and Fullpage.js interfering with each other

I am currently using the fullpage.js plugin on a test website I designed with webflow. Everything worked correctly until I included the plugin. Now, the scrolling interactions of webflow don't work anymore.
I think the two javascript files kind of interfere with each other, limiting functions of the other one to work correctly. I would love to fix this but I really don't know how.
This is the site without the fullpage.js included. This is the site with the fullpage.js included. As you can see, in the first example the paragraphs fade in and out on scrolling. In the second example they don't. The paragraphs simply stay in their initial appearance state which is opacity = 0. I really would love to see the fullpage.js working side by side with the webflow interactions.
_
This is the html code:
<body>
<div class="pagewrap">
<div class="section blue01">
<div class="w-container">
<p data-ix="scroll-fade-in"></p>
</div>
</div>
<div class="section blue02">
<div class="w-container">
<p data-ix="scroll-fade-in"></p>
</div>
</div>
<div class="section blue03">
<div class="w-container">
<p data-ix="scroll-fade-in"></p>
</div>
</div>
</div>
</body>
_
This is the javascript code:
<script type="text/javascript" src="js/webflow.js"></script>
<script type="text/javascript" src="js/jquery.fullPage.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.pagewrap').fullpage({
'verticalCentered': true,
'css3': true,
'navigation': true,
'navigationPosition': 'right',
});
});
</script>
_
This is the CSS code:
.section.table,
.slide.table {
display: table;
width: 100%;
}
.tableCell {
display: table-cell;
vertical-align: middle;
width: 100%;
height: 100%;
}
.easing {
-webkit-transition: all 1s ease-in-out;
-moz-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
.section {
height: 100vh;
}
.section.blue01 {
background-color: #3cb7e8;
}
.section.blue02 {
background-color: #3ccbe8;
}
.section.blue03 {
background-color: #3ce2e8;
}
html.w-mod-js.w-mod-no-ios *[data-ix="scroll-fade-in"] {
opacity: 0;
}
_
This is where you can find the two included javascript files:
jaroquastenberg.de/_x/help/01/js/webflow.js
jaroquastenberg.de/_x/help/01/js/jquery.fullPage.js
_
Is there maybe anyone who is good at javascript and can find out where the two scripts conflict with each other?
Thanks in advance!
Jaro
You'll find the answer in fullPage.js FAQs:
jQuery scroll event doesn't work
Same answer as Parallax doesn't work with fullpage.js
Also, consider using the callbacks provided by fullpage.js such as afterLoad, onLeave, afterSlideLeave and onSlideLeave detailed in the docs or the class added to the body element containing the active section/slide.
And:
Parallax doesn't work with fullpage.js.
Short answer: use the scrollBar:true option for fullPage.js or autoScrolling:false if you don't want to use the auto-scrolling feature.
Explanation: Parallax, as well as many other plugins which depends on the scrolling of the site, listens the scrollTop property of javascript. fullPage.js doesn't actually scroll the site but it changes the top or translate3d property of the site. Only when using the fullPage.js option scrollBar:true or autoScrolling:false it will actually scroll the site in a way it is accessible for the scrollTop property.
If you just want your text to fadeIn or out, I would use the CSS class added to the body on page change. But feel free to use the callbacks as well combined with javascript or jQuery to create your effects.
I solved how to run SCROLL animations in WEBFLOWE if you use FULLPAGE.JS. To scroll ANCHOR, after refreshing for each ANCHOR, refresh the scrolla position as follows:
$(document).ready(function() {
$('#fullpage').fullpage({
anchors: ['01', '02', '03', '04', '05'],
animateAnchor: true,
easing: 'easeInOutCubic',
scrollingSpeed: 600,
scrollOverflow: true,
scrollOverflowReset: true,
//
afterLoad: function(origin, destination, direction){
var loadedSection = this;
//refresh scroll position
$.fn.fullpage.setAutoScrolling(false);
$.fn.fullpage.setAutoScrolling(true);
//
if(origin.anchor == '01'){
}
if(origin.anchor == '02'){
}
if(origin.anchor == '03'){
}
if(origin.anchor == '04'){
}
if(origin.anchor == '05'){
}
}
});
});

Scroll Sections with Custom Scrollbar (Nice Scroll) -- Animation jerks on fast Scrolling

DEMO
I am using Scroll Section with Nice Scroll.
Every thing is fine but if i scroll really quickly it start producing these animation jerks.
HTML:
<section id="top" class="root_section">
This is a section 1
</section>
<section id="mid" class="root_section">
This is a section 2
<section id="mid-test-1" class="mid-inner-test-1 root_section"> Mid section </section>
</section>
<section id="bot" class="root_section">
This is a section 3
</section>
CSS:
html, body{
height:!00%;
}
.root_section{
height: 100%;
position: relative;
}
.mid-inner-test-1{
position: absolute;
top: 100px;
left: 100px;
}
JS:
$('section.root_section').scrollSections({
mousewheel: true,
});
$("body").niceScroll({
easing: 'easeOutCircle'
});
What i have tried:
If i declear mousewheel: false on scrollSection() function it starts working fine but it no longer switches the section on single scroll down or scroll up.
Any help will be much appreciated.
Change your JS to:
Demo Fiddle
$('body').scrollSections({
mousewheel: true,
});
$("body").niceScroll({
easing: 'easeOutCircle'
});
You are giving the plugin conflicting information, by instructing two different elements. You are effectively applying it to your body but then detecting the scroll event for mouse wheel on a child seperately.

Trying to fade and slide text out of initials on mouse over with jQuery

I'm trying to create an effect with jQuery where on mouse over of my initials on the page in the header, the div they are in expands (using jQuery animate) and the text of my full name fades in from each initial.
I have tried a variety of things but am not sure what is the best way to do this. I'm a bit stuck. I'm currently trying to get it going by having the initials of my name "OW" in two separate divs and then the remainder of my name to make up "wen" and "illiams" in between those initals. Like so:
<div class="initialF inlinediv">O</div>
<div class="fullF inlinediv">wen</div>
<div class="initialL inlinediv">W</div>
<div class="fullL inlinediv">illiams</div>
I thought it would work to use jQuery slideLeft and .fadeIn to get the text to slide in from the left as well as fading to look like the text is emerging from the initials but the animations was jumpy and would go onto a second line while the div was still expanding. I am using the below jQuery to detect the mouseIn/Out events:
<script>
$(".brand").mouseenter(function() {
$('.brand').animate({width: '160px'});
$('.fullF').fadeIn("slow");
});
$(".brand").mouseout(function() {
$('.brand').animate({width: '36px'});
$('.fullF').fadeOut("slow");
});
</script>
The alternatives I have tried were using jquery.lettering.js to help with it but there seemed to be some issues with that. Any suggestions to push me in the right direction would be useful and my site with a partially working example is here:
http://192.241.203.146/
Here's one using css transitions rather than jquery animate: http://jsfiddle.net/S58Se/2/
<div class='branding'>
<span class='initial'>O</span><span class='hidden nameFull wen'>wen</span>
<span class='initial'>W</span><span class='hidden nameFull illiams'>illiams</span>
</div>
span {
display: inline-block;
overflow: hidden;
transition: all 1s;
-moz-transition: all 1s;
-webkit-transition: all 1s;
}
.wen { width: 36px; }
.illiams { width: 160px; }
span.hidden {
width: 0px;
opacity: 0;
}
$('.branding').hover(
function() { $('.nameFull').removeClass('hidden'); },
function() { $('.nameFull').addClass('hidden'); }
);
Or you can do away with the javascript altogether with this: http://jsfiddle.net/S58Se/3/
remove the js and add these css statements:
.branding:hover .wen {
width: 36px;
opacity: 1;
}
.branding:hover .illiams {
width: 160px;
opacity: 1;
}
... just because I think it's neat.
A good way to go about this is to just expand the use of your call to the animation method by adding another property to the object you are passing in. So instead of calling an extra method (fadeIn) you just handle it all in one fell swoop:
$('.brand').on({
'mouseenter' : function () {
$('.nameFull').stop().animate({
'width' : '200px',
'opacity' : '1'
}, 500);
},
'mouseleave' : function () {
$('.nameFull').stop().animate({
'width' : '0',
'opacity' : '0'
}, 500);
}
});
You'll notice I'm also using 'on' instead of the 'hover' or 'mouseenter' and 'mouseleave' methods. In most recent versions of jQuery those methods just reference 'on', so it's better to just cut out the middle man and do it all in one place.
I'm not sure if this exactly fits your design, but I made a Codepen to demonstrate the code in action: http://codepen.io/Tristan-zimmerman/pen/lnDGh
Style the hidden divs position:absolute, and when show them:
'show' them first, to set them visible
then position them (next to your 'launching' div), using jQuery.position();
set the animation going.
Essentially you want them 'absolute' to avoid them thunking in/out & changing your existing flow. position() must be called after making the element visible, and then you should have appropriate starting conditions to kick off your animation.
Or you could try using <span>' for the incoming text and/or displaying as inline-block, which may help avoid the "incoming" kicking things down a line. HTH.
I think what you are looking for is something like this: JSFiddle
html:
<div class="brand">
<div>O<span class="full">wen </span>W<span class="full">illiams</span></div>
</div>
jq:
$('.brand').hover(function(){
$(this).stop().animate({width: '160px'},'slow',function(){
$(this).children('div').children('.full').stop().fadeIn('slow');
});
},function(){
$(this).children('div').children('.full').stop().fadeOut('slow',function(){
$(this).parent().parent().stop().animate({width: '36px'},'slow');
});
});
css:
.full{
display: none;
}
note: there is a simple bug that happens in a specific case and I'm working on it.
regards,

offsetting an html anchor to adjust for fixed header [duplicate]

This question already has answers here:
Fixed page header overlaps in-page anchors
(38 answers)
Closed 7 years ago.
I am trying to clean up the way my anchors work. I have a header that is fixed to the top of the page, so when you link to an anchor elsewhere in the page, the page jumps so the anchor is at the top of the page, leaving the content behind the fixed header (I hope that makes sense). I need a way to offset the anchor by the 25px from the height of the header. I would prefer HTML or CSS, but Javascript would be acceptable as well.
You could just use CSS without any javascript.
Give your anchor a class:
<a class="anchor" id="top"></a>
You can then position the anchor an offset higher or lower than where it actually appears on the page, by making it a block element and relatively positioning it. -250px will position the anchor up 250px
a.anchor {
display: block;
position: relative;
top: -250px;
visibility: hidden;
}
I found this solution:
<a name="myanchor">
<h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</a>
This doesn't create any gap in the content and anchor links works really nice.
I was looking for a solution to this as well. In my case, it was pretty easy.
I have a list menu with all the links:
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
And below that the headings where it should go to.
<h3>one</h3>
<p>text here</p>
<h3>two</h3>
<p>text here</p>
<h3>three</h3>
<p>text here</p>
<h3>four</h3>
<p>text here</p>
Now because I have a fixed menu at the top of my page I can't just make it go to my tag because that would be behind the menu.
Instead, I put a span tag inside my tag with the proper id.
<h3><span id="one"></span>one</h3>
Now use 2 lines of CSS to position them properly.
h3{ position:relative; }
h3 span{ position:absolute; top:-200px;}
Change the top value to match the height of your fixed header (or more).
Now I assume this would work with other elements as well.
FWIW this worked for me:
[id]::before {
content: '';
display: block;
height: 75px;
margin-top: -75px;
visibility: hidden;
}
As this is a concern of presentation, a pure CSS solution would be ideal. However, this question was posed in 2012, and although relative positioning / negative margin solutions have been suggested, these approaches seem rather hacky, create potential flow issues, and cannot respond dynamically to changes in the DOM / viewport.
With that in mind I believe that using JavaScript is still (February 2017) the best approach. Below is a vanilla-JS solution which will respond both to anchor clicks and resolve the page hash on load (See JSFiddle). Modify the .getFixedOffset() method if dynamic calculations are required. If you're using jQuery, here's a modified solution with better event delegation and smooth scrolling.
(function(document, history, location) {
var HISTORY_SUPPORT = !!(history && history.pushState);
var anchorScrolls = {
ANCHOR_REGEX: /^#[^ ]+$/,
OFFSET_HEIGHT_PX: 50,
/**
* Establish events, and fix initial scroll position if a hash is provided.
*/
init: function() {
this.scrollToCurrent();
window.addEventListener('hashchange', this.scrollToCurrent.bind(this));
document.body.addEventListener('click', this.delegateAnchors.bind(this));
},
/**
* Return the offset amount to deduct from the normal scroll position.
* Modify as appropriate to allow for dynamic calculations
*/
getFixedOffset: function() {
return this.OFFSET_HEIGHT_PX;
},
/**
* If the provided href is an anchor which resolves to an element on the
* page, scroll to it.
* #param {String} href
* #return {Boolean} - Was the href an anchor.
*/
scrollIfAnchor: function(href, pushToHistory) {
var match, rect, anchorOffset;
if(!this.ANCHOR_REGEX.test(href)) {
return false;
}
match = document.getElementById(href.slice(1));
if(match) {
rect = match.getBoundingClientRect();
anchorOffset = window.pageYOffset + rect.top - this.getFixedOffset();
window.scrollTo(window.pageXOffset, anchorOffset);
// Add the state to history as-per normal anchor links
if(HISTORY_SUPPORT && pushToHistory) {
history.pushState({}, document.title, location.pathname + href);
}
}
return !!match;
},
/**
* Attempt to scroll to the current location's hash.
*/
scrollToCurrent: function() {
this.scrollIfAnchor(window.location.hash);
},
/**
* If the click event's target was an anchor, fix the scroll position.
*/
delegateAnchors: function(e) {
var elem = e.target;
if(
elem.nodeName === 'A' &&
this.scrollIfAnchor(elem.getAttribute('href'), true)
) {
e.preventDefault();
}
}
};
window.addEventListener(
'DOMContentLoaded', anchorScrolls.init.bind(anchorScrolls)
);
})(window.document, window.history, window.location);
Pure css solution inspired by Alexander Savin:
a[name] {
padding-top: 40px;
margin-top: -40px;
display: inline-block; /* required for webkit browsers */
}
Optionally you may want to add the following if the target is still off the screen:
vertical-align: top;
My solution combines the target and before selectors for our CMS. Other techniques don't account for text in the anchor. Adjust the height and the negative margin to the offset you need...
:target::before {
content: '';
display: block;
height: 180px;
margin-top: -180px;
}
This takes many elements from previous answers and combines into a tiny (194 bytes minified) anonymous jQuery function. Adjust fixedElementHeight for the height of your menu or blocking element.
(function($, window) {
var adjustAnchor = function() {
var $anchor = $(':target'),
fixedElementHeight = 100;
if ($anchor.length > 0) {
$('html, body')
.stop()
.animate({
scrollTop: $anchor.offset().top - fixedElementHeight
}, 200);
}
};
$(window).on('hashchange load', function() {
adjustAnchor();
});
})(jQuery, window);
If you don't like the animation, replace
$('html, body')
.stop()
.animate({
scrollTop: $anchor.offset().top - fixedElementHeight
}, 200);
with:
window.scrollTo(0, $anchor.offset().top - fixedElementHeight);
Uglified version:
!function(o,n){var t=function(){var n=o(":target"),t=100;n.length>0&&o("html, body").stop().animate({scrollTop:n.offset().top-t},200)};o(n).on("hashchange load",function(){t()})}(jQuery,window);
For modern browsers, just add the CSS3 :target selector to the page. This will apply to all the anchors automatically.
:target {
display: block;
position: relative;
top: -100px;
visibility: hidden;
}
You can do it without js and without altering html. It´s css-only.
a[id]::before {
content: '';
display: block;
height: 50px;
margin: -30px 0 0;
}
That will append a pseudo-element before every a-tag with an id. Adjust values to match the height of your header.
I had been facing a similar issue, unfortunately after implementing all the solutions above, I came to the following conclusion.
My inner elements had a fragile CSS structure and implementing a position relative / absolute play, was completely breaking the page design.
CSS is not my strong suit.
I wrote this simple scrolling js, that accounts for the offset caused due to the header and relocated the div about 125 pixels below. Please use it as you see fit.
The HTML
<div id="#anchor"></div> <!-- #anchor here is the anchor tag which is on your URL -->
The JavaScript
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
&& location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top - 125 //offsets for fixed header
}, 1000);
return false;
}
}
});
//Executed on page load with URL containing an anchor tag.
if($(location.href.split("#")[1])) {
var target = $('#'+location.href.split("#")[1]);
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top - 125 //offset height of header here too.
}, 1000);
return false;
}
}
});
See a live implementation here.
For the same issue, I used an easy solution : put a padding-top of 40px on each anchor.
As #moeffju suggests, this can be achieved with CSS. The issue I ran into (which I'm surprised I haven't seen discussed) is the trick of overlapping previous elements with padding or a transparent border prevents hover and click actions at the bottom of those sections because the following one comes higher in the z-order.
The best fix I found was to place section content in a div that is at z-index: 1:
// Apply to elements that serve as anchors
.offset-anchor {
border-top: 75px solid transparent;
margin: -75px 0 0;
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
}
// Because offset-anchor causes sections to overlap the bottom of previous ones,
// we need to put content higher so links aren't blocked by the transparent border.
.container {
position: relative;
z-index: 1;
}
Solutions with changing position property are not always possible (it can destroy layout) therefore I suggest this:
HTML:
<a id="top">Anchor</a>
CSS:
#top {
margin-top: -250px;
padding-top: 250px;
}
Use this:
<a id="top"> </a>
to minimize overlapping, and set font-size to 1px. Empty anchor will not work in some browsers.
Borrowing some of the code from an answer given at this link (no author is specified), you can include a nice smooth-scroll effect to the anchor, while making it stop at -60px above the anchor, fitting nicely underneath the fixed bootstrap navigation bar (requires jQuery):
$(".dropdown-menu a[href^='#']").on('click', function(e) {
// prevent default anchor click behavior
e.preventDefault();
// animate
$('html, body').animate({
scrollTop: $(this.hash).offset().top - 60
}, 300, function(){
});
});
The above methods don't work very well if your anchor is a table element or within a table (row or cell).
I had to use javascript and bind to the window hashchange event to work around this (demo):
function moveUnderNav() {
var $el, h = window.location.hash;
if (h) {
$el = $(h);
if ($el.length && $el.closest('table').length) {
$('body').scrollTop( $el.closest('table, tr').position().top - 26 );
}
}
}
$(window)
.load(function () {
moveUnderNav();
})
.on('hashchange', function () {
moveUnderNav();
});
* Note: The hashchange event is not available in all browsers.
You can achieve this without an ID using the a[name]:not([href]) css selector. This simply looks for links with a name and no href e.g. <a name="anc1"></a>
An example rule might be:
a[name]:not([href]){
display: block;
position: relative;
top: -100px;
visibility: hidden;
}
Instead of having a fixed-position navbar which is underlapped by the rest of the content of the page (with the whole page body being scrollable), consider instead having a non-scrollable body with a static navbar and then having the page content in an absolutely-positioned scrollable div below.
That is, have HTML like this...
<div class="static-navbar">NAVBAR</div>
<div class="scrollable-content">
<p>Bla bla bla</p>
<p>Yadda yadda yadda</p>
<p>Mary had a little lamb</p>
<h2 id="stuff-i-want-to-link-to">Stuff</h2>
<p>More nonsense</p>
</div>
... and CSS like this:
.static-navbar {
height: 100px;
}
.scrollable-content {
position: absolute;
top: 100px;
bottom: 0;
overflow-y: scroll;
width: 100%;
}
There is one significant downside to this approach, however, which is that while an element from the page header is focused, the user will not be able to scroll the page using the keyboard (e.g. via the up and down arrows or the Page Up and Page Down keys).
Here's a JSFiddle demonstrating this in action.
This was inspired by the answer by Shouvik - same concept as his, only the size of the fixed header isn't hard coded. As long as your fixed header is in the first header node, this should "just work"
/*jslint browser: true, plusplus: true, regexp: true */
function anchorScroll(fragment) {
"use strict";
var amount, ttarget;
amount = $('header').height();
ttarget = $('#' + fragment);
$('html,body').animate({ scrollTop: ttarget.offset().top - amount }, 250);
return false;
}
function outsideToHash() {
"use strict";
var fragment;
if (window.location.hash) {
fragment = window.location.hash.substring(1);
anchorScroll(fragment);
}
}
function insideToHash(nnode) {
"use strict";
var fragment;
fragment = $(nnode).attr('href').substring(1);
anchorScroll(fragment);
}
$(document).ready(function () {
"use strict";
$("a[href^='#']").bind('click', function () {insideToHash(this); });
outsideToHash();
});
I'm facing this problem in a TYPO3 website, where all "Content Elements" are wrapped with something like:
<div id="c1234" class="contentElement">...</div>
and i changed the rendering so it renders like this:
<div id="c1234" class="anchor"></div>
<div class="contentElement">...</div>
And this CSS:
.anchor{
position: relative;
top: -50px;
}
The fixed topbar being 40px high, now the anchors work again and start 10px under the topbar.
Only drawback of this technique is you can no longer use :target.
Adding to Ziav's answer (with thanks to Alexander Savin), I need to be using the old-school <a name="...">...</a> as we're using <div id="...">...</div> for another purpose in our code. I had some display issues using display: inline-block -- the first line of every <p> element was turning out to be slightly right-indented (on both Webkit and Firefox browsers). I ended up trying other display values and display: table-caption works perfectly for me.
.anchor {
padding-top: 60px;
margin-top: -60px;
display: table-caption;
}
I added 40px-height .vspace element holding the anchor before each of my h1 elements.
<div class="vspace" id="gherkin"></div>
<div class="page-header">
<h1>Gherkin</h1>
</div>
In the CSS:
.vspace { height: 40px;}
It's working great and the space is not chocking.
how about hidden span tags with linkable IDs that provide the height of the navbar:
#head1 {
padding-top: 60px;
height: 0px;
visibility: hidden;
}
<span class="head1">somecontent</span>
<h5 id="headline1">This Headline is not obscured</h5>
heres the fiddle: http://jsfiddle.net/N6f2f/7
You can also add an anchor with follow attr:
(text-indent:-99999px;)
visibility: hidden;
position:absolute;
top:-80px;
and give the parent container a position relative.
Works perfect for me.
A further twist to the excellent answer from #Jan is to incorporate this into the #uberbar fixed header, which uses jQuery (or MooTools). (http://davidwalsh.name/persistent-header-opacity)
I've tweaked the code so the the top of the content is always below not under the fixed header and also added the anchors from #Jan again making sure that the anchors are always positioned below the fixed header.
The CSS:
#uberbar {
border-bottom:1px solid #0000cc;
position:fixed;
top:0;
left:0;
z-index:2000;
width:100%;
}
a.anchor {
display: block;
position: relative;
visibility: hidden;
}
The jQuery (including tweaks to both the #uberbar and the anchor approaches:
<script type="text/javascript">
$(document).ready(function() {
(function() {
//settings
var fadeSpeed = 200, fadeTo = 0.85, topDistance = 30;
var topbarME = function() { $('#uberbar').fadeTo(fadeSpeed,1); }, topbarML = function() { $('#uberbar').fadeTo(fadeSpeed,fadeTo); };
var inside = false;
//do
$(window).scroll(function() {
position = $(window).scrollTop();
if(position > topDistance && !inside) {
//add events
topbarML();
$('#uberbar').bind('mouseenter',topbarME);
$('#uberbar').bind('mouseleave',topbarML);
inside = true;
}
else if (position < topDistance){
topbarME();
$('#uberbar').unbind('mouseenter',topbarME);
$('#uberbar').unbind('mouseleave',topbarML);
inside = false;
}
});
$('#content').css({'margin-top': $('#uberbar').outerHeight(true)});
$('a.anchor').css({'top': - $('#uberbar').outerHeight(true)});
})();
});
</script>
And finally the HTML:
<div id="uberbar">
<!--CONTENT OF FIXED HEADER-->
</div>
....
<div id="content">
<!--MAIN CONTENT-->
....
<a class="anchor" id="anchor1"></a>
....
<a class="anchor" id="anchor2"></a>
....
</div>
Maybe this is useful to somebody who likes the #uberbar fading dixed header!
#AlexanderSavin's solution works great in WebKit browsers for me.
I additionally had to use :target pseudo-class which applies style to the selected anchor to adjust padding in FF, Opera & IE9:
a:target {
padding-top: 40px
}
Note that this style is not for Chrome / Safari so you'll probably have to use css-hacks, conditional comments etc.
Also I'd like to notice that Alexander's solution works due to the fact that targeted element is inline. If you don't want link you could simply change display property:
<div id="myanchor" style="display: inline">
<h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</div>
Here's the solution that we use on our site. Adjust the headerHeight variable to whatever your header height is. Add the js-scroll class to the anchor that should scroll on click.
// SCROLL ON CLICK
// --------------------------------------------------------------------------
$('.js-scroll').click(function(){
var headerHeight = 60;
$('html, body').animate({
scrollTop: $( $.attr(this, 'href') ).offset().top - headerHeight
}, 500);
return false;
});
I ran into this same issue and ended up handling the click events manually, like:
$('#mynav a').click(() ->
$('html, body').animate({
scrollTop: $($(this).attr('href')).offset().top - 40
}, 200
return false
)
Scroll animation optional, of course.

Categories