Fork me on GitHub!

Welcome

There’s a lot of obsolete information about HTML and CSS and how to do websites, many are outdated, whereas other more current are either too deep into technicalities or just in need to be found.

Using the thme “the right way” this site is an open-source reference which follows the “fork”, “pull request” contribution model popular on GitHub.

This site is a user-contributed (and reviewed) documentation describing web development best-practices, based on two goals:

  1. Vulgarize concepts to teach newcomers
  2. Link to other resources to deepen the knowledge

The target audience is people who wants to learn (or re-learn) with today’s HTML+CSS+Javascript best practices to build a web that is future proof.

On the same idea

Sites that follows the “fork me” on github concept documenting best practices for web development:

Other inspiring resources

Disclaimer

The site barely started, it is a direct action triggered by Move the web Forward, contribute section with proposed requests ”Lazyweb requests” asking for tools and solutions that would be cool to have for web developers issue #73

This is a living document and will continue to be updated with more helpful information and examples as they become available.

How to Contribute

Help make this website the best resource for new Frontend developers! Contribute on GitHub, Ask how is the best way to (…)


Posts

Back to top

Efficient shorthand css techniques

by pankajparashar, renoirb

Use shorthand CSS techniques, when saving those extra bytes is crucial for you!

Usage of shorthand or longhand are not only for brievety purposes. One common use case is to define in full the desired style using short hand, then, override specific style using longhand.

Extending a theme using shorthand and longhand

In most condition, the ideal premise is to see all element as a module and extend variants.

To illustrate this, imagine you want a type of block to set text content in. Content can be (only) a blog post introduction text, a code-snippet, a picture.

Let’s nicknamme it ”marble” (as for the example), each of them needs different styling but some of it has common styling effects.

/* a contrasting color to the background slate */
.marble {
  border:1px solid white;
  padding:25px;
  background:url(marble.png) #FFF repeat;
}

The previous could be a base module to use. Further down the project you could have “theme” section that takes care of the project specific theme.

/* in the project theme, override only what is specific to the project's theme */
.marble {
  background-color: #FCFCFC;
  border-color: #FCFCFC;
  border-radius: 5px; /* And add this border radius too, please! */
}

Imagine all content area are marble and some other will have a clear different style, imagine now we need to style a source-code block, just fork a different behavior to it.

/* use: <div class="marble marble-code">Hello world</div> */
.marble-code {
  font-family: sans-serif;
}

Beware of the cascading effect. If you set a specific effect, make sure there is not already defined. Being precise becomes more and more important as the code stacks up.

1. Padding

Case 1.1 - Padding for all four sections is uniform

/* longhand */
padding-top:5px;
padding-right:5px;
padding-bottom:5px;
padding-left:5px;

/* shorthand */
padding:5px;

Case 1.2 - Padding for (top & bottom) and (right & left) is the same

/* longhand */
padding-top:1px;
padding-right:2px;
padding-bottom:1px;
padding-left:2px;

/* shorthand */
padding:1px 2px;

Case 1.3 - Padding for right & left is the same

/* longhand */
padding-top:1px;
padding-right:2px;
padding-bottom:3px;
padding-left:2px;

/* shorthand */
padding:1px 2px 3px;

Case 1.4 - Padding for all four sections is different

/* longhand */
padding-top:1px;
padding-right:2px;
padding-bottom:3px;
padding-left:4px;

/* shorthand */
padding:1px 2px 3px 4px;

2. Margin

Case 2.1 - Margin for all four sections is uniform

/* longhand */
margin-top:5px;
margin-right:5px;
margin-bottom:5px;
margin-left:5px;

/* shorthand */
margin:5px;

Case 2.2 - Margin for (top & bottom) and (right & left) is the same

/* longhand */
margin-top:1px;
margin-right:2px;
margin-bottom:1px;
margin-left:2px;

/* shorthand */
margin:1px 2px;

Case 2.3 - Margin for right & left is the same

/* longhand */
margin-top:1px;
margin-right:2px;
margin-bottom:3px;
margin-left:2px;

/* shorthand */
margin:1px 2px 3px;

Case 2.4 - Margin for all four sections is different

/* longhand */
margin-top:1px;
margin-right:2px;
margin-bottom:1px;
margin-left:2px;

/* shorthand */
margin:1px 2px;

3. Border

Case 3.1 - Border width, style & color is specified

/* longhand */
border-width:1px;
border-style:solid;
border-color:#000;

/* shorthand */
border:1px solid #000;

Case 3.2 - Border width for all four sides is specified

/* longhand */
border-top-width:1px;
border-right-width:2px;
border-bottom-width:3px;
border-left-width:4px;

/* shorthand */
border-width:1px 2px 3px 4px;

4. Font

A common caveat about fonts is that, like colors, their effect bubbles up until it is redefined in a stronger selector.

Beware of the original definition then, when needed, use the most precise longhand to do your effect.

