Skip to content
View in the app

A better way to browse. Learn more.

Web Designer Forum

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

HTML5 Anchor - Name tag doesn't pass W3C Validator

Featured Replies

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?

  • Author

It does work, but when I pass it through W3C Validator as it currently is I get the following warning.

 

warning.png 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.

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 by BrowserBugs

  • 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 by Demonolith

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.

  • 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 -->

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.

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 by Nillervision

  • 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?

    $('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 by Nillervision

  • 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.

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 by Nillervision

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 by rbrtsmith

  • 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?

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 by rbrtsmith

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.

  • 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;
}

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 by rbrtsmith

  • 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?

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.

  • Author

Is it better to stop using pixels as a unit altogether (line-height, font-size, letter-spacing, margin, padding etc.)?

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.

 

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.

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 by rbrtsmith

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.