I've started using BEM methodology to decouple my HTML and CSS ... and it works pretty well most of the time. Even if its only your personal opinion, i would still like to know how others deal with this:
Let's assume we need to build a simple navigation. The HTML looks similar to
<nav class="nav">
<ul class="nav__list">
<li class="nav__item">
<a class="nav__link" href=""></a>
</li>
<li class="nav__item">
<a class="nav__link" href=""></a>
</li>
</ul>
</nav>
I'm not sure if i need the ".nav_item" and ".nav_link" or if it's better pratice to use this instead
.nav__list > li { CODE }
But my real issue is how to deal with "active" classes (not just for navigations, but in general). Is it better to use specific "active" classes like ".nav_item--active", so you can just use a single class inside your CSS file or if using more general class names like ".is-active" works better? But then you need to specify your classes inside your CSS file like ".nav_item.is-active" or (which looks even worse to me) ".nav__list > .is-active".
Every method has its downsides. To me the second way looks wrong if using BEM, but if you are going for the first way you run into "troubles" with your JS, because you need to "hard-code" the specific class name into your JS
someElement.addClass(".nav__item--active");
That way your JS relies too much on your HTML structure (or doesn't this matter too much?), which might change... And this leads to the second question. I heard that it's good to decouple not only your HTML and CSS but also your HTML and JS. So you could for example use those ".js-" classes to add click events and all that kind of stuff to elements instead of using your "styling" classes to trigger those kind of events. So instead of using
<button class="btn btn--large"></button> // $(".btn--large") in jQuery
you would have
<button class="btn btn--large js-dostuff"></button> // $(".js-dostuff") in jQuery
I think this in combination with HTML5 data-attributes works for pretty much for anything, but i'm asking myself what happens to navigation or accordions or stuff like that. Is it better for maintainability to use those ".js-" classes as well (for every item)
<nav class="nav">
<ul class="nav__list">
<li class="nav__item js-open-subnav">
<a class="nav__link" href=""></a>
<ul class="nav__sub">
<!-- ... -->
</ul>
</li>
</ul>
</nav>
or should i use $(".nav__item")... in my JS in this case? But that way you don't really decouple your HTML and JS (at least as far i understood this topic). It's not just about navigations, but about all those kind of javascript interactions, like accordions, sliders and so on.
I'll hope you guys can share some best practices for those questions and help me out.
Thanks
BEM methodology says you shouldn't use any global selectors such as tag selectors so use nav__item and nav__link.
The same story with active modifier. You shouldn't have any global entities (you can use mixes but that's a bit different thing). So the best way is to go with nav__item--active (or nav__item_state_active in classic BEM notation).
And BEM has sollution for JS, HTML (or templates) and actually any other block's technology.
The main idea is that block knows everything about itself: how it looks (css), how it works (js), what html it should produce (templates), its own tests, documentation, images, etc.
And as css technology of the nav block applies rules in declarative way (you define some selector and all the nodes which match this selector are styled with these rules) the same way you can describe js of the nav block.
Please take a look at http://xslc.org/jquery-bem/ which is jquery plugin which gives you possibility to work with blocks in BEM way easily.
And in case you use some build system you can put all these technologies in the same folder on filesystem:
blocks/
nav/
__list/
nav__list.css
nav__list.js
__item/
nav__item.css
nav.css
nav.js
nav.test.js
nav.png
nav.md
Having such file structure you may go deeper to what BEM actualy is and try i-bem.js: http://bem.info/articles/bem-js-main-terms/
Actually, js in terms of bem often considered as not such good idea.
For instance, bem is great to localize and move relations in css to horizontal scale, but in terms of js it's hard to abstract logic in very complex applications.
In react.js you can use it for class naming, and that's it (we use it this way and it works fine!).
I wrote a library for decoupling problem with naming.
Related
I am new to jQuery. I recently develop a plugin bu using jQuery UI widget factory. It is working fine. I was using inline styling. But It will get complex for large files.
For the large project I have the option to use classes. But when if someone wants to use my plugin he'll simply copy the link and use it. But If he has same name of classes on his page then its page will be destroys because my of my styles. Can anyone please guide me how to avoid this.
I hope you get the point.
Thanks
Some things to consider:
If you make a selector that is too specific, like
$("ul > li > .foo ~ .bar");
it may break by any changes on the markup.
However, if you don't, it will break your user's style.
As commented, the easier way to fix this would be adding an prefix on the class, like
<div class="my-plugin-container">
<span class="my-plugin-span"> "Hello World" </span>
(OR) <button class="my-plugin button"> </button>
</div>
If you could post any code we could be able to help you further. I'll edit it according when you do.
Best of luck
I have to build a multi language website in Business Catalyst(not my choice), my only option for the language switcher and the fore the link rel="alternate" is JS.
After a lot of trial and error I got this to work:
<script type="text/javascript">
document.write("<ul>");
document.write("<li>English</li>");
document.write("<li>French</li>");
document.write("<ul>");
</script>
The only problem is that it is slow and probably badly written.
It is there a better way to write the code? Maybe one that load faster and possibly using jQuery?
Thank you very much in advance for your help
Antonio
You can include the following in your html.
<ul id="multilang">
<li>
English
</li>
<li>
French
</li>
</ul>
Then use jQuery to manipulate the url.
$(function () {
$.each($("#multilang a"), function () {
$(this).attr('href', $(this).attr('href') + location.pathname);
});
});
I generally recommend avoiding string based dynamic html since it tends to be hard to maintain over time. Instead I recommend going for some sort of template based solution. There are a few options, but one popular framework is KnockoutJs
http://knockoutjs.com/
1- A a starter. document.write will replace the whole DOM with your list, therefore, I suggest appending the list to an html element.
2- To improve performance, try to have less function call to reduce overhead. Option 1: prepare the html and write it in one string, then append that string. E.g.
var lang = "<ul><li>stuff...</li><li>other stuff....</li></ul>";
Or, for readability,
lang = "<ul>";
lang = "<li>English</li>";
lang = "<li>French</li>";
lang = "</ul>";
Then
$("#change_lang").html(lang);//change_lang is a div <div id="change_lang"> that you have prepared to put the links inside.
3- Maybe you can load the html from your server directly, without having JS to print it on screen for you. Put it in .html page (I'm not sure about your page structure, therefore, I cannot know why this approach might not be suitable for you) but loading html directly without waiting for JS and JQuery to load will make display much faster.
<ul>
<li>English</li>
<li>French</li>
</ul>
4- Also try to put your JS code in separate files, and then minify them to reduce size and hence loading time. Having JS in separate files allows the browser to cache them and eliminate the need to load them every time. Search for PageSpeed to show you various ways to improve your site performance.
This question is not about how to toggle a div. But instead how to toggle visibility in a big web app. My web app needs only to run on Chromium (Webkit). The problem I have is probably more related to infrastructure and best practices, and I wonder if anyone has experience with this.
My app runs on node-webkit, which means all files are local, and loading is quick. To feel really snappy, I add all content to the DOM I possibly can. I want to stay away from state changing my app with Javascript, so no $('.view-projects').addClass('visible');. Because it will get messy really soon, and I feel it's not really the task of JS.
Instead the approach I have chosen works like this.
// javascript sample (I actually code in CoffeeScript)
// catch all click events on elements with data-trigger attributes
app.on('view:addProject', function () {
// add a class to the root view
$('#app').addClass('view-addProject');
}):
Markup:
<!-- markup sample -->
<div id="app">
<div class="projects">
<div data-trigger="view:addProject"></div>
<div>etc.</div>
</div>
<div class="addProject">
etc.
</div>
</div>
Css, used as the state machine:
app.view-addProject .addProject {
visibility: visible;
display: block;
}
What I want to know is if other people have tried something like this, have good experiences with other approaches etc. Or maybe I am missing something, I feel I am getting myself in trouble with dynamic content.
Note: I can't simply use show/hide, since my elements use display: -webkit-flex/-webkit-box; etc.
If you want to toggle visibility, here are some alternative approaches:
Control state by changing CSS via the CSSOM
Change state by changing data- attributes
Change state by changing DOM nodeNames
I have html snippets and i was wondering where I should keep them... For example:
Currently I have the following in my HTML page
<div id="Mailbox" class="ui-corner-all">
<div id="Messages">
<ul class="messageList">
<li class="noMessage">You have no messages</li>
</ul>
</div>
<div class="trashIcon ui-corner-bottom">
Delete Selected Message(s)
</div>
</div>
Then, when the page loads, jquery and javascript turns this into a full functioning mailbox system.
What I am wondering is - Should I bother with the HTML snippet, or just build the entire thing through JS?
Having the markup in your page potentially degrades much better for users with no script. Plus, it's usually easier to work with existing markup than build it completely from scratch with JavaScript.
Sometimes templating can be an appropriate solution. This will not degrade for users without script, but if you have a script-heavy page that needs to create a lot of markup dynamically, templates can make this simpler.
If you find that you are duplicating blocks of markup from page to page, this should probably be addressed server-side by storing the common content in a single location.
Depends if you're writing an application or a website. Does SEO matter? Does accessibility matter? Do you need to support a wide range of browsers and devices?
If not then I'd write it in JS but take a look at some MVC frameworks such as backbone.js or JavaScriptMVC etc. in which case you'll likely want to be using client-side templating so you're html should be in the page but not in the DOM.
I'm trying to make it really obvious in the DOM that javascript code depends on the structure. Is the following a good idea?
HTML:
<a class='submenu' data-submenu="true" .... </a>
JS:
var mySubnav = $("[data-submenu]");
Makes it really clear that javascript is operating on the html. But I haven't seen this used by other people.
I'm not sure why you can't just use classes for this case? If your links have a subnav class that's far more compatible and easy to parse, plus stylable, than a data-submenu attribute.