got a question here. I have a very simple polymer-element that taking a series of <a> anchor tags inside it (the Light-DOM), it creates some kind of navigation bar. So my simple solution consists in to get access to the Light-DOM (from the polymer-element) to know how many anchors the user put in there and also get some information that i need for generate the thing in a template as follows:
<!-- this is the polymer-element -->
<polymer-element name='x-nav' >
<template>
<style>
a {color: blue;}
li{display: inline-block;}
</style>
<nav>
<ul>
<template repeat="{{links}}">
<li>
{{innerHTML}}
</li>
</template>
</ul>
</nav>
</template>
<script>
Polymer('x-nav', {
ready: function(){
this.links = [];
for(var i = 0; i < this.children.length; i++){
this.links.push(this.children[i]);
}
}
});
</script>
</polymer-element>
<!-- this is the implementation in the Light-DOM -->
<x-nav>
<a href='/hone'>home</a>
<a href='/about'>about</a>
<a href='/contact'>contact</a>
</x-nav>
The question is that I really dont know if this is a good approach or if there are a better way or "best practices" to accomplish this kind of stuff, when we want to create customizable elements and we dont know what or how many tags the user will put in the ligh-dom side. Thanks! :D
That seems fairly reasonable to me and should work fine, so long as the <x-nav>'s links are static.
Two things of note, rather than this.children you could try this.querySelectorAll('a') to be sure that you only get the 'a' nodes.
You could also look into using <content select='a'></content> as that's responsive to changes in the x-nav's light dom, but I don't know of a way to put each anchor in a separate <li> with <content>. It's possible that <content select='a[nth-child({{idx}})]'></content> would work, requiring you to only keep track of how many anchors are in the light dom.
Related
I've recently started using the <template> tag for HTML that I process afterwards using a template library, e.g.
<template id="tmpl">
<div class="something">
{{title}}
</div>
</template>
...
<script>
var output = Mustache.render($('#tmpl').html(), {
link: 'abc',
title: 'abc'
});
</script>
However, I've come to realise this means I have a broken link (example.com/pages/{{link}}) in my HTML. This is a concern, as various crawlers might consider it invalid (in fact, the Google Search Console reports my homepage as having a broken link).
Is it valid to use <template> this way?
Is it better to put it in something like <script type="text/template"> instead (as seen on the handlebars.js website)?
The output variable does contain the HTML we would expect, i.e., the rendered template; however, your code does not write the contents of the output variable anywhere.
Here is a working example:
<template id="tmpl">
<div class="something">
{{title}}
</div>
</template>
<span id="output"></span>
<script>
var output = Mustache.render($('#tmpl').html(), {
link: 'abc',
title: 'abc'
});
$('#output').html(output);
</script>
Google has not properly crawled the test site I setup for this. However, when I asked GoogleBot to render my version of your code it displayed the link inside the template element, i.e., *{{title}}* and the rendered template link, i.e., *abc*. Even though Google says you have a broken link in the template element, you really don't when a user views it.
One possible way to get Google to quit indicating that you have a broken link is to surround your template tags with <!--googleoff: anchor--> ...templates... <!--googleon: anchor-->. These tags stop googlebot from indexing anchor tags contained within.
Example:
<!--googleoff: anchor-->
<template id="tmpl">
<div class="something">
{{title}}
</div>
</template>
<!--googleon: anchor-->
I would like to create a tooltip containing an unodered list using bootstrap v2.3.2. I am currently using the following html as the content of the tooltip:
<p align='left'><b>This alert would have fired:</b></p>
<ul align='left'>
<li align='left'>1 time in the past week</li>
<li align='left'>8 times in the past two weeks</li>
<li align='left'>20 times in the past month</li>
</ul>
The current output looks like this:
I would like the 3 list items to be bulleted and have the natural indent of an unordered list but for some reason the tooltip does not behave like this. I am relatively new to html and css so please assume very little css and bootstrap knowledge in any explanations. I will create css classes for this once I have it working correctly so please be easy on my bad practices (if I have any) but do point them out.
Tooltips aren't really designed for displaying HTML code within them (unless you use a tooltip plug-in like Tooltipster (http://iamceege.github.io/tooltipster/). I would think of a more clever way to incoporate what you want displayed onto the page without using a tooltip. I put some code below which is easy to read, that shows the error of trying to use HTML within a tooltip.
<!doctype html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
</head>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<body>
<p align='left' data-toggle="tooltip" title = "'<br>'One'<br>'Two">This alert would have fired:</p>
</body>
<script>
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
</script>
Edit: Here's a good reference on Bootstrap's tooltips. Nothing wrong with saying you're "new" to web development by the way. We all have to start somewhere :-)
-> http://www.w3schools.com/bootstrap/bootstrap_tooltip.asp
I should have specified that this is a polymer question and not native HTML.
I have a template like this
<template>
<a href="{{ href }}">
<content></content>
</a>
</template>
When I hover over the custom element my cursor iscursor:text and not cursor:pointer, this is an easy fix to apply cursor pointer, but I feel as if those kind of properties should be inherited. Is there any way to apply the content and inherit the a properties properly?
Example on jsfiddle here
Update: 1
An even bigger issue with this is that you can't right-click and select copy-link either.
Update: 2
I kind of think I get it now, <content> isn't being passed a height or width, so the outer most element (the custom one) is height 0, width 0. So the anchor has no room to expand. Hence the cursor isn't switching.
tried, no luck
::content * {
width:inherit;
height:inherit;
}
Update 3
This kinda worked.
I had to give the anchor a id=anchor and use jQuery.
$(this.$.anchor).append($(this).html());
This won't import font-awesome icons for some reason, where does.
Perhaps it's because it's not importing over the styles when I grab the HTML?
There's no error in the console either.
I dropped the to font-awesome within the polymer template and it worked, which is kind of crappy. Need a better solution.
This is a bug with Chrome's current implementation of Shadow DOM that will be fixed in Chrome 37.
You have nothing to make a link out of; you're "linkifying" an empty block.
If you give <content> some innards, you'll see the inherited style:
<template>
<a href="{{ href }}">
<content> Here is a link. </content>
</a>
</template>
Example Fiddle
I have no idea how you're actually using this element, but http://jsbin.com/qaqigizajuvi/1/edit is a simple example of how to make at least what I think you're trying to achieve, work.
If you're using {{ name }} macros, you'll need to declare attributes for each name that you use. There's also no point in a <content> block if you just want a linktext: use another attribute macro in your definition:
<polymer-element name="monkey-test" attributes="href label" noscript>
<template>
{{ label }}
</template>
</polymer-element>
and then instantiate it as either:
<monkey-test href="http://example.org" label="tadah"></monkey-test>
or set up a <monkey-test> element and then set its href and label attributes via JavaScript using e.href=... and e.label=... or e.setAttribute(name, value)
note that the noscript attribute is used here because there's no explicit script block with a new Polymer('monkey-test', { ... }) call. If we want a more complex element, we can't get away with noscript.
I'm in the process of marking up a site and I've been really trying to hone my accessibility skills. I'm wondering what the most semantic mark-up is for tabbed content. This is what I have now:
<section>
<nav>
Stuff
Stuff
Stuff
</nav>
<section id="content" aria-live="polite" role="region">
<article>...</article>
<article>...</article>
<article>...</article>
</section>
</section>
I have a few specific questions about this.
Am I on the right track? If not can someone recommend some changes?
Will I need to make changes if I were to load in the articles via AJAX?
Do I need the nav tag?
Are WAI-ARIA roles enough here?
Are these the correct WAI-ARIA roles to use?
1.Am I on the right track? If not can someone recommend some changes?
Yes, you've absolutely started in a good way. Some of the tab stuff could be given some tab-related roles if you want to improve it, but it's functional as is.
2.Will I need to make changes if I were to load in the articles via AJAX?
No. It should be fine. The fact that it is a live region should (tested with NVDA only) mean that new content is announced. Is this the behaviour you're after?
3.Do I need the nav tag?
No, but I think it helps make it crystal clear what that bit of the document is for. A note though, that if you do what I've done below and mark it as a tablist, the fact that it's a navigation element doesn't get announced anymore.
4.Are WAI-ARIA roles enough here?
If by ARIA roles you're also including states and properties, yes essentially you should be covered for loading dynamic content (if that's what you're after). There's no case for moving the user's keyboard focus or anything with things as they are. IMO, you'd only really want to do that if there's a lot of navigational stuff between what the user clicked and what content you're giving them.
5.Are these the correct WAI-ARIA roles to use?
You're not far off. If you really want a tab-style experience, then you need the tablist, tab and tabpanel roles. I'll give an example.
I've taken your code and made a contrived but working example to test it. It's not loading anything in AJAX, just showing and hiding stuff. I wanted to be sure before I gave this answer, but I'll put the code here too in case it helps.
<html>
<head>
<title>Aria test</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('nav a').on('click', function () {
hideArticles();
deslectAllTabs();
$(this).attr('aria-selected', true);
var tab = '#' + $(this).attr('aria-controls');
$(tab).show();
});
});
function hideArticles() {
$('article').hide();
}
function deslectAllTabs() {
$('nav a').attr('aria-selected', false);
}
</script>
<style type="text/css">
article { display: none; }
</style>
</head>
<body>
<section>
<nav role="tablist">
Stuff1
Stuff2
Stuff3
</nav>
<section id="content" aria-live="polite" role="region">
<article id="content1" role="tabpanel">The lazy dog jumped over the quick fox</article>
<article id="content2" role="tabpanel">If you click this tab then your life will be better</article>
<article id="content3" role="tabpanel">Know your roles</article>
</section>
</section>
</body>
</html>
I hope this helps.
Semantics tend to get vague at this level, but yeah I think you're on the right track as long as each of the tabs would really count as a separate article.
The article element represents a component of a page that consists of a self-contained composition in a document, page, application, or site and that is intended to be independently distributable or reusable, e.g. in syndication. This could be a forum post, a magazine or newspaper article, a blog entry, a user-submitted comment, an interactive widget or gadget, or any other independent item of content.
Source
I don't think the <nav> is misplaced here, although it depends on how important the different tabs are in regards to the whole of your website:
The nav element represents a section of a page that links to other pages or to parts within the page: a section with navigation links. Not all groups of links on a page need to be in a nav element only sections that consist of major navigation blocks are appropriate for the nav element. In particular, it is common for footers to have a list of links to various key parts of a site, but the footer element is more appropriate in such cases, and no nav element is necessary for those links.
Source
I wouldn't use sections to wrap the stuff in it though.
The section element is not a generic container element. When an element is needed only for styling purposes or as a convenience for scripting, authors are encouraged to use the div element instead. A general rule is that the section element is appropriate only if the element's contents would be listed explicitly in the document's outline.
Source
An additional rule of fist for the <section> element is that they should have a title. If not, it's probably not really a "section" but just a group of elements that you needed to wrap in something, so just use a <div>.
I need to store some hidden HTML for each li element. What's the best way to do this?
I've tried storing it as data on each li element but the hidden HTML tags screw up the li element.
I've managed to do it by storing the data in a hidden text area for each li.
Is this the best way to do it? Or is there a better way.
I'm storing around 200 chars.
Put your hidden HTML in a div / span with a CSS class that has:
display: none;
See the display property.
You can put a hidden field at each li to put the data! I think that hidden fields will work well, and theres no limit for the amount of data.
<input type="hidden" id="myId" value="value here pls..." />
Hopes this help you!
<input type="hidden" value="your hidden stuff here" />
Is your data HTML or is it content? Do you need it for programatic reasons? If it's just a matter of hiding content, as you would for a screen reader when using image-swap, for example, use css:
#my_content {
text-indent: -9999px;
}
Beyond that you could use hidden form fields, or simply use CSS to hide the element entirely.
try this
<div style="display:none;">your html here.....</div>
One way I've recently learned to do this is to use <script> tags. You can add an ID to the script tag, and reference in javascript using that ID to fetch the content and do something with it. I use this for inline templates.
http://www.bennadel.com/blog/2411-Using-Underscore-js-Templates-To-Render-HTML-Partials.htm
<script id="foo" type="text/template">
<p>your text here</p>
</script>
now in real javascript:
<script type="text/javascript">
<!-- assume jquery for the sake of assuming something -->
$(function() {
fooTemplate = $("#foo").clone();
$("#target").append(fooTemplate);
});
</script>
I created a fiddle, but I had to use a div in the HTML area because fiddle doesn't like having an extra script node... The principle is the same -- just change to script in your html in your page.
If your <li> are children of an <ol> element and values you want to store are integers, then you can store them as
<li value="11">DISPLAY ITEM</li>
another approach:
if you want your extra HTML DATA to be present, but you don't want to render it at all (i assume this because you said that you tried to hide them inside a textarea -and thats why im posting this answer) then why not just put it inside comments?
<li> your code....
<!--
<div>my hidden html code of this li, of course i won't have nested comments in here!!!</div>
-->
</li>
Of course this is tricky, and not easy to get this data, but if you need this just for debug it will be ok.
Otherwise i'm in favor of display:none in a wrapped div.
Captain Obvious.
Here are two methods not mentioned in other answers.
The advantage of both methods is that, when you're working in your HTML programming environment, you get normal syntax coloring and error-checking.
Method 1
<template>
<div>Here's my hidden HTML.</div>
</template>
Method 2
<span hidden>
<div>Here's my hidden HTML.</div>
</span>