Working with images on a Retina Display

retina-display-images

Recently I bought a macbook pro with retina display and I realized that in some websites the images were appearing fuzzy and with low resolution. It occurs because the retina display contains more pixels in the same physical size, and a lot of websites are not prepared to it.

Pixels

Let’s assume the following code

<img src="image.png" width="100" height="100" />

The above HTML code will show us on the screen an image of 100px by 100px (CSS pixel) on a non-retina display while on a retina display is necessary an image of 200px by 200px to retain the same physical size.

pixel-density

Resizing Images

1. Single image with double size

Suppose we need to display an image of 100px by 100px in our website. To make it work well on a retina display we need an image of 200px by 200px and resize it using CSS.

.image{
  background-image: url(image@2x.png); /* image@2x.png = 200px by 200px */
  background-size: 100px 100px;
  height: 100px;
  width: 100px;
}

We could make it this way as well.

<img src="image@2x.png" width="100" height="100" />

Both work fine but there is best ways to do it. If you are using a non-retina display, why do you need to load a double size image? You don’t! Let’s see the next examples.

2. CSS: -webkit-image-set

This option is very useful and work well with image sprites. The browser is also smart enough to know which image should download. It means that who has retina display should spend more data usage.

.image{
  background-image: url(image.png);
  background-image: -webkit-image-set(url(image.png) 1x, url(image@2x.png) 2x);
  background-size: 100px 100px;
  height: 100px;
  width: 100px;
}

3. HTML: srcset

The srcset attribute on img is very similar to -webkit-image-set. On browsers without srcset support, the value of the src attribute will be used. On regular resolution displays, the 1x variant of the srcset will be used. On displays with 2 device pixels per CSS pixel, the 2x variant of the srcset will be used.

<img src="image.png" srcset="image.png 1x, image@2x.png 2x" />

4. Using JavaScript to replace all the images

Replace low resolution images with double resolution images can take a long time. We can use JavaScript to replace all images in a webpage. I’ve made my own script and worked like a charm.

(function(){

  if (window.devicePixelRatio > 1) {

    var images = document.getElementsByTagName("img");

    for(var i=0; i<images.length; i++) {

      images[i].width  = images[i].clientWidth;
      images[i].height  = images[i].clientHeight;
      images[i].src = images[i].src.replace(".", "@2x.");

    };

  };

})();

Network test

The test is very simple and basically we can say that who has a computer with a retina display is spending more data usage.

Non-retina display

network non-retina display

Retina display

network retina display

Conclusion

We have seen some ways on how to implement images with good definition on devices with retina displays. If you are a web designer or just want to improve your knowledge, I really recommend these techniques.

If you are working with icons, a good option is to use @font-faces instead of images. Today, there are many good quality icon fonts that can meet your requirements for website design.

Favicons also need to be in a better quality on a retina display. You can export a 32px version to make a favicon Retina ready.

AngularJS ngClick and ngRepeat

ngclick

Second article about AngularJS and today we are going to see ngClick and ngRepeat directives. I’ve decided to write about these directives because they are very important and we use them all the time.

Let’s assume the following code

(function(){

  var myApp = angular.module('myApp', []);

  myApp.controller("myController", function($scope){

  });

})();

Wrapping your Javascript in a closure is a good habit!

<!DOCTYPE html>
<html ng-app="myApp">
  <head>
    <title>AngularJS ngClick and ngRepeat</title>
  </head>
  <body ng-controller="myController">

    <!-- ngClick example goes here -->

    <!-- ngRepeat example goes here -->

    <script src="angular.min.js"></script>
    <script src="app.js"></script>
  </body>
</html>

ngClick

The first thing we need to do is to create a button in our HTML code and through the ngClick directive call the click function. After that, we will define the click function inside the controller.

<button ng-click="click();">Click</button>

