I often use CSS ids or classes to select elements in Javascript. Many of those classes do just exist for that use case and do not have any styles attached at all.
I ponder now if it would be any good to mark those classes explicitly. Maybe something like a leading underscore (e.g. class="_field").
The thing is that I never heard of such a practice. Is this recommended? Maybe already used in a bigger project? What kind of marking would make sense? I read somewhere that a leading underscore could be problematic. What else could I use to easily identify those "Javascript only" classes?
You can do that as a personal coding convention. The spec doesn't state that the class attribute must be used in styling only, or in scripting only. You can use it to classify your elements in any way you want, so there's no restriction in how you name and organize your classes.
The majority of the time I find that the class names used in JS matches the styling I want to do in CSS. As long as you name them properly it's not a big deal that a class name is used by only CSS or JS.
You may want to use the data-* attributes suggested by HTML5. They even work in HTML4, though the resulting code is not valid.
As a sidenote, ExtJS has used "namespaced" custom attributes for their tree nodes for quite some time:
<div class="x-tree-node-el x-tree-node-leaf x-unselectable cls"
ext:tree-node-id="Foobar">
(They should change that to data-ext-tree-node-id btw)
It is better to use ids for working with JavaScript since an element has only one id that is unique to it, while classes can be applied to multiple HTML elements.
Related
I'm using css to change the sizes of two divs so that their size represents some value that changes a few times per session.
Is there anyway to define a css class something like:
.shiftydiv(*) {
width:\1;
}
where \1 is whatever * matched? Then I can just add a class like .shiftydiv25 via jquery whenever I need to change the size.
I don't need legacy support for browsers and I'd prefer not adding any dependencies.
If I can't do it with pure css I'll either create CSS classes dynamically or inject style= attributes into my code. Which would be better (less bad).
EDIT:
If there is a nice way to do this with JS/jquery that would work well too.
EDIT 2:
So doing this with js is actually quite easy. oops
Maybe instead pure CSS use SASS/LESS and generate multiple classes?
You can use for loop and iterate over lets say 20 elements and make .shiftydiv1, shiftydiv2, ... shiftydiv20.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
One of my colleagues doesn't like to use HTML classes and ids for javascript/jQuery purpose. Therefore I've seen that he had created custom html attribute such as
<div id="myid" class="cssClasses ..." [some-purpose-id]="mycustomId">...</div>
I asked him if it was really a good idea and he replied that he considers that classes and Ids should be reserved for styling.
Personally, I would have used classes. Some classes would have been used for styling, and some other classes would have been used for programming (jQuery selectors). The idea is to keep things appart also. And of course jQuery could set styling classes but if possible not use them for selection. Of course I also use id when appropriate but since an id is unique on a page, I like to do generic stuff using classes.
I would like to know you opinions on the better approach (if there is one). Thank you.
I would recommend against that, but rather use the HTML5 data attribute. Read about it here.
You should use classes and IDs for both javascript and CSS. Your colleague is wrong.
It helps to remember that you want to keep separation between data (html), presentation (css styling), and behavior (javascript). Classes and IDs are there for a reason, and it's not for styling (and not for javascript, either!). They are there to allow you to semantically mark up your document.
When writing proper HTML, your classes and IDs should reflect the actual content and purpose of the data those nodes contain. Then, when you need to style them, you can specify the proper styling for, say the .zip_code class. And when you need special behavior, you can use javascript to apply the required behavior to your .deletable list items.
Of course, sometimes in the real world, there are people who feel very strongly against things, and you end up having to go along with what they want. In this case, you may have to compromise with your colleague and use HTML5's data-* attributes, as someone else suggested. However, while this is a solution that will result in valid HTML, it is not what data-* attributes were designed for, so it isn't technically the correct solution.
No, for the most part, you shouldn't use made-up attributes. These are not valid HTML, and will show up as errors if you try to validate your code.
However in HTML5 you can use custom attributes that begin with data-. You can read more about them on the html5doctor website. data- attributes, however, are more often advocated for storing information, not labels. e.g. for a product you might say data-brand="gucci". Or something.
Using attributes for styling or javascript is misleading, because it's not a dichotomy. Often, you will need to add an id or class to style your markup. If possible, you can reuse these attributes to select elements in javascript without adding attributes. It keeps your code clean, but this is obviously just a preference.
If you need to select an element that doesn't already have a unique id or class that could be used for selection, you could use the data attribute. However using ids and classes is still standard practice.
It may be useful if you want to supply another data inside attributes for multiple purposes, look at the following example:
<script>
function getIt(){
ob = document.getElementById('myid')
alert(ob.getAttributeNode('anotherTitle').value)
}
</script>
<div id="myid" class="cssClasses" anotherTitle="new Title">The div</div>
Test
I used the anotherTitle attribute to save or store another set of data in-which it may be used in another usage.
This is a working example http://jsfiddle.net/vxknh/
The refrence: http://www.w3schools.com/jsref/prop_attr_value.asp
Maybe your colleague was inspired by examples of the declarative style used in the dojo toolkit.
data- is a good way to "stamp" your attributes for a specific purpose (for example all dojo specific attributes are of the form data-dojo-whatever). This reduces the risk of conflict with other scripts or css.
So yes it can be a good idea, but no classes and ids are not reserved for styling.
Classes and ID have their advantages and disadvantages (it is also very dependant on how you use them).
Classes - they were designed to convey styling info, but with advent of jQuery now they have dual purpose, sometimes signifying action (or data) and sometimes styling. This is quite confusing especially on large scale projects. Imagine a designer trying to "re-factor" the CSS and changing these class names on elements that have javascript/jQuery hooked up to it - bad things ensue. You could mitigate against that prefixing your non-styling class names with a "namespace" like ".donttouchthis-jqueryclass", which differentiates the logic from presentation is a very primitive manner. The advantage of using a class is that it can be "stacked" thus it can convey more complex "logic" than an ID for example. From a pure javascript (no jQuery) point of view reliance on classes in your code introduces some backward compatibility issues (getElementsByClassName).
IDs - as the name implies were designed to uniquely identify elements. From a programming point of view IDs offer the fastest way to access elements in the DOM (getElementById). They can also be styled, however the potential to remove an ID when re-factoring is lower (as you can always remove ID styling and give it a class). IDs are unique thus making extensive use of them to store any complex data is very, very limited. But they are great to bind click handlers or uniquely identify chunks of the DOM as long as you only need one of elements identified by them.
Both Classes and IDs have one important rule which limits their usefulness as means for conveying any business logic - they cannot start with a number (and often you just need that database id conveniently assigned to an element)
Custom attributes (not data-) - they can be anything which is kinda cool, however if you care about "validity" of your HTML you will be restricted to certain DTD types and you will need to specify them in your DTD. In reality they do not harm your HTML as browsers are specifically obliged (under the W3C convention) to ignore unknown attributes. The only problem being a clash with potential future developments. If you are using pure javascript they will also be a bit of a pain to use (but this is a subjective option - as suggested in one of the answers above this is a good supplementary option to use them as data storage). The potential for a mixup when re-factoring CSS is small.
Custom data- attributes - these are great if you are using jQuery because you can store really complex data against it (objects etc), when used correctly they really kick ass and give you a nice vocabulary to describe function of your DOM elements. "data-" namespace nicely protects it from any future conflicts with non name-spaced attributes.
Having said all that the best solution is not to overtly rely on any of these, but implement javascript patterns which allow you to pass a parent DOM element and later apply functionality to it based on markup (like a standard jQuery plugin pattern). This way you remove a lot of dependencies on specific attributes/classes/ids that are a part of static HTML source.
I want to clarify the good practices in terms of Designer/Developer workflow.
Here is my observation, let me know if I am wrong : there is no fundamental reason why CSS and JS should use the same attributes. Events associated to an html tag are not related to the styles that are applied to it and separating them would help the maintenance for both the developers and the designers.
And my question : why isn't there a strict separation between the two? I understand that we are free to use custom attributes for JavaScript and keep IDs, classes and HTML tag names for CSS however everything in jQuery seems to be made to use them. For example :
$("#myid").html("Test");
$("#myid").addClass("clickable");
$("#myid").removeClass("clickable");
if($("#myid").hasClass("clickable")) var clickable = true;
etc. Why is so?
Side-question : is there some performance issues about using only custom attributes for JavaScript?
$('[event="clickable"]').html("Test");
This article from Roy Tomeij http://roytomeij.com/2012/dont-use-class-names-to-find-HTML-elements-with-JS.html mentionned in stackoverflow : Separate ID and Class for JS and CSS seems to advice not to use classes in Javascript but that's all I have found so far and I want to expand the discussion.
It is valuable for both CSS and JavaScript to have the two items : unique IDs and multiple classes but when I think about it we could have div such as
<div css_id="mydiv" css_class="green" js_id="unique_element" js_class="other_event">
and hypothetical CSS properties and jQuery functions such as
div#mydiv{margin_top:20px;} //reads from css_id attributes
div.green{color:green;} //reads from css_class attributes
$("#unique_element").click(function(){alert("Clicked!")}) //reads from js_id attributes
$(".other_event").click(function(){alert("Congratulations!")}) //reads from js_class attributes
and in the same way
$("#unique_element").addClass("clickable2"); //add a value to the js_class attribute
Thank you all! I do not intend to reinvent everything just to explore ways to improve teams' workflows.
I think you can answer your own question. What possible benefit does having markup that looks like this provide?
<div css_id="mydiv" css_class="green" js_id="unique_element" js_class="other_event">
To me it looks messy and harder to deal with. In theory, content is king, and in the beginning you have a beautifully marked-up semantic HTML document. Thoughtfully, you add semantic class names and IDs based on the content within them. Using these IDs and classes, you are able to staple design and functionality onto your document using CSS and JavaScript respectively.
To answer your other question, IDs are faster for JavaScript. If you're using JQuery, the performance is negligible if you cache the DOM references as variables (which you should always do if you reference an element more than onec). For example, var $myclass = $('.myclass'); You can read more about selector performance here.
For CSS, many people recommend avoiding IDs for styling as much as possible. You can read the spec on specificity, but basically using lots of ids will lead to some of the same (though less extreme) problems as using !important.
The best I've seen is:
<div class="button button-primary js-modal-popup">
Essentially - add a class with js- prepended to it so you can distinguish from your stylistic classes and your jQuery hooks. It allows you to to create as many ID's or classes as you'd like without inhibiting your styles to be tied to actions as well.
there is no fundamental reason why CSS and JS should use the same attributes.
This is true. They're two separate languages...so, yes. There is no 'fundamental reason' why they should use the same attributes.
however everything in jQuery seems to be made to use them.
I don't think this is true, though. JQuery has specific functions for class and so on because, well, they're existing CSS attributes. But it also has the same exact functions for custom attributes, so there's no asymmetry here. I don't think this could be used as evidence that Jquery was made to use CSS attributes anymore than custom attributes.
As to your questions of performance or which to use, I think that bookcasey adequately answered them.
This is more of an organisation question concerning Jquery.
Using the following simple example:
click me
<script>
$(document).ready(function(){
$('.click').on('click',function(){
alert('Clicked!');
});
});
</script>
Now multiply this by a 1000 on your website, it can quickly get messy. You also can forget which classes you attributed for Jquery or for your CSS.
I usually try to avoid mixing both, so I add my classes for CSS and others for the Jquery, in case I change I the layout or use that section somewhere else, ... I can change the CSS. But how to do you remember which one is for CSS or Jquery? Do you name your classes "JSclassName" or something like that?
Let me know if I'm not clear and thanks for your help.
Have a consistent naming scheme for your "sections" in terms of case and meaning
Keep id and class names the same both for CSS and JS to avoid the confusion.
Relating to semantic code, you should give meaning to the class/id names as well. This helps you remember what you are adding code for. Don't use something like "centeredContainer" or "thisIsClickable".
Example:
<section class="weatherWidget">
<ul class="forecast">
<li class="vicinity">
...
<ul class="news">
<li class="region">
...
I also namespace my CSS and JS to avoid conflicts. The following code ensures that only weather widget contents are referenced by the code:
//this click event is only for weatherWidget vicinity
$('.weatherWidget .vicinity').on('click',function{...});
//this CSS is only for weatherWidget regions
.weatherWidget .region{...}
Also, although I don't really use them nor endorse using them, LESS and SASS frameworks can also help in terms of avoiding redundant CSS code by using variables.
First, give your identifiers more meaningful names. In my opinion, click is not a ideal one. A button is clickable, so is a anchor, even a div element.
Second, if you do have hundreds of identifiers, try to use namespace to distinguish CSS/JavaScript identifiers. But I think this is not necessary, using the CSS identifier in your JavaScript is natural, a meaningful name is in the first position.
<style>
.ui-cart-button{ };
</style>
Buy
Namespace is a good way to make your code cleaner and more readable, I recommend you to have a look at the source code of jQueryUI.
Here are my suggestions;
Always use unique IDs. IDs should be unique, given to a specific element or selector only while classes can be given to multiple selectors.
No need to use same class for JavaScript and CSS both since multiple classes can be assigned to a selector like <div class="class1 class2">
Use a style-sheet attachment for common items appear in multiple pages so as to limit Embedded and Inline styles.
Links below will suggest some guidelines for you.
30 CSS Best Practices for Beginners
15 Best CSS Practices to Make Your Life Easier
10 Best CSS Practices to Improve Your Code
All the above given information is to let you know about using CSS. From all these info, you may formulate the best option ideal for your needs.
I am tempted to make some custom attributes for some page elements to make selection easier, via the .attr(); function in jQuery.
I figure that this is probably discouraged, as there is a lot of flexibility in jQuery and javaScript that, as a novice, I have not learned to employ yet to its full potential.
Other than making cryptic IDs or adding lots of classes, what are some ways to add more information to my divs and other page elements for easy selecting via the selector $()?
I'm mostly curious as to pros/cons, and what memory issues or speed issues result based on different approaches.
There isn't a problem at all creating custom attributes on your elements. Anyway, you should follow the html5 data- spec.
<div id="foo" data-info="hello" data-more="{'iam': 'anobject'}" />
The cool thing about using this is, jQuery (latest version) will automatically parse the data-x attributes and adds those into the .data() expando.
$('#foo').data('info') === 'hello'
$('#foo').data('more').iam === 'anobject'
You are still able to run a selector like
$('div[data-info=hello]')
on your elements.
ref.: .data(), html5 data attributes
HTML5 introduces data-* attributes. So if you are going to introduce custom attributes, I would at least stick to this specification.
There is also the .data() method in jQuery for associating arbitrary data with elements. As long as you don't need to use the data in a selector, this is the preferred way.
jQuery plug ins usually use some already existing attributes like "rel" or "title" but jQuery also has the .data() method which stores information on an specific object in javascript. It acts like a log.
http://api.jquery.com/jQuery.data/
Both of this techniques are acceptable and work well.
The first thing to be aware of is that the jQuery selectors are extremely powerful. You don't always need to select by an ID or a class - you can select by tag, by type, by relation to another selection (children/parents/siblings/etc). So, there may not be a need to add IDs or classes to your various elements in order to select them.
With that said, don't avoid classes and IDs just for avoiding classes and IDs. They exist for a reason, and that reason is to make selection of them straightforward and easy (whether it is with jQuery or CSS or whatever else). If you remove classes and IDs, you may make your HTML look nicer, but your jQuery code may become convoluted and/or very inefficient. (For example, it is always faster to select an ID directly than select a parent component and find its children.)
I don't think you should be discouraged to use attr(). It is a powerfull tool and really helps to add more information to your elements. I have some projects using it to suport internal javascript frameworks and it turns my code clean and legible. And it has the advantage to be is a ease to work with selectors!
You should really be using only classes and IDs for the initial selection but here are some handy selectors you can use on top of this:
http://api.jquery.com/category/selectors/
A unique ID is the quickest way to find an element through jQuery, so if the purpose of your temptation is to make your elements easier for jQuery to retrieve, it seems pointless.
I've used such techniques for adding attributes such as title or alt for better accessibility.
Use .data('key', 'val') to set your data and.data('key') to read it.
I would definitely use the Data api (http://api.jquery.com/jQuery.data/)