November 16, 201411 yr I'm changing a site from <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> to <!DOCTYPE html> I understand that I must remove the name tag from an anchor so that it validates properly through W3C Validator, but in doing so it the anchor ceases to work. Following guidelines I changed my code from <a name="topofpage id="topofpage"></a> <div class="pagetop"><a href="#topofpage">PAGE TOP <sup>▲</sup></a></div> to <h1 id="topofpage"></h1> <div class="pagetop"><a href="#topofpage">PAGE TOP <sup>▲</sup></a></div> Here is the page itself (code on line 75 and 119). Why is this not working for me?
November 17, 201411 yr Author It does work, but when I pass it through W3C Validator as it currently is I get the following warning. Line 85, Column 35: The name attribute is obsolete. Consider putting an id attribute on the nearest container instead.<a name="topofpage" id="topofpage"></a> Sorry, I should have clarified that that was the issue in my original post.
November 17, 201411 yr Ah you only need an id for an anchor point; keep the id and lose the name attribute. <a id="topofpage"></a> <!-- or for a div --> <div id="topofpage">Content in here</div> <!-- or for a heading --> <h1 id="topofpage">Title</h1> Edited November 17, 201411 yr by BrowserBugs
November 17, 201411 yr Author When I make that change the page validates fine, but clicking on one a 'PAGE TOP' link no longer works. I'll leave it that way for now to demonstrate. Edited November 17, 201411 yr by Demonolith
November 17, 201411 yr Try removing that "scripts/smooth.pack.js" script. I think it's trying to do the job and possibly causing issues. You can find plugins that do the same job and probably work better, if you need the animation at all.
November 17, 201411 yr Author Thanks Skateside, I've swapped that script with the following and it now works fine - the replacement is a little bulky, but it works, <script> // Smooth scroll for in page links - http://wibblystuff.blogspot.in/2014/04/in-page-smooth-scroll-using-css3.html // Improvements from - http://codepen.io/kayhadrin/pen/KbalA $(function() { var $window = $(window), $document = $(document), transitionSupported = typeof document.body.style.transitionProperty === "string", // detect CSS transition support scrollTime = 1; // scroll time in seconds $("a[href*=#]:not([href=#])").on("click", function(e) { var target, avail, scroll, deltaScroll; if (location.pathname.replace(/^\//, "") == this.pathname.replace(/^\//, "") && location.hostname == this.hostname) { target = $(this.hash); target = target.length ? target : $("[id=" + this.hash.slice(1) + "]"); if (target.length) { avail = $document.height() - $window.height(); if (avail > 0) { scroll = target.offset().top; if (scroll > avail) { scroll = avail; } } else { scroll = 0; } deltaScroll = $window.scrollTop() - scroll; // if we don't have to scroll because we're already at the right scrolling level, if (!deltaScroll) { return; // do nothing } e.preventDefault(); if (transitionSupported) { $("html").css({ "margin-top": deltaScroll + "px", "transition": scrollTime + "s ease-in-out" }).data("transitioning", scroll); } else { $("html, body").stop(true, true) // stop potential other jQuery animation (assuming we're the only one doing it) .animate({ scrollTop: scroll + "px" }, scrollTime * 1000); return; } } } }); if (transitionSupported) { $("html").on("transitionend webkitTransitionEnd msTransitionEnd oTransitionEnd", function(e) { var $this = $(this), scroll = $this.data("transitioning"); if (e.target === e.currentTarget && scroll) { $this.removeAttr("style").removeData("transitioning"); $("html, body").scrollTop(scroll); } }); } }); //@ sourceURL=pen.js </script><!-- Smooth Scroll -->
November 17, 201411 yr Woh! That's a lot of code mate for a 'top' scroller! Anchor points work regardless of plugins, thus it must be the plugin. Here's a simple version if you're running jquery; <script> $(document).ready(function(){ $(".totop").click(function (){ $("html, body").animate({scrollTop:0}, "slow"); return false; }); }); </script> and html <div class="pagetop"><a href="#topofpage" class="totop">PAGE TOP <sup>▲</sup></a></div> and the best bit is no js it will still jump to the top.
November 17, 201411 yr The reason that the script is so long is beause it will work scroll to ANY linked id even when accessed from a link* from another page. But if you only need to scroll to the top on the same page then go with BrowserBugs' solution. *with the id in the url Edited November 17, 201411 yr by Nillervision
November 18, 201411 yr Author Thanks Nillervision and BrowserBugs, that works great. Should I be overly concerned with how clicking to go to the top of the page adds #topofpage to the URL?
November 18, 201411 yr Nope, although some search engines treat the id of an element as a content marker of sorts it's not a true path like www.domain.com/?topofpage and wouldn't be treated as a separate page.
November 18, 201411 yr $('html, body').animate({ scrollTop: $("#target-element").offset().top }, 1000); Not my code I stole it from here: http://www.abeautifulsite.net/smoothly-scroll-to-an-element-without-a-jquery-plugin-2/ EDIT: Sorry THIS is what you want (from the same article) $('a[href^="#"]').on('click', function(event) { var target = $(this.href); if( target.length ) { event.preventDefault(); $('html, body').animate({ scrollTop: target.offset().top }, 1000); } }); See how it uses the href attribute instead of the name attribute so your markup will be valid ANOTHER EDIT: You can use this script to handle your top scrolling as well if your top element has an id. If you choose to use both scripts (this one and browserbugs') you must target a classname instead of just all links with # in their href ( 'a[href^=#] ) as the scripts would force the browser to scroll two times in different directions otherwise. Edited November 18, 201411 yr by Nillervision
November 18, 201411 yr Author I've tried that code exclusively Nillervision, but now I get no smooth scroll and items don't jump to the right place - have I inserted the code wrong? <script> $('a[href^="#"]').on('click', function(event) { var target = $( $(this).attr('href') ); if( target.length ) { event.preventDefault(); $('html, body').animate({ scrollTop: target.offset().top }, 1000); } }); </script><!-- Smooth Scroll --> <a href="#frjquinn" id="frjquinn">FR. J. QUINN</a> • <a id="frjquinn"></a> Here's the page - I've only changed the first row of the menu for now.
November 19, 201411 yr I'm not absolutly sure what causes it (I don't get any errors in the console) but I think it might be because you are executing the script before any page elements has been rendered so when the script loops through the page it will not find any link-elements to target because they havent been rendered to the page yet. If this is what causes the problem its easy to fix: Just wrap the script in a window.onload or $(document).ready function. Then the code will not be executed before the page has loaded. You allready have a $(document).ready function declared in which you call fancybox in line 12. you could try to move the scroll code into that function and see what happens. EDIT: Alternatively you could move the script to the bottom of the page just before the closing body tag. That way the script should first execute after the page elements has been created Edited November 19, 201411 yr by Nillervision
November 19, 201411 yr First when some javascript isn't working, open up your dev tools console and see if there are errors, if there are it can quickly point you to your problem. Like jQuery not being defiend means you're not loading in jQuery before the script executes, if a particular dom element is not defined then it's likely that your niot wrapping your code inside of the document ready event. $(document).ready(function(){ // code. }); Also make sure the $ symbol has been aliased to jQuery, you can do it like this --> (function($) { $(document).ready(function(){ // code }); }(jQuery)); If it wasn't aliased your console would tell you that $ is undefined or not a function. Other useful things include the console.log(); method, you can use this to log information to the console at run-time, you can check variable values and so forth. It would be very difficult to build JavaScript applications without the console. To take things further all the custom code I write gets assigned to a single global object. The function I have above only creates local variables but because of closure you cannot call these functions from outside of the block. to be able to do this you create a global object then assign the functions as methods to it. var GLOBALOBJECT = {}; (function($) { $(document).ready(function(){ GLOBALOBJECT.smoothScroll = { init: function() { // code } }; GLOBALOBJECT.smoothScroll.init(); // call function locally here }); }(jQuery)); GLOBALOBJECT.smoothScroll.init(); // can call it here also. This is very important if you are building a larger application and you don't want conflicting variables. Especially if run 3rd party plugins. Edited November 19, 201411 yr by rbrtsmith
November 19, 201411 yr Author Thanks guys, I've added the following script and it now works. <script> (function($) { $( document ).ready(function() { $('a[href^="#"]').on('click', function(event) { var target = $( $(this).attr('href') ); if( target.length ) { event.preventDefault(); $('html, body').animate({ scrollTop: target.offset().top }, 1000); } }); }); }(jQuery)); </script><!-- Smooth Scroll --> However, is there a way to make the scroll move more fluidly by slowing it down as it begins / ends a scroll? I don't quite follow what you are saying about the dev tools console rbrtsmith - how can I access it?
November 19, 201411 yr Assuming you are using chrome, which, at the moment has the best developer tools: right click on your webpage->inspect-element. Then click on the console tab. I recommend you google for some chrome developer tools tutorials it's well worth knowing them. As regarding to the scrolling animation what you are looking for is an easing function. $('html, body').animate({ scrollTop: target.offset().top }, 1000, 'linear'); Here you see the 3rd parameter being passed to the animate function is the string 'linear' The default for jQuery animate is 'swing'. If you want more control over this then you need to look into something like jQuery UI which has a load more easing parameters. Also noticing your <script> tags in your code -- don't emebed js directly into your html files, link to an external js file instead. Edited November 19, 201411 yr by rbrtsmith
November 19, 201411 yr Glad you got it to work Like rbrtsmith said: The easing type will handle how the animation accelerates. "Liniar" should just be a straight animation "curve". Also you can play with the time parameter "1000" is equal to 1 sec. and might be a bit slow.
November 19, 201411 yr Author Thanks again, tried out the 'linear' with differing time parameters and concluded that what it originally was suited best! I seem to be having an issue on one page with spacing between lines. If I use <!DOCTYPE html> the spacing between the name and year is to wide whereas if I use <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> it appears as it should. I've illustrated this issue in the attachment. <div class="priestswrapper"> <a href="#frgnelson" id="gnelson"></a> <img style="float: left;" src="images/history/parish-priests/frgeoergenelson.png" width="155" height="226" alt="Fr. George Nelson" /> <div class="priestdetailswrapper"> <div class="priestname">FR. GEORGE NELSON<br /> <span style="font-size: 25px; line-height: 20px;">1892</span></div> <div class="priestdetails"> <strong>Born: </strong>1845 in Cardonagh, Donegal <div class="parishpriestsspacer"></div> <strong>Ordained: </strong>1871 in Sessions, France <div class="parishpriestsspacer"></div> <strong>Died: </strong>23<sup>rd</sup> February, 1920 in Carncorn<br /> (Castlederg Parish) </div> <!-- priestsdetails --> </div> <!-- priestdetailswrapper --> </div> <!-- priestwrapper --> <div class="pagetop"><a href="#topofpage" id="totop">PAGE TOP <sup>▲</sup></a></div> .parishpriestsspacer { height: 10px; } .priestswrapper { width: 600px; margin: 30px 0 0 82px; } .priestdetailswrapper { width: 420px; float: left; } .priestname { font-family: Oswald, "Arial Black", Gadget, sans-serif; font-size: 31px; letter-spacing: 1px; margin-top: 10px; color: #FFF; background: #575974; padding: 0 10px 9px 10px; } .priestdetails { font-family: 'arialnarrow', 'Arial Narrow', Arial, sans-serif; font-size: 18px; float: left; line-height: 18px; margin: 10px 0 0 10px; }
November 20, 201411 yr Don't use the old xhtml doctypes, they're well outdated now. go with the html5 declaration <!DOCTYPE html> as for spacing between your lines of text that is merely the line-height property. body { line-height: 1.45; } I find somewhere between 1.4 and 1.6 reads best, but ultimately it depends on the font. Don't use pixels on line height unless you are attempting to center a single line of text inside a container, in which case using display:table would be better in case the line of text breaks into two lines at smaller viewports. Edited November 20, 201411 yr by rbrtsmith
November 20, 201411 yr Author Thanks rbrtsmith, I added the following CSS: .priestyear { font-size: 25px; line-height: 0.8; } And replaced <span style="font-size: 25px; line-height: 0.25;">1892</span> with <div class="priestyear">1892</div></div> Why is it preferable not to use pixels when it comes to line-height?
November 20, 201411 yr Because for readability the distance between the lines of text should be directly related to the font size. when you put in no units then the line height will be that number x the font size. If you put pixels that distance is the same even if you go for a much larger font size.
November 21, 201411 yr or if someone resizes the font in their browser (the line height - or leading in the print world - will remain the same)
November 22, 201411 yr Author Is it better to stop using pixels as a unit altogether (line-height, font-size, letter-spacing, margin, padding etc.)?
November 22, 201411 yr Is it better to stop using pixels as a unit altogether (line-height, font-size, letter-spacing, margin, padding etc.)? Pixels have their place when you explicitly want something to be that size. I use them often, you use different units under different situations, there's no one rule fits all. For spacing units like margins and padding that is directly related to textual content I would go with EMs or REMs. Even in responsive sites there are often areas that have fixed pixel widths so in these cases I use pixels.
November 24, 201411 yr Pixels have their place when you explicitly want something to be that size. I use them often, you use different units under different situations, there's no one rule fits all. For spacing units like margins and padding that is directly related to textual content I would go with EMs or REMs. Even in responsive sites there are often areas that have fixed pixel widths so in these cases I use pixels. I agree with Robert but would just add that I like to use rem for top/bottom margin/padding and % for left/right on block elements. I would not use % for top/button because all the heights of the page usually depends on the amount of content, which will differ from page to page. So % units for top/bottom relative to parent elements height is not very useful.
November 24, 201411 yr I agree with Robert but would just add that I like to use rem for top/bottom margin/padding and % for left/right on block elements. I would not use % for top/button because all the heights of the page usually depends on the amount of content, which will differ from page to page. So % units for top/bottom relative to parent elements height is not very useful. I too agree that % are rarely useful for heights, other than some edge case scenarios. However I make use of all the measurement units when it comes to width, it really depends what I am trying to create. If I want a fixed width block on the left and a fluid container to the right taking up the remaining space I wouldn't actually need to use any percentage widths thanks to one of the side effects of overflow: hidden http://jsfiddle.net/oLqcvdx0/1/ In conclusion it all depends on the scenario. What matters is that the solution you go with in that particular scenario should respond well to all screen sizes and be flexible in terms of the content that is input. You should also be able to nest further things inside if you follow the oocss principles, like the example I put up you can easily nest more of these blocks inside of one another as you see in the second block of my example above. Edited November 24, 201411 yr by rbrtsmith
Create an account or sign in to comment