{{ message }}
myApp.controller("myController", function($scope){

  $scope.click = function(){

    $scope.message = "It's working!";

  }

}

Great. The button is working through the ngClick directive and the message expression we’ve created was replaced by “It’s working”.

ngRepeat

When we work with AngularJS, objects and arrays are used daily. Let’s continue our example including an array of objects and store the data inside the controller

myApp.controller("myController", function($scope){
  
  $scope.message = "It's working!";
  $scope.users = json; // Storing data inside the controller

});

var json = [
  {name: "Guilherme", email: "guilherme@test.com", age: "22"},
  {name: "Milena", email: "milena@test.com", age: "26"}
];

Now we’ve got a user array, simulating a JSON in the real life ;) How do we print out this data inside our webpage? We need to use the ngRepeat directive.

<ul>
  <li ng-repeat="user in users">{{ user.name }}</li>
</ul>

The page has been printed out with all the names. But we need to print out the email as well as the age. What do you think about changing the list to a table? It will be easy.

<table>
  <tr ng-repeat="user in users">
    <td>{{ user.name }}</td>
    <td>{{ user.email }}</td>
    <td>{{ user.age }}</td>
  </tr>
</table>

What if we want to keep our list and print out the name, email and age?

<ul>
  <li ng-repeat-start="user in users">{{ user.name }}</li>
  <li>{{ user.age }}</li>
  <li ng-repeat-end>{{ user.email }}</li>
</ul>

Conclusion

The ngClick and ngRepeat directives are extremely easy to work with. JSON works great with the ngRepeat directive and it’s very common to use. You can find these examples on GitHub https://github.com/guinatal/blog-examples

Understanding CSS Combinators

Combinators

Have you already used the following combinator before?

div ~ p {
  background-color: skyblue;
}

We have just seen the general sibling selector and it can be very useful. Let’s check it out! There are four combinators in CSS3.

  • Descendant Selector
  • Child Selector
  • Adjacent Sibling Selector
  • General Sibling Selector CSS3

Descendant Selector

The descendant selector matches all elements that are descendants of a specified element. The following example selects all p elements inside div elements:

div p {
  background-color: skyblue;
}
<article>
  <h1>Descendant Selector</h1>
  <div>
    <p>Descendant Selector 1</p>
    <p>Descendant Selector 2</p>
    <section>
      <p>Descendant Selector 3</p>
      <p>Descendant Selector 4</p>
    </section>
  </div>
  <p>Descendant Selector 5</p>
  <p>Descendant Selector 6</p>
</article>

Descendant Selector

Child Selector

The child selector selects all elements that are the immediate children of a specified element. The following example selects all p elements that are immediate children of a div element:

div > p {
  background-color: skyblue;
}
<article>
  <h1>Child Selector</h1>
  <div>
    <p>Child Selector 1</p>
    <p>Child Selector 2</p>
    <section>
      <p>Child Selector 3</p>
      <p>Child Selector 4</p>
    </section>
  </div>
  <p>Child Selector 5</p>
  <p>Child Selector 6</p>
</article>

Child Selector

Adjacent Sibling Selector

The adjacent sibling selector selects all elements that are the adjacent siblings of a specified element. Sibling elements must have the same parent element, and “adjacent” means “immediately following”. The following example selects all p elements that are placed immediately after div elements:

div + p {
  background-color: skyblue;
}
<article>
  <h1>Adjacent Sibling Selector</h1>
  <div>
    <p>Adjacent Sibling Selector 1</p>
    <p>Adjacent Sibling Selector 2</p>
    <section>
      <p>Adjacent Sibling Selector 3</p>
      <p>Adjacent Sibling Selector 4</p>
    </section>
  </div>
  <p>Adjacent Sibling Selector 5</p>
  <p>Adjacent Sibling Selector 6</p>
</article>

Adjacent Sibling Selector

General Sibling Selector

The general sibling selector selects all elements that are siblings of a specified element. The following example selects all p elements that are siblings of div elements:

