Thursday, November 20, 2014

CSS Tabs Navigation Tricks

Developing a tabs navigation with CSS holds some simple tricks, but most of the front-end guys end up getting the results in an inappropriate way. Here's what you need to know about it -
I. The margin-bottom: -1px to the <li> element
II. The border and background to the <a> element
III. Change in border and background in the <a> element when <li> has .active class

HTML: 

CSS: 
ul{ margin: 0; padding: 0; list-style: none; border-bottom: 1px solid #ddd; 
}
ul:before, ul:after{
    content: ""; display: table;
}
ul:after{
    clear: both;
}
/**/
ul li{ 
    float: left; 
    margin: 0 4px -1px 4px;                /*Trick 1*/
}
ul li a{ 
    display: block; 
    text-decoration: none; 
    padding: 10px 15px; 
    border: 1px solid transparent;         /*Trick 2*/
    background: transparent;               /*Trick 2*/ 
}
ul li a:hover{
    background: #eee;
}
ul li.active a{ 
    border-radius: 4px 4px 0 0;
    border: 1px solid #ddd; 
    border-bottom: 1px solid transparent; /*Trick 3*/ 
    background: #fff;                     /*Trick 3*/ 
}

jQuery: 
$(function(){
    $('li a').on('click', function(e){
        e.preventDefault(); // to avoid page refresh because a elements have # in href 
        $('li').removeClass('active');
        $(this).parent('li').addClass('active');
    });
});


Demo: http://jsfiddle.net/dipaks2011/o35c8yxt/

Note: The fiddle demo is creating a ghost border on the right side of the tabs which doesn't appear in real HTML page.


Saturday, November 15, 2014

JavaScript text selection popover

Those who have read some articles on Medium.com are aware of how they can select text anywhere on a page and share it on Twitter or write a short comment about the selected text right on that page.

That's a nice popover to have, if the requirement is to select the text and show some information related to it on the same spot. I thought of posting a simple demo of it here, so that others can use it.

Here's the code 

HTML:
    
Having been in the field, most recently in India, I have seen that access to safe water is just a few dollars away for many people. A small loan can create a pathway to a household water tap. Making access to capital ubiquitous and affordable for those living in poverty would go a long way towards eliminating water stress.
CSS:
::selection{
  background: SeaGreen;
  color: White;
}
::-moz-selection{
  background: SeaGreen;
  color: White;
}
#textDescription{
  line-height:1.9em; font-size:16px; margin:10px; border:1px #333 solid; padding:5px; width: 450px;
 }
 .selectedText{
  position: relative;
  background-color: SeaGreen; color:#fff; line-height: 1.2em;
 } 
 .popDiv{
  background: ForestGreen; color: white; padding: 6px; width: 180px; height: 80px;  
  position: absolute; top: 18px; left: 0;
  border-radius: 4px; box-shadow: 2px 3px 4px #444;

  -webkit-animation: slideIn .5s;
  animation: slideIn .5s;
 }

 @-webkit-keyframes slideIn{
  from{
   top: 8px; opacity: 0; height: 40px;
  }
  to{
   top: 18px; opacity: 1; height: 80px;
  }
 }

 @-moz-keyframes slideIn{
  from{
   top: 8px; opacity: 0; height: 40px;
  }
  to{
   top: 18px; opacity: 1; height: 80px;
  }
 }

 @keyframes slideIn{
  from{
   top: 8px; opacity: 0; height: 40px;
  }
  to{
   top: 18px; opacity: 1; height: 80px;
  }
 }
JavaScript / jQuery:
 


 var parentContainerId = "textDescription"
  
 if(!window.CurrentSelection){
  CurrentSelection = {}
 }
 
 CurrentSelection.Selector = {}
 
 //get the current selection
 CurrentSelection.Selector.getSelected = function(){
  var sel = '';
  if(window.getSelection){
   sel = window.getSelection()
  }
  else if(document.getSelection){
   sel = document.getSelection()
  }
  else if(document.selection){
   sel = document.selection.createRange()
  }
  return sel
 }
 //function to be called on mouseup
 CurrentSelection.Selector.mouseup = function(){
  
  var st = CurrentSelection.Selector.getSelected()
  if(document.selection && !window.getSelection){
    var range = st
    range.pasteHTML("" + range.htmlText + "");   
  }
  else{
    var range = st.getRangeAt(0)    
    var newNode = document.createElement("span");
    newNode.setAttribute("class", "selectedText");
    range.surroundContents(newNode);
    //
    var getTitle = newNode.innerHTML;
    newNode.setAttribute("title", getTitle);

    //
    var popDiv = document.createElement('span');
    popDiv.setAttribute('class', 'popDiv');
    popDiv.innerHTML = getTitle;

    if(newNode.innerHTML.length > 0) {
     newNode.appendChild(popDiv);
    }     
    //Remove Selection: To avoid extra text selection in IE  
    if (window.getSelection) {
      window.getSelection().removeAllRanges();
    }
        else if (document.selection){ 
         document.selection.empty();
        }
        //
  }
 }
        
 $(function(){

  $("#"+parentContainerId).on('mouseup', function(){
    $('span.selectedText').contents().unwrap();
    $(this).find('span.popDiv').remove();
  });

  $("#"+parentContainerId).bind("mouseup",CurrentSelection.Selector.mouseup); 
 })        


