I have the following HTML:
<ul class='dropSelect'>
<li data-value="one">
<span>Menu1</span>
</li>
<li data-value="two">
<span>Menu2</span>
</li>
<li data-value="three">
<span>Menu3</span>
</li>
</ul>
My question is: is it better practice to place the data-value attribute on the span next to the actual menu item text or is it just as good to place on the parent li element as I have done? This attribute will receive data from a web service and I'm using some js to grab the value of this attribute and placing it inside of another element on the page.
SOF warned me upon posting this question that it might be too subjective ... and it might be ... but my concern is to understand what, if any, impact my placement of this attribute may have on UI engineering, javascript DOM manipulation, accessibility, etc.
Broadly speaking, I suggest storing data on the element that most closely maps to the data's 'parent' or 'owner'. It's all about what conveys the most meaning.
For example, if you are representing a list of 'people' in your html thus
<ul>
<li class="person">Tim Bresnan</li>
<li class="person">Joe Root</li>
</ul>
and you wish to associate a date of birth without displaying it, put it on the li items as they represent the person.
$('.person').data('dob');
If however your html representation of a person is more complex, say
<ul>
<li class="person">
<div class="name">Tim Bresnan</div>
<div class="dob">28th Feb 1985</div>
</li>
<li class="person">
<div class="name">Joe Root</div>
<div class="dob">30th Dec 1990</div>
</li>
</ul>
you might wish to include the ISO8601 datetime representation as data on the dob class elements.
$('.person .dob').data('dob');
Although html5 data attributes are subjective, and can be used anytime/anywhere, I'm assuming you are looking these elements up by them in your situation. In your situation I'd put them in the same place you did for a couple of reasons.
This is the top level (child), so it's very easy to grab them all by the data attribute.
$('li[data-value]')
At some point you might have much more inside each <li>, right now it might only be the <span> but by having the list-item hold the data-value you can easily get other DOM elements inside of it. If you had it inside of the span you'd have to go UP a level to the list-item, then .find() whatever element you want.
If your span held data-value:
$('[data-value="whatever"]').closest('li').find('.someOtherThing');
Instead now you don't have to do that pointless look-up for the parent <li>!
$('[data-value="whatever"]').find('.someOtherThing');
I would say to put the data-values in the span within the listing. I think it's best to put the data-attribute closest to the string it has an effect on, in this case the span.
On another note, this piece of jQuery works fine:
$(document).ready( function() {
$("li").click(function(){
var txt = $(this).text();
$("#mydiv").text(txt);
});
});
With this, I've tested in jsFiddle (http://jsfiddle.net/YqePE/) that clicking on a li, can return it's text value, and so it would also return any data-attribute you have in that li.
BUT, if by some sort of weird CSS makeup, it can be possible this would generate an unwelcome outcome, where as you think you don't click a certain LI, the browser thinks you do. To prevent this, you would want to make the span holding the data-attribute.
From what it seems like you're trying to do. You could use jQuery's .index(). (Yes, I know it wasn't tagged jQuery)
$('ul.dropSelect > li').each(function(){
var i = $(this).index();
});
It is not necessary to use the data attribute for this information.
Try to use pseudo class selectors of CSS or jQuery to bind the specif item:
CSS:
.dropSelect li:nth-child(1) {
// First <li>
}
Or jQuery:
// Second <li>
$('.dropSelect li').eq(1)
DEMO: http://jsfiddle.net/wYpK6/
Related
Trying to determine the correct syntax for using Microdata inside my breadcumbs implementation. Everything I have read seems to lean towards the fact that the breadcrumbs are structured inside an ordered or unorderd list. Mine is not.
<body itemscope="" itemtype="http://schema.org/WebPage">
...
<div class="breadcrumbs" itemprop="breadcrumb">
Home
<span class="delimiter"> > </span>
Parent Item
<span class="delimiter"> > </span>
<span>Child</span>
</div>
...
</body>
If I run it inside Google's tool it seems correct, but compared to their example it is missing a lot of elements and doesn't have the structure of their example BreadcrumbList.
I'm also a little confused about the correct properties for the links. Should they all have title and url properties?
I was looking at the examples at the bottom of the page here: http://schema.org/WebPage
The breadcrumb property expects one of two values:
Text
BreadcrumbList
If you provide a Text value (like you do in the example), you can’t provide data about each link. If you are fine with that, the Microdata in your example is correct (but it also contains RDFa, which doesn’t seem to make sense, at least not without further context; so if you didn’t add them intentionally, you might want to remove the property attributes).
If you want to provide data about each link, you have to provide a BreadcrumbList value.
For the Microdata, it doesn’t matter whether or not you use a list. If the example uses ol→li→a→span, you could as well use something like div→span→a→span. You just have to make sure to use the correct element type.
If you can’t add parent elements to the a elements, it’s still possible to use BreadcrumbList. But then you would have to duplicate the URL with a link element inside the a element.
Is there any difference between identifying an HTML element by class/id or by a custom attribute?
I mean, for example, if I have a menu and I want to change the color of the current (active) li element, I currently use this:
<style>
li[active]{color:red}
</style>
<ul>
<li active>...</li>
<li>...</li>
</ul>
But the most common usage is:
<style>
li.active{color:red}
</style>
<ul>
<li class="active">...</li>
<li>...</li>
</ul>
So what is the difference between them? I mean, they have the same result, but why don't people use the first method I wrote? That is much more simple and results in cleaner HTML source code.
Just for those who don't get the question... The first snippet I wrote is identifying an element BY HTML5 ATTRIBUTE. The second snippet is identifying an element BY CLASS.
So the question again: What's the difference between identifying an HTML element by HTML5 ATTRIBUTE and CLASS OR ID NAME?
Your active attribute example is invalid HTML, although it will usually (always?) work in practice because CSS is a separate spec that doesn't care about HTML's rules, and browsers try to do "what you mean" when it comes to invalid HTML.
Custom attributes should start with the data- prefix per the spec. These data attributes are usually used for associating an element with some extra data for use with JavaScript, although it's also possible to target them with CSS.
Technically, you could do something like
<li data-active="yeppers">
And then target it with CSS:
li[data-active='yeppers'] { ... }
However, that would be highly unusual and annoying for most anyone who had to look at your code.
Semantically, "active" isn't really data, and it's not necessarily unique to one element, so assigning class="active" makes the most sense.
I have 4 elements "Block" "button1" "button2" and "label".
I want the block to have the buttons inside it by CSS. this can be done by HTML like this :
<b class = "block">
<g class="Label"> </g>
<a class="button1"> </a>
<a class="button2"> </a>
</b>
but it'll take so much space if done 50 times in one page.
and I want a way to change button1,2 'href' with as less a possible lines of code.
CSS is meant to modify the appearance of a page, and not to be used for adding content - although pseudo-elements like :before and :after are commonly used for decorative purposes (e.g. adding arrows, or for layout hacks)
Have you considered using a JS-based method? You can loop through all the .block elements and then insert the label and buttons in each of them.
An example of a JS-based method would be: (assuming that you're using jQuery)
$(document).ready(function() {
$(".block").each(function() {
// Create elements to append
var apnd = '<element></element>';
// Append the created elements
$(apnd).appendTo($(this));
});
});
The only way I can think to achieve this would be use a parameterised jQuery function that adds or modifies the "href" value of each button of a given CSS class (with minor variations of the assigned href based on a given parameter - if that suits).
Sorry, to directly address the question, I agree with the other posters in that this can't be achieved using CSS alone.
I have a custom styled drop-down selection box created with CSS/Javascript, which is meant to imitate a <select> element. The box is a <div> with an internal list composed of <li> elements, which mirror the <option> elements of a standard select box.
Now, a standard select <option> element has two important components: the internal text node, which is what is actually displayed onscreen in the drop-down, and a value attribute which is the string that indicates the value of the selection (for use with form submissions or Javascript).
With my custom box, the text node inside the <li> element mirrors the internal text node in an <option> element. But how should I mirror the "value" attribute? According to w3schools (not the best resource, I know), the LI element has a "value" attribute which can be used, but it is deprecated in favor of CSS styling. But what CSS attribute can be used to indicate the "value" of the List Element? Or is there some better way to associate a value with an LI element?
Any attribute starting with "data-" is valid html nowadays. So you could do something like:
<ul>
<li data-value="1">Option #1</li>
<li data-value="754">Option #2</li>
</ul>
That way you could easily access your value for each option at a later stage.
You should use HTML5 data-* attributes any time you need to store arbitrary data on an element:
<li data-value="something">Some text</li>
Side note:
The box is a <div> with an internal list composed of <li> elements
I hope you have a ul (or ol, or menu) element as a parent of those li elements!
"But what CSS attribute can be use" No CSS-attribute, as there are only HTML-attributes.
To store any data on any element you may use the data-*-attributes, for example <li data-value="some value">.
According to HTML5 standart you should use data-* attributes
<li data-value="value">Text here</li>
I have a question about how to present some structured data using HTML.
I have some tree-like data, which you might normally present using sections and subsections (i.e. <h1>, <h2>, etc.) and/or using nested lists (i.e. lists whose items contain lists of sub-items).
An example of this data is a to-do list, which has tasks that include sub-tasks and sub-sub-tasks.
Each of these data also has associated properties, for example:
bool completed;
DateTime completionDate;
Priority priority;
My question is, what do you suggest as a good way to present this data on one page, using HTML?
My first idea is to present it as a table:
One of the table's columns shows the task or sub-task
Other columns in each row show the values of the properties (e.g. "completed", etc.) associated with that task
My problem with this is that showing all tasks and sub-tasks in one table column would lose the information about how the tasks are nested: for example it wouldn't show that the second row is actually a subtask of the first row. Can you suggest a way to work-around that problem? I thought of decorating items with a variable number of chevrons like '>' to show how deeply nested each item is, for example:
TASK COMPLETED
Some major task No
> A subtask Yes
> Another subtask Yes
> > A sub-subtask Yes
Next major task No
Some problems with that however are:
It might look ugly, and I'm not sure that it's as intuitively understandable and as readable as it can be. Might some other ornament, or simply variable-length whitespace indent, be better?
I don't see an elegant way to encode it using HTML+CSS; for example, would you insert the ornament using HTML, or insert it using CSS; and if using CSS, would that be by adding something like class="level1" through class="level6" to show the nesting level?
A second way would be to present it as text that flows vertically, for example ...
<h1>Some major task</h1>
<p>Completed: no.</p>
<h2>A subtask</h2>
...etc...
... which I will do as well, but I also want a view which lets the reader scan the column of property values, which is easier when the property values are aligned in a column instead of interspersed with other text.
This is more about UI design than coding, but ... I'm surely not the first person to want to display this kind of data, but I don't remember having seen any examples, so I'd like to ask you.
The UI component you want is called a TreeTable (or Tree Table). There are various implementations of it in Javascript/HTML. Here's one that uses Javascript. Here's another one that's pure HTML/CSS (but doesn't collapse/expand)
You're talking about nesting in the hierarchal structure of HTML. By its very nature you don't really have to do any special work at all.
A simple, recursive list is all you need, without any special considerations for depth or anything. You can even add expand-collapse functionality to any level if you want without much extra work.
<ul>
<li>
<div class="task-group">
<span class="task-title">Task 1</span>
<span class="task-status">Complete</span>
<ul>
<li>
<div class="task-group">
<span class="task-title">Task 1a</span>
<span class="task-status">Complete</span>
</div>
<li>
<div class="task-group">
<span class="task-title">Task 1b</span>
<span class="task-status">Incomplete</span>
</div>
</li>
</ul>
</div>
</li>
</ul>
Then you just style each task-group to have a relative margin to its parent so that the nesting becomes recursive. Set up fancy (or no) bullets for the tasks with li's style, and customize the positioning of the task-status class to make it lay out the way you want it.
You can also get lower subtasks to recursively inherit smaller text size by setting a relative text-size in the CSS. Something like .75em, so that each level is three quarters smaller than the previous level.
Something like this:
.task-group {
font-size: .75em;
margin-left: 1em;
}
.task-title {
text-decoration: underline;
float: left;
}
.task-status {
float: right;
}
UL, OL and LI are good for this purpose. Structuring it as JSON is even better. You can render the HTML from JSON in any way you wish.
The question has no right or wrong answer. But I'll answer this question within a question.
If using CSS, would that be by adding
something like class="level1" through
class="level6" to show the nesting
level?
No. You would use the appropriate selector in CSS.
li {
// level one style
}
li li
{
// level two style
}
etc.