div ~ p {
  background-color: skyblue;
}
<article>
  <h1>General Sibling Selector</h1>
  <div>
    <p>General Sibling Selector 1</p>
    <p>General Sibling Selector 2</p>
    <section>
      <p>General Sibling Selector 3</p>
      <p>General Sibling Selector 4</p>
    </section>
  </div>
  <p>General Sibling Selector 5</p>
  <p>General Sibling Selector 6</p>
</article>

General Sibling Selector

Conclusion

If you are a new learner or just improving your CSS skills, you need to know that CSS Combinators are used all the time by front-end developers. We have just seen very basic examples and most of the times they are used just like that. But you can also make different combinations using all of them.

First AngularJS App

angularjs

Hello! This is my first post and I have decided to write about AngularJS. I am still improving my skills with Angular and I would like to share my knowledge. Today, we are going to see how to start an AngularJS App and learn basic concepts like Module, Directives and Expressions.

<!DOCTYPE html>
<html>
  <head>
    <title>First AngularJS App</title>
  </head>
  <body>
    <h1>First AngularJS App</h1>
  </body>
</html>

The first thing we need to do is to import the AngularJS library and initialize the application through the ng-app directive. After that, the app is ready to read Angular codes.

<!DOCTYPE html>
<html ng-app> <!-- Directive -->
  <head>
    <title>First AngularJS App</title>
  </head>
  <body>
    <h1>First AngularJS App</h1>

    <!-- Expressions -->
    <p>8 + 5 = {{ 8 + 5 }}</p>
    <p>100 / 2 = {{ 100 / 2 }}</p>
    <p>100 * 2 + 1 = {{ 100 * 2 + 1 }}</p>
    <p>Currency = {{ 100 | currency }}</p>

    <!-- AngularJS Library -->
    <script src="angular.min.js"></script>
  </body>
</html>

AngularJS extends HTML attributes with Directives, and binds data to HTML with Expressions. In the following link you have a list of directives https://docs.angularjs.org/api/ng#directive

Controllers

AngularJS applications are controlled by controllers. The ng-controller directive defines the application controller.
First of all, we need to create an Angular Module for our application.

<html ng-app="myApp">

It is time to build our application file. Let’s create the app.js file and import it. As you can see, the controller is attached (inside) to the application.

<script src="app.js"></script>
(function(){
  var myApp = angular.module('myApp', []);

  // Controller
  myApp.controller("myController", function(){

    this.user = obj;

  });

  var obj = {
    name: 'Guilherme',
    password: '123',
    age: '23'
  }

})();

In our current HTML, we have the directive (ng-controller), controller name (myController) and an Alias (controller).

<!DOCTYPE html>
<html ng-app="myApp"> <!-- Directive -->
  <head>
    <title>First AngularJS App</title>
  </head>
  <body>
    <h1>First AngularJS App</h1>

    <!-- Expressions -->
    <article>
      <h1>Expressions</h1>
      <p>8 + 5 = {{ 8 + 5 }}</p>
      <p>100 / 2 = {{ 100 / 2 }}</p>
      <p>100 * 2 + 1 = {{ 100 * 2 + 1 }}</p>
      <p>Currency = {{ 100 | currency }}</p>
    </article>

    <!-- Controller -->
    <article ng-controller="myController as controller">
      <h1>Controller</h1>
      <p>{{ controller.user.name }}</p>
      <p>{{ controller.user.password }}</p>
      <p>{{ controller.user.age }}</p>
    </article>

    <!-- AngularJS Library -->
    <script src="angular.min.js"></script>
    <!-- External Javascript -->
    <script src="app.js"></script>
  </body>
</html>

Conclusion

We have just made a very simple app using AngularJS, but I believe that now you (if had never seen) have an idea of the power and simplicity of this great javascript framework. I did and recommend the free course of AngularJS. http://campus.codeschool.com/courses/shaping-up-with-angular-js