Demo: http://jsfiddle.net/dipaks2011/uz0gsu8a/1/



Related Posts:

jQuery tab navigation:
http://dipaksblogonline.blogspot.in/2012/03/simple-jquery-tab-navigation.html

Defer third party scripts:
http://dipaksblogonline.blogspot.in/2012/06/defer-third-party-scriptsads-until.html

Using multiple iScrolls in one page:
http://dipaksblogonline.blogspot.in/2013/06/using-multiple-iscroll-in-one-page.html



Wednesday, September 17, 2014

HTML5 details element

Have you ever wondered if you could achieve that jQuery Accordion widget effect without jQuery or JavaScript? Did you think it will be ever possible to create it with just HTML? If no, well, you can achieve that with the HTML5 <details> element.

The details element is used as a widget to show/hide additional information.
Click me to toggle more information
The details element is used as a widget to show/hide additional information.
Demo: http://jsfiddle.net/8mthoj5g/

Attributes:

It comes with one additional attribute that is 'open'. By default it appears in closed state, but if you want to keep the hidden information visible on-load, you can use the 'open' attribute -
Click me to toggle more information
The details element is used as a widget to show/hide additional information.
Demo: http://jsfiddle.net/8mthoj5g/1/

Nesting:

Nesting multiple details in details is possible -
Click me to toggle more information
The details element is used as a widget to show/hide additional information.
More links to help
Demo: http://jsfiddle.net/8mthoj5g/2/

Styling:

This is the area where you can make the widget look beautiful with CSS. If you want to style the marker you can use ::-webkit-details-marker pseudo class  -
details{
    border: 1px solid #666; 
    border-radius: 4px; 
    margin: 0 0 4px 0;
}
summary{ 
    background: linear-gradient(to top, #f1efef 0%, #e8e9e9 50%, #e8e8e8 100%); 
    padding: 8px; 
    outline: none; 
}
.more-info{ 
    border-top: 1px solid #666; 
    padding: 8px; 
}
details[open] summary{ 
    background: none; 
}
summary::-webkit-details-marker {
  color: #818b94;
}
Demo: http://jsfiddle.net/czs29fd3/

To replace the default marker with some fancy icon, you can use the CSS :before and :after pseudo classes with summery element, but before using a replacement for marker you must hide it first -
summary::-webkit-details-marker {
  display: none; /*Hide the default marker*/
}
summary:after {  
  content: "+";   
  float: left; 
  font-size: 1em; 
  font-weight: bold;       
  width: 22px;
}
details[open] summary:after {
  content: "-";
}
What about the browsers that don't support details element?
Use this Bulletproof HTML5 <details> fallback using jQuery by @MathiasBynens

Browser Support:

You can see the latest browser support at caniuse.com




Monday, August 18, 2014

Understanding HTML5 Pattern Attribute

What is HTML5 Pattern?
The HTML5 pattern attribute is nothing but a JavaScript Regular Expression. It is used to match form field's value against the specified format. Patterns are used to validate email addresses, dates, credit card numbers, zip codes and so on.

For example, the following pattern requires one number and three uppercase character, if you didn't enter the said format it will prompt you with a message:
  pattern="[0-9][A-Z]{3}"
Demo: http://jsfiddle.net/aoq22s54/

Similarly, if you have a field to accept only five numeric values, use this pattern:
pattern="\d{5}" in this pattern the '\d' stands for numeric values and '{5}' to accept only five characters.
Demo: http://jsfiddle.net/fhcox947/

Let's validate a DD/MM/YYYY date format:
Here's the pattern we need to use for validating this date format - pattern="(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}" 

The first section of this pattern (0[1-9]|[12][0-9]|3[01]) says - use 0 before the first value 1-9 except when the first value is 1/2, and use 0-9 after the first 1/2 value, and when the first values is 3 use only 0/1 after it. Sounds simple? I guess yes :)
Demo: http://jsfiddle.net/j8qpe3ca/

I hope you have understood how the patterns workplease refer this HTML5 pattern website for some common regular expression styles.


Monday, August 11, 2014

Language Specific CSS - The :lang attribute