Sometimes it is even better to create a specific sub class (e.g. bolded) than being over specific (e.g. header > nav strong.title {}, albeit specific, is considered as a VERY BAD practices)

Case 4.1 - Font style, variant, weight, size, height, family is specified

/* longhand */
font-style:italic;
font-variant:small-caps;
font-weight:bold;
font-size:1em;
line-height:140%;
font-family:"Lucida Grande",sans-serif;

/* shorthand */
font:italic small-caps bold 1em/140% "Lucida Grande",sans-serif;

5. Background

Case 5.1 - Background color, image, repeat, attachment, position is specified

/* longhand */
background-color:#f00;
background-image:url(background.gif);
background-repeat:no-repeat;
background-attachment:fixed;
background-position:0 0;

/* shorthand */
background:#f00 url(background.gif) no-repeat fixed 0 0;

6. Colors

Case 6.1 - When a color consists of three pairs of hexadecimal digits, you can omit one digit from each pair

/* longhand */
color:#000000;
color:#336699;
color:#0099CC;

/* shorthand */
color:#000;
color:#369;
color:#09C;

7. List Style

Case 7.1 - When list type, position and image is specified

/* longhand */
list-style-type:square;
list-style-position:inside;
list-style-image:url(image.gif);

/* shorthand */
list-style:square inside url(image.gif);

8. Outline

Case 8.1 - When outline color, style and width is specified

/* longhand */
outline-color:#f00;
outline-style:solid;
outline-width:2px;

/* shorthand */
outline:#f00 solid 2px;

Back to top

Efficient way to re-use a front-end library in your project

by Renoir Boulanger

Extending or re-using one (or many) front-end libraries is a very common practice. The holy-grail of efficiendy in front-end development practices is to be able to import re-usable libraries and adapt to the project’s requirements.

For example. Imagine you want to create a new project, and you already have a few modules available e.g. alert or notification message that could be used in any other projects.

This tutorial is about isolating your own project-specific code, get the benefit of already made patterns that can then mixed-matched for every specific views you may need.

A Common mistake

Unfortunately, a common mistake is that people simply copy-paste code from project to project without real version scheme or version control mechanisms at all (e.g. Git, Subversion). From a set of personnal, mixed with some other project’s source.

Carrying practices and “dead-wood” code alone every project, without follow up from the author or the source.

Although source-control is suggested, the essential to remember is to not modify external libraries. But merely extend and adapt; this is where CSS parsers comes in handy (more on this later).

A better way?

A better would be to use the same concepts that programmers uses in the Object Oriented paradygm. In a few words:

Import, extend your specialized version, separate concerns, re-use. proffit.

This is roughly what OOCSS (Object Oriented CSS) stands for.

But why re-inventing when you can just use and reuse existing in an efficient way?

Compiled CSS

To be able to re-use, and separate concerns, we have no choice, we need something to process and replace things around.

You may follow my drift if you ever had wishes similar to those:

This is some of my own personnal reasons I prefer using compiled CSS.

After that, there is a lot of CSS parsers.

Personally, I like LESS. Because: it can run in the browser, on the server side (within NodeJS), compile from the command line, and be used in automated deployment tools.

A killer argument is that it can only as simple as.

<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="less.js" type="text/javascript"></script>

See usage for more details

To use in production, get the compiled CSS in the localStorage from Firefox/Chrome (in the developer tools such as Firebug) the compiled css and commit the css to the project’s as minified CSS.

Not to forget that you can also use as much as you need @include statements and separate your code, but end up with ONE css file.

How to do?

Create a folder within your project that will handle external libraries.

(rest of your project tree)
web/
  assets/
    lib/
      bootstrap/
      misc/
    js/
    myproject/
      _variables.less
      _adaptations.less
      _modules.less
      _states.less
      _fonts.less
    main.less

In the web/assets/lib/bootstrap/ either download, svn external or submodule from a specific version and keep it as it is. untouched.

While in this example I use Twitter Bootstrap, I often use some specific sup-parts from the also Excellent Zurb Foundation, their font-icons, library for example.

Then. In main.less (or any name you choose as your “main”); copy-paste the conteent from the original web/assets/lib/bootstrap/less/bootstrap.less into web/assets/main.less, and adjust paths accordingly.

Customization

Now that you have this basic workspace, have a look at Twitter Bootstrap’s variables.less file, see myproject/_variables.less has my own version of the original.

Beware though. To avoid compilation errors; just make sure to include the original variables.less file, and only override what you need.

The rest comes by creating patterns and separate concerns.

For example, Imagine you have the module .form-actions and you need to adjust for your needs.

We have the original:

.navbar-fixed-top {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: @zindexFixedNavbar;
}
.navbar-fixed-top .navbar-inner {
  padding-left:  0;
  padding-right: 0;
  .border-radius(0);
}

Then, in your own project code (e.g. in _adaptations.less), you could adjust the original with specific styling:

.myproject > .navbar-fixed-top .divider-vertical {
  background-color: lighten(@themeDarkestColor, 6%);
  border-right-color: darken(@themeDarkestColor, 15%);
  height: 62px;
}

See also that I did not overspecify but precisely wanted to be the direct children (>) of .myproject that, in this case, is assigned to the <body> tag.

In conclusion

The key for re-use is to separate the concerns and not edit your external libraries. By doing so, you will learn how to be very specific with shorthand and selectors, without creating ridiculous selector trails.

Back to top

How to change colors and parameters in a CSS framework such as Twitter Bootstrap

I thought to re-visit the previous post because somebody asked on the Twitter Bootstrap Mailing list if they can change some elements colors using plain css.

I was assuming that the person do not know the existence of css pre-processors so I shared the following blueprint on how to do.

  1. Download bootstrap distribution and the less.js file.

It is a bad practice to modify external library but better extending it. Here’s how

  1. Create a copy of bootstrap.less outside of bootstrap distribution folder.

  2. Adjust path on the bootstrap.less @include directives.

  3. Create your own variables.less

  4. Call that one in your own new bootstrap.less file

  5. The new variables.less file should have only variables you want to rewrite. And it should have an include at its top to the original (aka overloading) variables.less file

Follow LESS css pre-processor howto to use less and yoi can change colours!

Best regards

Back to top

Creating and using jQuery events, the thing I wished I knew before

During web development, it often happens you want to attach events handler on something in your page. A common usage could be you want to flip a plus sign to a minus sign when you click on a button.

<a href="/some/url/324" class="flip-icon" data-target="#generated-324"><i class="icon-plus"></i></a>

Later in a script you may be compelled to do something similar to the following (assuming you are using jQuery):

$(document).ready(function(){
// Rest of the document in document.ready
// DO NOT USE AS-IS, SEE LAST EXAMPLE

    $('.flip-icon.).click(function(event){  
        event.preventDefault(); 
        var clicked = $(this);
        var flipElement = clicked.find('i');
        if (flipElement.hasClass('icon-plus')) {
            flipElement.removeClass('icon-plus').addClass('icon-minus');
        } else {
            flipElement.removeClass('icon-minus').addClass('icon-plus');
        }
    });
});

But what happens if you want to add other events such as, for example, activating an accordion. You may end up with duplicating events and get some collisions.

Did you know that the ‘click’ event is only a string and you can create any event name you may want?

To describe what I am refering to, I have a add an other behavior that will also, in part, require the previous example.

Imagine we have an accordion managed already grabbing the element’s a[data-target] click event handler.

$(document).ready(function(){
// Rest of the document in document.ready
// DO NOT USE AS-IS, SEE LAST EXAMPLE

    $('a[data-target]').click(function(event){
        // do the accordion stuff
    });
});

But, what if for some reason, our page has to reload some sections and our event handler managing the a[data-target] click gets lost

Instead, of creating a click specific event handler (what if we want to change) and be potentially lost with the element to attach event onto.

You can use jQuery’s on method and attach an event to the <body>, a safe element that every document has.

Things to note about the on method:

Also, there is nice thing about bubbling.

When an event happens, the event crawls the DOM up to the body (called ‘catch’) then gets back to the triggerer element (called ‘bubbling’) and firing in that order all event handlers.

Knowing all of this now, instead of attaching a single event type handler to a specific element, let’s take advantage of our new knowledge.

'use strict';
$(document).ready(function(){
// Rest of your document

    // Look at the 'flip-my-icon-event', we just made-up that one. See below.
    $('body').on('click flip-my-icon-event', '.flip-icon', function(){
/* Look here     *************************                                       */
        // Let's put it also in a self-executing anonymous, to isolate scope
        (function(triggered){

            // Same as earlier.
            var clicked = $(this);
            var flipElement = clicked.find('i');
            if (flipElement.hasClass('icon-plus')) {
                flipElement.removeClass('icon-plus').addClass('icon-minus');
            } else {
                flipElement.removeClass('icon-minus').addClass('icon-plus');
            }
            // End same as earlier

        })($(this)); // this fires the self-executing.
    });

    $('body').on('click', 'a[data-target]', function(event){
        event.preventDefault();

        // do the accordion stuff
        var collapsible = $($(this).attr('data-target'));
        if (typeof collapsible.attr('data-collapsible') === 'undefined')  {
            collapsible
                .collapse()
                .attr('data-collapsible', 'applied')
                .on('show', function(){
                    jQuery(this).parent().removeClass('is-hidden');
                })
                .on('hide', function(){
                    jQuery(this).parent().addClass('is-hidden');
                });
        // End do the accordion stuff

        jQuery(this).trigger('click').trigger('flip-my-icon-event');
/* Look here                         *******************************        */
        }
    });
});

The following works, because of the following trigger html pattern, as from the begining:

<a href="/some/url/324" class="flip-icon" data-target="#generated-324"><i class="icon-plus"></i></a>

And of the following:

References

Back to top