Do you know the German words are much longer than English? And the Arabic language is read from right-to-left? How about using different font family for Chinese version of your website? Oh! That would be awesome! Can I achieve that via CSS?

Yes! With the help of the :lang(X) pseudo class and with the [lang="x"] attribute selector.
body{ 
 font: normal 14px/1.1em "Lucida Sans Unicode", "Lucida Sans", Arial, Verdana, sans-serif;
 color: RoyalBlue;
}

/*For German version*/
:lang(de) body{ /*or - html[lang="de"] body{}*/
  color: ForestGreen;
}
A demo without the lang attribute: http://jsfiddle.net/a5Ltfge0/
A demo with German version: http://jsfiddle.net/2nkmjzv6/

We can also use it with any container element such as: div, section, article, span and so on. For example
German Content
span[lang="de"]{
  color: red;
}

Sunday, July 13, 2014

Installing Grunt and Plugins

Installing Grunt Task Runner is simple enough when you know how to install it, but it's quite frustrating when you are installing it the first time. Once you started using grunt, you will never leave it. Here are some simple steps to install and run.

1. Download and install NodeJS from here.
Once you are done with the installation of NodeJS, create folder somewhere on your hard-drive and name it as first-grunt-project. Now, create a project structure inside the first-grunt-project folder as:
-first-grunt-project
  -- dev
     -- js 
     -- styles
        -- less 
        -- variables.less 
        -- colors.less 
        -- style.less /*we need to import all less files in this file with @import "variables.less" and so on
     -- css 
        -- style.css 
     -- index.html 
Now right click inside the root folder that is first-grunt-project and select the option Open command window here. Since you have already installed NodeJS just verify the version with a command node --version that should show you the NodeJS version you have installed.

2. Create a new file called package.json and save it at the root directory:
first-grunt-project
  -- package.json
Add this code in package.json file and save it. You can check the current version of package.json here. More information on package.json can be read at the npm website.
{
  "name": "grunt-project", 
  "version": "1.2.5" 
}
3. Go to command window and type npm install -g grunt-cli, this will install the cli for you.
Note: npm stands for Node Package Manager.
And cli stands for Command Line Interface

4. Create a new js file and save it as Gruntfile.js. Add the following code in it. This code is to compile LESS files to CSS. Refer the video below for installing JavaScript plugins.
module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    less: {
      development: {
        options: {
          compress: true,
          yuicompress: true,
          optimization: 2
        },
        files: {
          // target.css file: source.less file
          "dev/styles/style.css": "dev/styles/less/styles.less"
        }
      }
    },
    watch: {
      styles: {
        files: ['dev/styles/less/**/*.less'], // which files to watch
        tasks: ['less'],
        options: {
          nospawn: true
        }
      }
    }
});

//plugins
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');

//tasks
grunt.registerTask('default', ['watch']);

};
5. Go to command window and type npm install grunt --save-dev this will install grunt for you.

You are ready with the installation of grunt, you can confirm that by running grunt --version command. After installing grunt, install the two plugins we are using in the gruntfile.js above for compiling LESS file - that are contrib less and contrib watch.

Videos:
All about packge.json and gruntfile.js:


All about creating a basic project with Grunt:


Create another folder and try with installing grunt first and the cli and then the next steps from here - http://ericnish.io/blog/compile-less-files-with-grunt and see the effect


Saturday, June 21, 2014

Need a candidate who can control DOM

Document Object Model (DOM) is an Application Programming Interface (API) for HTML and XML. I was reading this article at Mozilla Developer Network (MDN) and it has mentioned that DOM is a fully object-oriented representation of web page and we can modify its content and control the visual representation (CSS/styling) by using client side scripting languages like JavaScript.

If the DOM can be controlled by JavaScript for both modifying the content and to control its visual appearance then why a front-end developer is always deprived from writing JavaScript? You may say: No. He/she writes JavaScript for showing/hiding elements, and to create a modal dialog, or to develop some widgets like tabs and accordions. But, we never let him/her write business logic. Wait. That’s the point where you are under-utilizing your resources. Let them write the business logic. Everyone can learn, everyone can improve, and everyone can contribute. Just give them that opportunity—start with small.  

A front-end developer whose job is to create DOM is not allowed to control it with JavaScript and the JavaScript developer who knows very less about DOM is allowed to control it. Isn't it strange? Are we actually letting the right people do the right job, or we are making the working system more complex? Wouldn't it be great if all front-end developers know JavaScript and all JavaScript developers understand the DOM as a first step in development?

It is absolutely necessary to create such all-rounder developers in the organization itself instead of separating these two essential parts of DOM.

The requirements are changing in IT industry today. Most of the companies are looking for the candidates who have in-depth knowledge of the DOM and JavaScript. A few people succeed in it and the majority settles for the one half of it compromising the other. How can we expect such a blend when we haven’t created one?