Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Web Design

132 Articles
article-image-creating-css-stylus-preprocessor
Packt
26 Nov 2014
5 min read
Save for later

Creating CSS via the Stylus preprocessor

Packt
26 Nov 2014
5 min read
Instead of manually typing out each line of CSS you're going to require for your Ghost theme, we're going to get you setup to become highly efficient in your development through use of the CSS preprocessor named Stylus. Stylus can be described as a way of making CSS smart. It gives you the ability to define variables, create blocks of code that can be easily reused, perform mathematical calculations, and more. After Stylus code is written, it is compiled into a regular CSS file that is then linked into your design in the usual fashion. It is an extremely powerful tool with many capabilities, so we won't go into them all here; however, we will cover some of the essential features that will feature heavily in our theme development process. This article by Kezz Bracey, David Balderston, and Andy Boutte, author of the book Getting Started with Ghost, covers how to create CSS via the Stylus preprocessor. (For more resources related to this topic, see here.) Variables Stylus has the ability to create variables to hold any piece of information from color codes to numerical values for use in your layout. For example, you could map out the color scheme of your design like this: default_background_color = #F2F2F2 default_foreground_color = #333 default_highlight_color = #77b6f9 You could then use these variables all throughout your code instead of having to type them out multiple times: body { background-color: default_background_color; } a { color: default_highlight_color; } hr { border-color: default_foreground_color; } .post { border-color: default_highlight_color; color: default_foreground_color; } After the preceding Stylus code was compiled into CSS, it would look like this: body { background-color: #F2F2F2;} a { color: #77b6f9; } hr { border-color: #333; } .post { border-color: #77b6f9; color: #333; } So not only have you been saved the trouble of typing out these color code values repeatedly, which in a real style sheet means a lot of work, but you can also now easily update the color scheme of your site simply by changing the value of the variables you created. Variables come in very handy for many purposes, as you'll see when we get started on theme creation. Stylus syntax Stylus code uses a syntax that reads very much like CSS, but with the ability to take shortcuts in order to code faster and more smoothly. With Stylus, you don't need to include curly braces, colons, or semicolons. Instead, you use tab indentations, spaces, and new lines. For example, the code I used in the last section could actually be written like this in Stylus: body background-color default_background_color   a color default_highlight_color   hr border-color default_foreground_color   .post border-color default_highlight_color color default_foreground_color You may think at first glance that this code is more difficult to read than regular CSS; however, shortly we'll be getting you running with a syntax highlighting package that will make your code look like this: With the syntax highlighting package in place you don't need punctuation to make your code readable as the colors and emphasis allow you to easily differentiate between one thing and another. The chances are very high that you'll find coding in this manner much faster and easier than regular CSS syntax. However, if you're not comfortable, you can still choose to include the curly braces, colons, and semicolons you're used to and your code will still compile just fine. The golden rules of writing in Stylus syntax are as follows: After a class, ID, or element declaration, use a new line and then a tab indentation instead of curly braces Ensure each line of a style is also subsequently tab indented After a property, use a space instead of a colon At the end of a line, after a value, use a new line instead of a semicolon Mixins Mixins are a very useful way of preventing yourself from having to repeat code, and also to allow you to keep your code well organized and compartmentalized. The best way to understand what a mixin is, is to see one in action. For example, you may want to apply the same font-family, font-weight, and color to each of your heading tags. So instead of writing the same thing out manually for each H tag level, you could create a mixin as follows: header_settings() font-family Georgia font-weight 700 color #454545 You could then call that mixin into the styles for your heading tags: h1 header_settings() font-size 3em h2 header_settings() font-size 2.25em h3 header_settings() font-size 1.5em When compiled, you would get the following CSS: h1 { font-family: Georgia; font-weight: 700; color: #454545; font-size: 3em; }   h2 { font-family: Georgia; font-weight: 700; color: #454545; font-size: 2.25em; } h3 { font-family: Georgia; font-weight: 700; color: #454545; font-size: 1.5em; } As we move through the Ghost theme development process, you'll see just how useful and powerful Stylus is, and you'll never want to go back to handcoding CSS again! Summary You now have everything in place and ready to begin your Ghost theme development process. You understand the essentials of the Stylus, the means by which we'll be creating your theme's CSS. Resources for Article: Further resources on this subject: Advanced SOQL Statements [Article] Enabling your new theme in Magento [Article] Introduction to a WordPress application's frontend [Article]
Read more
  • 0
  • 0
  • 14156

article-image-building-responsive-image-sliders
Packt
20 Nov 2013
7 min read
Save for later

Building Responsive Image Sliders

Packt
20 Nov 2013
7 min read
(For more resources related to this topic, see here.) Responsive image sliders Opening a website and seeing an image slider in the header area is common nowadays. Image sliders display highlighted content, which are really useful, within a limited space. Although the free space is more limited when a site is viewed through mobile devices, the slider element still catches the client's attention. The difference between how much area can be used to display a highlighted content and the resource available to render it is really big if compared with desktop, where we generally do not have problems with script performance, and the interaction of each transition is performed through the use of arrow signs to switch images. When the responsive era started, the way that people normally interacted with image sliders was observed, and changes, such as the way to change each slide, were identified, based on the progressive enhancement concept. The solution was to provide a similar experience to the users of mobile devices: the adoption of gestures and touches on image slider elements for devices that accept them instead of displaying fallbacks. With the constant evolution of browsers and technologies, there are many image slider plugins with responsive characteristics. My personal favorite plugins are Elastislide, FlexSlider2, ResponsiveSlides, Slicebox, and Swiper. There are plenty available, and the only way to find one you truly like is to try them! Let's look in detail at how each of them works. Elastislide plugin Elastislide is a responsive image slider that will adapt its size and behavior in order to work on any screen size based on jQuery. This jQuery plugin handles the slider's structure, including images with percentage-based width inside, displaying it horizontally or vertically with a predefined minimum number of shown images. Elastislide is licensed under the MIT license and can be downloaded from https://github.com/codrops/Elastislide. When we are implementing an image slider, simply decreasing the container size and displaying a horizontal scrollbar will not solve the problem for small devices gracefully. The recommendation is to resize the internal items too. Elastislide fixes this resizing issue very well and defines the minimum elements we want to show instead of simply hiding those using CSS. Also, Elastislide uses a complementary and customized version of jQuery library named jQuery++. jQuery++ is another JavaScript library very useful to deal with DOM and special events. In this case, Elastislide has a custom version of jQuery++, which enables the plugin working with swipe events on touch devices. How to do it As we will see four different applications of this plugin for the same carousel, we will use the same HTML carousel's structure and may modify only the JavaScript before executing the plugin, specifying the parameters: <ul id="carousel" class="elastislide-list"> <li><a href="#"><img src = "image-photo.jpg" /></a></li> <li><a href="#"><img src = "image-sky.jpg" /></a></li> <li><a href="#"><img src = "image-gardem.jpg" /></a></li> <li><a href="#"><img src = "image-flower.jpg" /></a></li> <li><a href="#"><img src = "image-belt.jpg" /></a></li> <li><a href="#"><img src = "image-wall.jpg" /></a></li> <li><a href="#"><img src = "image-street.jpg" /></a></li> </ul> At the bottom of the DOM (before the </body> closing tag), we will need to include the jQuery and jQuery++ libraries (required for this solution), and then the ElastiSlide script: <script src = "http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src = "js/jquerypp.custom.js"></script> <script src = "js/modernizr.custom.17475.js"></script> <script src = "js/jquery.elastislide.js"></script> Then, include the CSS stylesheet inside the <head> tag: <link rel="stylesheet" type="text/css" href="css/elastislide.css" /> Alright, now we already have the basis to show four different examples. For each example, you must add different parameters when executing the plugin script, in order to get different rendering, depending on the project need. Example 1 – minimum of three visible images (default) In this first example, we will see the default visual and behavior, and whether we will put the following code right after it, including the ElastiSlide plugin: <script type="text/javascript"> $('#carousel').elastislide(); </script> The default options that come with this solution are: Minimum three items will be shown Speed of scroll effect is 0.5 seconds Horizontal orientation Easing effect is defined as ease-in-out The carousel will start to show the first image on the list The following screenshot represents what the implementation of this code will look like. Look at the difference between its versions shown on tablets and smartphones: Example 2 – vertical with a minimum of three visible images There is an option to render the carousel vertically, just by changing one parameter. Furthermore, we may speed up the scrolling effect. Remember to include the same files used in Example 1, and then insert the following code into the DOM: <script type="text/javascript"> $('#carousel').elastislide({ orientation: 'vertical', speed: 250 }); </script> By default, three images are displayed as a minimum. But this minimum value can be modified as we will see in our next example: Example 3 – fixed wrapper with a minimum of two visible images In this example, we will define the minimum visible items in the carousel, the difference may be noticed when the carousel is viewed on small screens and the images will not reduce too much. Also, we may define the image to be shown starting from the third one. Remember to include the same fi les that were used in Example 1, and then execute the scripts informing the following parameters and positioning them after including the ElastiSlide plugin: <script> $('#carousel').elastislide({ minItems: 2, start: 2 }); </script> Example 4 – minimum of four images visible in an image gallery In the fourth example, we can see many JavaScript implementations. However, the main objective of this example is to show the possibility which this plugin provides to us. Through the use of plugin callback functions and private functions we may track the click and the current image, and then handle this image change on demand by creating an image gallery: <script> var current = 0; var $preview = $('#preview'); var $carouselEl = $('#carousel'); var $carouselItems = $carouselEl.children(); var carousel = $carouselEl.elastislide({ current: current, minItems: 4, onClick: function(el, pos, evt){ changeImage(el, pos); evt.preventDefault(); }, onReady: function(){ changeImage($carouselItems.eq(current), current); } }); function changeImage(el, pos) { $preview.attr('src', el.data('preview')); $carouselItems.removeClass('current-img'); el.addClass('current-img'); carousel.setCurrent(pos); } </script> For this purpose, ElastiSlide may not have big advantages if compared with other plugins because it depends on our extra development to finalize this gallery. So, let's see what the next plugin offers to solve this problem. Summary This article, explains four different image-slider plugins and their implementation. These examples are elaborative for the use of the plugins. Resources for Article: Further resources on this subject: Top Features You Need to Know About – Responsive Web Design [Article] Different strategies to make responsive websites [Article] So, what is KineticJS? [Article]
Read more
  • 0
  • 0
  • 13684

article-image-optimizing-jquery-applications
Packt
13 Jan 2016
19 min read
Save for later

Optimizing jQuery Applications

Packt
13 Jan 2016
19 min read
This article, by Thodoris Greasidis, the author of jQuery Design Patterns, presents some optimization techniques that can be used to improve the performance of jQuery applications, especially when they become large and complex. We will start with simple practices to write performant JavaScript code, and learn how to write efficient CSS selectors in order to improve the page's rendering speed and DOM traversals using jQuery. We will continue with jQuery-specific practices, such as caching of jQuery Composite Collection Objects, how to minimize DOM manipulations, and how to use the Delegate Event Observer pattern as a good example of the Flyweight pattern. (For more resources related to this topic, see here.) Optimizing the common JavaScript code In this section, we will analyze some performance tips that are not jQuery-specific and can be applied to most JavaScript implementations. Writing better for loops When iterating over the items of an array or an array-like collection with a for loop, a simple way to improve the performance of the iteration is to avoid accessing the length property on every loop. This can easily be done by storing the iteration length in a separate variable, which is declared just before the loop or even along with it, as shown in the following code: for (var i = 0, len = myArray.length; i < len; i++) {     var item = myArray[i];     /*...*/ } Moreover, if we need to iterate over the items of an array that does not contain "falsy" values, we can use an even better pattern, which is commonly applied when iterating over arrays that contain objects: var objects = [{ }, { }, { }]; for (var i = 0, item; item = objects[i]; i++) {     console.log(item); } In this case, instead of relying on the length property of the array, we are exploiting the fact that access to an out-of-bounds position of the array returns undefined, which is "falsy" and stops the iteration. Another sample case in which this trick can be used is when iterating over Node Lists or jQuery Composite Collection Objects, as shown in the following code: var anchors = $('a'); // or document.getElementsByTagName('a'); for (var i = 0, anchor; anchor = anchors[i]; i++) {     console.log(anchor.href); } For more information on the "truthy" and "falsy" JavaScript values, you can visit https://developer.mozilla.org/en-US/docs/Glossary/Truthy and https://developer.mozilla.org/en-US/docs/Glossary/Falsy. Using performant CSS selectors Even though Sizzle (jQuery's selector engine) hides the complexity of DOM traversals that are based on a complex CSS selector, we should have an idea of how our selectors perform. By understanding how CSS selectors can be matched against the elements of the DOM can help us write more efficient selectors, which will perform in a better way when used with jQuery. The key characteristic of efficient CSS selectors is specificity. According to this, IDs and Class selectors will always be more efficient than selectors with many results, such as div and *. When writing complex CSS selectors, keep in mind that they are evaluated from right to left, and a selector gets rejected after recursively testing it against every parent element until the root of the DOM is reached. As a result, try to be as specific as possible with the right-most selector in order to cut down the matched elements as early as possible during the execution of the selector: // initially matches all the anchors of the page // and then removes those that are not children of the container $('.container a');   // performs better, since it matches fewer elements // in the first step of the selector's evaluation $('.container .mySpecialLinks'); Another performance tip is to use the Child Selector (parent > child) wherever applicable in an effort to eliminate the recursion over all the hierarchies of the DOM tree. A great example of this can be applied in cases where the target elements can be found at a specific descendant level of a common ancestor element: // initially matches all the div's of the page, which is bad $('.container div') ;   // a lot better better, since it avoids the recursion // until the root of the DOM tree $('.container > div');   // best of all, but can't be used always $('.container > .specialDivs'); The same tips can also be applied to CSS selectors that are used to style pages. Even though browsers have been trying to optimize any given CSS selector, the tips mentioned earlier can greatly reduce the time that is required to render a web page. For more information on jQuery CSS selector performance, you can visit http://learn.jquery.com/performance/optimize-selectors/. Writing efficient jQuery code Let's now proceed and analyze the most important jQuery-specific performance tips. For more information on the most up-to-date performance tips about jQuery, you can go to the respective page of jQuery's Learning Center at http://learn.jquery.com/performance. Minimizing DOM traversals Since jQuery has made DOM traversals such simple tasks, a big number of web developers have started to overuse the $() function everywhere, even in subsequent lines of code, making their implementations slower by executing unnecessary code. One of the main reasons that the complexity of the operation is so often overlooked is the elegant and minimalistic syntax that jQuery uses. Despite the fact that JavaScript browser engines have already become more faster, with performance comparable with many compiled languages, the DOM API is still one of their slowest parts, and as a result, developers have to minimize their interactions with it. Caching jQuery objects Storing the result of the $() function to a local variable, and subsequently, using it to operate on the retrieved elements is the simplest way to eliminate unnecessary executions of the same DOM traversals: var $element = $('.Header'); if ($element.css('position') === 'static') {     $element.css({ position: 'relative' }); } $element.height('40px'); $element.wrapInner('<b>'); It is also highly suggested that you store Composite Collection Objects of important page elements as properties of our modules and reuse them everywhere in our application: window.myApp = window.myApp || {}; myApp.$container = null; myApp.init = function() {     myApp.$container = $('.myAppContainer');     }; $(document).ready(myApp.init); Caching retrieved elements on modules is a very good practice when the elements are not going to be removed from the page. Keep in mind that when dealing with elements with shorter lifespans, in order to avoid memory leaks, you either need to ensure that you clear their references when they are removed from the page, or have a fresh reference retrieved when required and cache it only inside your functions. Scoping element traversals Instead of writing complex CSS selectors for your traversals, as follows: $('.myAppContainer .myAppSection'); You can instead have the same result in a more efficient way using an already retried ancestor element to scope the DOM traversal. This way, you are not only using simpler CSS selectors that are faster to match against page elements, but you are also reducing the number of elements that need to be checked. Moreover, the resulting implementations have less code repetitions (they are DRYer), and the CSS selectors used are simple and more readable: var $container = $('.myAppContainer'); $container.find('.myAppSection'); Additionally, this practice works even better with module-wide cached elements: var $sections = myApp.$container.find('.myAppSection'); Chaining jQuery methods One of the characteristics of all jQuery APIs is that they are fluent interface implementations that enable you to chain several method invocations on a single Composite Collection Object: $('.Content').html('')     .append('<a href="#">')     .height('40px')     .wrapInner('<b>'); Chaining allows us to reduce the number of used variables and leads us to more readable implementations with less code repetitions. Don't overdo it Keep in mind that jQuery also provides the $.fn.end() method (http://api.jquery.com/end/) as a way to move back from a chained traversal: $('.box')     .filter(':even')     .find('.Header')     .css('background-color', '#0F0')     .end()     .end() // undo the filter and find traversals     .filter(':odd') // applied on  the initial .box results     .find('.Header')     .css('background-color', '#F00'); Even though this is a handy method for many cases, you should avoid overusing it, since it can affect the readability of your code. In many cases, using cached element collections instead of $.fn.end() can result in faster and more readable implementations. Improving DOM manipulations Extensive use of the DOM API is one of the most common things that makes an application slower, especially when it is used to manipulate the state of the DOM tree. In this section, we will showcase some tips that can reduce the performance hit when manipulating the DOM tree. Creating DOM elements The most efficient way to create DOM elements is to construct an HTML string and append it to the DOM tree using the $.fn.html() method. Additionally, since this can be too restrictive for some use cases, you can also use the $.fn.append() and $.fn.prepend() methods, which are slightly slower but can be better matches for your implementation. Ideally, if multiple elements need to be created, you should try to minimize the invocation of these methods by creating an HTML string that defines all the elements and then inserting it into the DOM tree, as follows: var finalHtml = ''; for (var i = 0, len = questions.length; i < len; i++) {     var question = questions[i];     finalHtml += '<div><label><span>' + question.title + ':</span>' + '<input type="checkbox" name="' + question.name + '" />' + '</label></div>'; } $('form').html(finalHtml); Another way to achieve the same result is using an array to store the HTML for each intermediate element and then joining them right before inserting them into the DOM tree: var parts = []; for (var i = 0, len = questions.length; i < len; i++) {     var question = questions[i];     parts.push('<div><label><span>' + question.title + ':</span>' +     '<input type="checkbox" name="' + question.name + '" />' +     '</label></div>'); } $('form').html(parts.join('')); This is a commonly used pattern, since until recently it was performing better than concatenating the intermediate results with "+=". Styling and animating Whenever possible, try using CSS classes for your styling manipulations by utilizing the $.fn.addClass() and $.fn.removeClass() methods instead of manually manipulating the style of elements with the $.fn.css() method. This is especially beneficial when you need to style a big number of elements, since this is the main use case of CSS classes and the browsers have already spent years optimizing it. As an extra optimization step used to minimize the number of manipulated elements, you can try to apply CSS classes on a single common ancestor element, and use a descendant CSS selector to apply your styling ( https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_selectors). When you still need to use the $.fn.css() method; for example, when your implementation needs to be imperative, we prefer using the invocation overload that accepts object parameters: http://api.jquery.com/css/#css-properties. This way, when applying multiple styles on elements, the required method invocations are minimized, and your code also gets better organized. Moreover, we need to avoid mixing methods that manipulate the DOM with methods that are read from the DOM, since this will force a reflow of the page, so that the browser can calculate the new positions of the page elements. Instead of doing something like this: $('h1').css('padding-left', '2%'); $('h1').css('padding-right', '2%'); $('h1').append('<b>!!</b>'); var h1OuterWidth = $('h1').outerWidth();   $('h1').css('margin-top', '5%'); $('body').prepend('<b>--!!--</b>'); var h1Offset = $('h1').offset(); We will prefer grouping the nonconflicting manipulations together like this: $('h1').css({     'padding-left': '2%',     'padding-right': '2%',     'margin-top': '5%' }).append('<b>!!</b>'); $('body').prepend('<b>--!!--</b>');   var h1OuterWidth = $('h1').outerWidth(); var h1Offset = $('h1').offset(); This way, the browser can try to skip some rerenderings of the page, resulting in less pauses of the execution of your code. For more information on reflows, you can refer to https://developers.google.com/speed/articles/reflow. Lastly, note that all jQuery generated animations in v1.x and v2.x are implemented using the setTimeout() function. This is going to change in v3.x of jQuery, which is designed to use the requestAnimationFrame() function, which is a better match to create imperative animations. Until then, you can use the jQuery-requestAnimationFrame plugin (https://github.com/gnarf/jquery-requestAnimationFrame), which monkey-patches jQuery to use the requestAnimationFrame() function for its animations when it is available. Manipulating detached elements Another way to avoid unnecessary repaints of the page while manipulating DOM elements is to detach the element from the page and reattach it after completing your manipulations. Working with a detached in-memory element is more faster and does not cause reflows of the page. In order to achieve this, we will use the $.fn.detach() method, which in contrast with $.fn.remove() preserves all event handlers and jQuery data on the detached element: var $h1 = $('#pageHeader'); var $h1Cont = $h1.parent(); $h1.detach();   $h1.css({     'padding-left': '2%',     'padding-right': '2%',     'margin-top': '5%' }).append('<b>!!</b>');   $h1Cont.append($h1); Additionally, in order to be able to place the manipulated element back to its original position, we can create and insert a hidden "placeholder" element into the DOM. This empty and hidden element does not affect the rendering of the page and is removed right after the original item is placed back into its original position: var $h1PlaceHolder = $('<div style="display: none;"></div>'); var $h1 = $('#pageHeader'); $h1PlaceHolder.insertAfter($h1);   $h1.detach();   $h1.css({     'padding-left': '2%',     'padding-right': '2%',     'margin-top': '5%' }).append('<b>!!</b>');   $h1.insertAfter($h1PlaceHolder); $h1PlaceHolder.remove(); $h1PlaceHolder = null; For more information on the $.fn.detach() method, you can visit its documentation page at http://api.jquery.com/detach/. Using the Flyweight pattern According to computer science, a Flyweight is an object that is used to reduce the memory consumption of an implementation that provides the functionality and/or data that will be shared with other object instances. The prototypes of JavaScript constructor functions can be characterized as Flyweights to some degree since every object instance can use all the methods and properties that are defined on its Prototype, until it overwrites them. On the other hand, classical Flyweights are separate objects from the object family that they are used with and often hold the shared data and functionality in special data structures. Using Delegated Event Observers A great example of Flyweights in jQuery applications are Delegated Event Observers that can greatly reduce the memory requirements of an implementation by working as a centralized event handler for a large group of elements. This way, we can avoid the cost of setting up separate observers and event handlers for every element and utilize the browser's event bubbling mechanism to observe them on a single common ancestor element and filter their origin. Moreover, this pattern can also simplify our implementation when we need to deal with dynamically constructed elements since it removes the need of attaching extra event handlers for each created element. For example, the following code attaches a single observer on the common ancestor element of several <button> elements. Whenever a click happens on one of the <button> elements, the event will bubble up to the parent element with the buttonsContainer CSS class, and the attached handler will be fired. Even if we add extra buttons later to that container, clicking on them will still fire the original handler: $('.buttonsContainer').on('click', 'button', function() {     var $button = $(this);     alert($button.text()); }); The actual Flyweight object is the event handler along with the callback that is attached to the ancestor element. Using $.noop() The jQuery library offers the $.noop() method, which is actually an empty function that can be shared with implementations. Using empty functions as default callback values can simplify and increase the readability of an implementation by reducing the number of the required if statements. Such a thing can be greatly beneficial for jQuery plugins that encapsulate the complex functionality: function doLater(callbackFn) {     setTimeout(function() {         if (callbackFn) {             callbackFn();         }     }, 500); }   // with $.noop() function doLater(callbackFn) {     callbackFn = callbackFn || $.noop();     setTimeout(function() {         callbackFn();     }, 500); } In such situations, where the implementation requirements or the personal taste of the developer leads to using empty functions, the $.noop() method can be beneficial to lower the memory consumption by sharing a single empty function instance among all the different parts of an implementation. As an added benefit of using the $.noop() method for every part of an implementation, we can also check whether a passed function reference is actually the empty function by simply checking whether callbackFn is equal to $.noop(). For more information, you can visit its documentation page at http://api.jquery.com/jQuery.noop/. Using the $.single plugin Another simple example of the Flyweight pattern in a jQuery application is the jQuery.single plugin, as described by James Padolsey in his article 76 bytes for faster jQuery, which tries to eliminate the creation of new jQuery objects in cases where we need to apply jQuery methods on a single page element. The implementation is quite small and creates a single jQuery Composite Collection Object that is returned on every invocation of the jQuery.single() method, containing the page element that was used as an argument: jQuery.single = (function(){     var collection = jQuery([1]); // Fill with 1 item, to make sure length === 1     return function(element) {         collection[0] = element; // Give collection the element:         return collection; // Return the collection:     }; }()); The jQuery.single plugin can be quite useful when used in observers, such as $.fn.on() and iterations with methods, such as $.each(): $buttonsContainer.on('click', '.button', function() {     // var $button = $(this);     var $button = $.single(this); // this is not creating any new object     alert($button); }); The advantages of using the jQuery.single plugin originate from the fact that we are creating less objects, and as a result, the browser's Garbage Collector will also have less work to do when freeing the memory of short-lived objects. Keep in mind that the side effects of having a single jQuery object returned by every invocation of the $.single() method, and the fact that the last invocation argument will be stored until the next invocation of the method: var buttons = document.getElementsByTagName('button'); var $btn0 = $.single(buttons[0]); var $btn1 = $.single(buttons[1]); $btn0 === $btn1 Also, if you use something, such as $btn1.remove(), then the element will not be freed until the next invocation of the $.single() method, which will remove it from the plugin's internal collection object. Another similar but more extensive plugin is the jQuery.fly plugin, which supports the case of being invoked with arrays and jQuery objects as parameters. For more information on jQuery.single and jQuery.fly, you can visit http://james.padolsey.com/javascript/76-bytes-for-faster-jquery/ and https://github.com/matjaz/jquery.fly. On the other hand, the jQuery implementation that handles the invocation of the $() method with a single page element is not complex at all and only creates a single simple object: jQuery = function( selector, context ) {     return new jQuery.fn.init( selector, context ); }; /*...*/ jQuery = jQuery.fn.init = function( selector, context ) {     /*... else */     if ( selector.nodeType ) {         this.context = this[0] = selector;         this.length = 1;         return this;     } /* ... */ }; Moreover, the JavaScript engines of modern browsers have already become quite efficient when dealing with short lived objects, since such objects are commonly passed around an application as method invocation parameters. Summary In this article, we learned some optimization techniques that can be used to improve the performance of jQuery applications, especially when they become large and complex. We initially started with simple practices to write performant JavaScript code, and learned how to write efficient CSS selectors in order to improve the page's rendering speed and DOM traversals using jQuery. We continued with jQuery-specific practices, such as caching of jQuery Composite Collection Objects and ways to minimize DOM manipulations. Lastly, we saw some representatives of the Flyweight pattern and took a look at an example of the Delegated Event Observer pattern. Resources for Article: Further resources on this subject: Working with Events [article] Learning jQuery [article] Preparing Your First jQuery Mobile Project [article]
Read more
  • 0
  • 0
  • 13604

article-image-mastering-fundamentals
Packt
08 Apr 2016
10 min read
Save for later

Mastering of Fundamentals

Packt
08 Apr 2016
10 min read
In this article by Piotr Sikora, author of the book Professional CSS3, you will master box model, floating's troubleshooting positioning and display types. Readers, after this article, will be more aware of the foundation of HTML and CSS. In this article, we shall cover the following topics: Get knowledge about the traditional box model Basics of floating elements The foundation of positioning elements on webpage Get knowledge about display types (For more resources related to this topic, see here.) Traditional box model Understanding box model is the foundation in CSS theories. You have to know the impact of width, height, margin, and borders on the size of the box and how can you manage it to match the element on a website. Main questions for coders and frontend developers on interviews are based on box model theories. Let's begin this important lesson, which will be the foundation for every subject. Padding/margin/border/width/height The ingredients of final width and height of the box are: Width Height Margins Paddings Borders For a better understanding of box model, here is the image from Chrome inspector: For a clear and better understanding of box model, let's analyze the image: On the image, you can see that, in the box model, we have four edges: Content edge Padding edge Border edge Margin edge The width and height of the box are based on: Width/height of content Padding Border Margin The width and height of the content in box with default box-sizing is controlled by properties: Min-width Max-width Width Min-height Max-height Height An important thing about box model is how background properties will behave. Background will be included in the content section and in the padding section (to padding edge). Let's get a code and try to point all the elements of the box model. HTML: <div class="element">   Lorem ipsum dolor sit amet consecteur </div> CSS: .element {    background: pink;    padding: 10px;    margin: 20px;   width: 100px;   height: 100px;    border: solid 10px black; }   In the browser, we will see the following: This is the view from the inspector of Google Chrome: Let's check how the areas of box model are placed in this specific example: The basic task for interviewed Front End Developer is—the box/element is described with the styles: .box {     width: 100px;     height: 200px;     border: 10px solid #000;     margin: 20px;     padding: 30px; } Please count the final width and height (the real space that is needed for this element) of this element. So, as you can see, the problem is to count the width and height of the box. Ingridients of width: Width Border left Border right Padding left Padding right Additionally, for the width of the space taken by the box: Margin left Margin right Ingridients of height: Height Border top Border bottom Padding top Padding bottom Additionally, for height of the space taken by the box: Margin top Margin bottom So, when you will sum the element, you will have an equation: Width: Box width = width + borderLeft + borderRight + paddingLeft + paddingRight Box width = 100px + 10px + 10px + 30px + 30px = 180px Space width: width = width + borderLeft + borderRight + paddingLeft + paddingRight +  marginLeft + marginRight width = 100px + 10px + 10px + 30px + 30px + 20px + 20 px = 220px Height: Box height = height + borderTop + borderBottom + paddingTop + paddingBottom Box height  = 200px + 10px + 10px + 30px + 30px = 280px Space height: Space height = height + borderTop + borderBottom + paddingTop + paddingBottom +  marginTop + marginBottom Space height = 200px + 10px + 10px + 30px + 30px + 20px + 20px = 320px Here, you can check it in a real browser: Omiting problems with traditional box model (box sizing) The basic theory of box model is pretty hard to learn. You need to remember about all the elements of width/height, even if you set the width and height. The hardest for beginners is the understanding of padding, which shouldn't be counted as a component of width and height. It should be inside the box, and it should impact on these values. To change this behavior to support CSS3 since Internet Explorer 8, box sizing comes to picture. You can set the value: box-sizing: border-box What it gives to you? Finally, the counting of box width and height will be easier because box padding and border is inside the box. So, if we are taking our previous class: .box {     width: 100px;     height: 200px;     border: 10px solid #000;     margin: 20px;     padding: 30px; } We can count the width and height easily: Width = 100px Height = 200px Additionally, the space taken by the box: Space width = 140 px (because of the 20 px margin on both sides: left and right) Space height = 240 px (because of the 20 px margin on both sides: top and bottom) Here is a sample from Chrome: So, if you don't want to repeat all the problems of a traditional box model, you should use it globally for all the elements. Of course, it's not recommended in projects that you are getting in some old project, for example, from new client that needs some small changes:  * { width: 100px; } Adding the preceding code can make more harm than good because of the inheritance of this property for all the elements, which are now based on a traditional box model. But for all the new projects, you should use it. Floating elements Floating boxes are the most used in modern layouts. The theory of floating boxes was still used especially in grid systems and inline lists in CSS frameworks. For example, class and mixin inline-list (in Zurb Foundation framework) are based on floats. Possibilities of floating elements Element can be floated to the left and right. Of course, there is a method that is resetting floats too. The possible values are: float: left; // will float element to left float: right; // will float element to right float: none; // will reset float Most known floating problems When you are using floating elements, you can have some issues. Most known problems with floated elements are: Too big elements (because of width, margin left/right, padding left/right, and badly counted width, which is based on box model) Not cleared floats All of these problems provide a specific effect, which you can easily recognize and then fix. Too big elements can be recognized when elements are not in one line and it should. What you should check first is if the box-sizing: border-box is applied. Then, check the width, padding, and margin. Not cleared floats you can easily recognize when to floating structure some elements from next container are floated. It means that you have no clearfix in your floating container. Define clearfix/class/mixin When I was starting developing HTML and CSS code, there was a method to clear the floats with classes .cb or .clear, both defined as: .clearboth, .cb {     clear: both } This element was added in the container right after all the floated elements. This is important to remember about clearing the floats because the container which contains floating elements won't inherit the height of highest floating element (will have a height equal 0). For example: <div class="container">     <div class="float">         … content ...     </div>     <div class="float">         … content ...     </div>     <div class="clearboth"></div> </div> Where CSS looks like this: .float {     width: 100px;     height: 100px;     float: left; }   .clearboth {     clear: both } Nowadays, there is a better and faster way to clear floats. You can do this with clearfix, which can be defined like this: .clearfix:after {     content: " ";     visibility: hidden;     display: block;     height: 0;     clear: both; } You can use in HTML code: <div class="container clearfix">     <div class="float">         … content ...     </div>     <div class="float">         … content ...     </div> </div> The main reason to switch on clearfix is that you save one tag (with clears both classes). Recommended usage is based on the clearfix mixin, which you can define like this in SASS: =clearfix   &:after     content: " "     visibility: hidden     display: block     height: 0     clear: both So, every time you need to clear floating in some container, you need to invoke it. Let's take the previous code as an example: <div class="container">     <div class="float">         … content ...     </div>     <div class="float">         … content ...     </div> </div> A container can be described as: .container   +clearfix Example of using floating elements The most known usage of float elements is grids. Grid is mainly used to structure the data displayed on a webpage. In this article, let's check just a short draft of grid. Let's create an HTML code: <div class="row">     <div class="column_1of2">         Lorem     </div>     <div class="column_1of2">         Lorem     </div>   </div> <div class="row">     <div class="column_1of3">         Lorem     </div>     <div class="column_1of3">         Lorem     </div>     <div class="column_1of3">         Lorem     </div>   </div>   <div class="row">     <div class="column_1of4">         Lorem     </div>     <div class="column_1of4">         Lorem     </div>     <div class="column_1of4">         Lorem     </div>     <div class="column_1of4">         Lorem     </div> </div> And SASS: *   box-sizing: border-box =clearfix   &:after     content: " "     visibility: hidden     display: block     height: 0     clear: both .row   +clearfix .column_1of2   background: orange   width: 50%   float: left   &:nth-child(2n)     background: red .column_1of3   background: orange   width: (100% / 3)   float: left   &:nth-child(2n)     background: red .column_1of4   background: orange   width: 25%   float: left   &:nth-child(2n)     background: red The final effect: As you can see, we have created a structure of a basic grid. In places where HTML code is placed, Lorem here is a full lorem ipsum to illustrate the grid system. Summary In this article, we studied about the traditional box model and floating elements in detail. Resources for Article: Further resources on this subject: Flexbox in CSS [article] CodeIgniter Email and HTML Table [article] Developing Wiki Seek Widget Using Javascript [article]
Read more
  • 0
  • 0
  • 13522

article-image-css-grids-rwd
Packt
24 Aug 2015
12 min read
Save for later

CSS Grids for RWD

Packt
24 Aug 2015
12 min read
In this article by the author, Ricardo Zea, of the book, Mastering Responsive Web Design, we're going to learn how to create a custom CSS grid. Responsive Web Design (RWD) has introduced a new layer of work for everyone building responsive websites and apps. When we have to test our work on different devices and in different dimensions, wherever the content breaks, we need to add a breakpoint and test again. (For more resources related to this topic, see here.) This can happen many, many times. So, building a website or app will take a bit longer than it used to. To make things a little more interesting, as web designers and developers, we need to be mindful of how the content is laid out at different dimensions and how a grid can help us structure the content to different layouts. Now that we have mentioned grids, have you ever asked yourself, "what do we use a grid for anyway?" To borrow a few terms from the design industry and answer that question, we use a grid to allow the content to have rhythm, proportion, and balance. The objective is that those who use our websites/apps will have a more pleasant experience with our content, since it will be easier to scan (rhythm), easier to read (proportion) and organized (balance). In order to speed up the design and build processes while keeping all the content properly formatted in different dimensions, many authors and companies have created CSS frameworks and CSS grids that contain not only a grid but also many other features and styles than can be leveraged by using a simple class name. As time goes by and browsers start supporting more and more CSS3 properties, such as Flexbox, it'll become easier to work with layouts. This will render the grids inside CSS frameworks almost unnecessary. Let's see what CSS grids are all about and how they can help us with RWD. In this article, we're going to learn how to create a custom CSS grid. Creating a custom CSS grid Since we're mastering RWD, we have the luxury of creating our own CSS grid. However, we need to work smart, not hard. Let's lay out our CSS grid requirements: It should have 12 columns. It should be 1200px wide to account for 1280px screens. It should be fluid, with relative units (percentages) for the columns and gutters. It should use the mobile-first approach. It should use the SCSS syntax. It should be reusable for other projects. It should be simple to use and understand. It should be easily scalable. Here's what our 1200 pixel wide and 12-column width 20px grid looks like: The left and right padding in black are 10px each. We'll convert those 10px into percentages at the end of this process. Doing the math We're going to use the RWD magic formula:  (target ÷ context) x 100 = result %. Our context is going to be 1200px. So let's convert one column:  80 ÷ 1200 x 100 = 6.67%. For two columns, we have to account for the gutter that is 20px. In other words, we can't say that two columns are exactly 160px. That's not entirely correct. Two columns are: 80px + 20px + 80px = 180px. Let's now convert two columns:  180 ÷ 1200 x 100 = 15%. For three columns, we now have to account for two gutters: 80px + 20px + 80px + 20px + 80px = 280px. Let's now convert three columns:  280 ÷ 1200 x 100 = 23.33%. Can you see the pattern now? Every time we add a column, all that we need to do is add 100 to the value. This value accounts for the gutters too! Check the screenshot of the grid we saw moments ago, you can see the values of the columns increment by 100. So, all the equations are as follows: 1 column: 80 ÷ 1200 x 100 = 6.67% 2 columns: 180 ÷ 1200 x 100 = 15% 3 columns: 280 ÷ 1200 x 100 = 23.33% 4 columns: 380 ÷ 1200 x 100 = 31.67% 5 columns: 480 ÷ 1200 x 100 = 40% 6 columns: 580 ÷ 1200 x 100 = 48.33% 7 columns: 680 ÷ 1200 x 100 = 56.67% 8 columns: 780 ÷ 1200 x 100 = 65% 9 columns: 880 ÷ 1200 x 100 = 73.33% 10 columns: 980 ÷ 1200 x 100 = 81.67% 11 columns:1080 ÷ 1200 x 100 = 90% 12 columns:1180 ÷ 1200 x 100 = 98.33% Let's create the SCSS for the 12-column grid: //Grid 12 Columns .grid { &-1 { width:6.67%; } &-2 { width:15%; } &-3 { width:23.33%; } &-4 { width:31.67%; } &-5 { width:40%; } &-6 { width:48.33%; } &-7 { width:56.67%; } &-8 { width:65%; } &-9 { width:73.33%; } &-10 { width:81.67%; } &-11 { width:90%; } &-12 { width:98.33%; } } Using hyphens (-) to separate words allows for easier selection of the terms when editing the code. Adding the UTF-8 character set directive and a Credits section Don't forget to include the UTF-8 encoding directive at the top of the file to let browsers know the character set we're using. Let's spruce up our code by adding a Credits section at the top. The code is as follows: @charset "UTF-8"; /* Custom Fluid & Responsive Grid System Structure: Mobile-first (min-width) Syntax: SCSS Grid: Float-based Created by: Your Name Date: MM/DD/YY */ //Grid 12 Columns .grid { &-1 { width:6.67%; } &-2 { width:15%; } &-3 { width:23.33%; } &-4 { width:31.67%; } &-5 { width:40%; } &-6 { width:48.33%; } &-7 { width:56.67%; } &-8 { width:65%; } &-9 { width:73.33%; } &-10 { width:81.67%; } &-11 { width:90%; } &-12 { width:98.33%; } } Notice the Credits are commented with CSS style comments: /* */. These types of comments, depending on the way we compile our SCSS files, don't get stripped out. This way, the Credits are always visible so that others know who authored the file. This may or may not work for teams. Also, the impact on file size of having the Credits display is imperceptible, if any. Including the box-sizing property and the mobile-first mixin Including the box-sizing property allows the browser's box model to account for the padding inside the containers; this means the padding gets subtracted rather than added, thus maintaining the defined width(s). Since the structure of our custom CSS grid is going to be mobile-first, we need to include the mixin that will handle this aspect: @charset "UTF-8"; /* Custom Fluid & Responsive Grid System Structure: Mobile-first (min-width) Syntax: SCSS Grid: Float-based Created by: Your Name Date: MM/DD/YY */ *, *:before, *:after { box-sizing: border-box; } //Moble-first Media Queries Mixin @mixin forLargeScreens($width) { @media (min-width: $width/16+em) { @content } } //Grid 12 Columns .grid { &-1 { width:6.67%; } &-2 { width:15%; } &-3 { width:23.33%; } &-4 { width:31.67%; } &-5 { width:40%; } &-6 { width:48.33%; } &-7 { width:56.67%; } &-8 { width:65%; } &-9 { width:73.33%; } &-10 { width:81.67%; } &-11 { width:90%; } &-12 { width:98.33%; } } The main container and converting 10px to percentage value Since we're using the mobile-first approach, our main container is going to be 100% wide by default; but we're also going to give it a maximum width of 1200px since the requirement is to create a grid of that size. We're also going to convert 10px into a percentage value, so using the RWD magic formula: 10 ÷ 1200 x 100 = 0.83%. However, as we've seen before, 10px, or in this case 0.83%, is not enough padding and makes the content appear too close to the edge of the main container. So we're going to increase the padding to 20px:  20 ÷ 1200 x 100 = 1.67%. We're also going to horizontally center the main container with margin:auto;. There's no need to declare zero values to the top and bottom margins to center horizontally. In other words, margin: 0 auto; isn't necessary. Just declaring margin: auto; is enough. Let's include these values now: @charset "UTF-8"; /* Custom Fluid & Responsive Grid System Structure: Mobile-first (min-width) Syntax: SCSS Grid: Float-based Created by: Your Name Date: MM/DD/YY */ *, *:before, *:after { box-sizing: border-box; } //Moble-first Media Queries Mixin @mixin forLargeScreens($width) { @media (min-width: $width/16+em) { @content } } //Main Container .container-12 { width: 100%; //Change this value to ANYTHING you want, no need to edit anything else. max-width: 1200px; padding: 0 1.67%; margin: auto; } //Grid 12 Columns .grid { &-1 { width:6.67%; } &-2 { width:15%; } &-3 { width:23.33%; } &-4 { width:31.67%; } &-5 { width:40%; } &-6 { width:48.33%; } &-7 { width:56.67%; } &-8 { width:65%; } &-9 { width:73.33%; } &-10 { width:81.67%; } &-11 { width:90%; } &-12 { width:98.33%; } } In the padding property, it's the same if we type 0.83% or .83%. We can omit the zero. It's always a good practice to keep our code as streamlined as possible. This is the same principle as when we use hexadecimal shorthand values: #3336699 is the same as #369. Making it mobile-first On small screens, all the columns are going to be 100% wide. Since we're working with a single column layout, we don't use gutters; this means we don't have to declare margins, at least yet. At 640px, the grid will kick in and assign corresponding percentages to each column, so we're going to include the columns in a 40em (640px) media query and float them to the left. At this point, we need gutters. Thus, we declare the margin with .83% to the left and right padding. I chose 40em (640px) arbitrarily and only as a starting point. Remember to create content-based breakpoints rather than device-based ones. The code is as follows: @charset "UTF-8"; /* Custom Fluid & Responsive Grid System Structure: Mobile-first (min-width) Syntax: SCSS Grid: Float-based Created by: Your Name Date: MM/DD/YY */ *, *:before, *:after { box-sizing: border-box; } //Moble-first Media Queries Mixin @mixin forLargeScreens($width) { @media (min-width: $width/16+em) { @content } } //Main Container .container-12 { width: 100%; //Change this value to ANYTHING you want, no need to edit anything else. max-width: 1200px; padding: 0 1.67%; margin: auto; } //Grid .grid { //Global Properties - Mobile-first &-1, &-2, &-3, &-4, &-5, &-6, &-7, &-8, &-9, &-10, &-11, &-12 { width: 100%; } @include forLargeScreens(640) { //Totally arbitrary width, it's only a starting point. //Global Properties - Large screens &-1, &-2, &-3, &-4, &-5, &-6, &-7, &-8, &-9, &-10, &-11, &-12 { float: left; margin: 0 .83%; } //Grid 12 Columns .grid { &-1 { width:6.67%; } &-2 { width:15%; } &-3 { width:23.33%; } &-4 { width:31.67%; } &-5 { width:40%; } &-6 { width:48.33%; } &-7 { width:56.67%; } &-8 { width:65%; } &-9 { width:73.33%; } &-10 { width:81.67%; } &-11 { width:90%; } &-12 { width:98.33%; } } } Adding the row and float clearing rules If we use rows in our HTML structure or add the class .clear to a tag, we can declare all the float clearing values in a single nested rule with the :before and :after pseudo-elements. It's the same thing to use single or double colons when declaring pseudo-elements. The double colon is a CSS3 syntax and the single colon is a CSS2.1 syntax. The idea was to be able to differentiate them at a glance so a developer could tell which CSS version they were written on. However, IE8 and below do not support the double-colon syntax. The float clearing technique is an adaptation of David Walsh's CSS snippet (http://davidwalsh.name/css-clear-fix). We're also adding a rule for the rows with a bottom margin of 10px to separate them from each other, while removing that margin from the last row to avoid creating unwanted extra spacing at the bottom. Finally, we add the clearing rule for legacy IEs. Let's include these rules now: @charset "UTF-8"; /* Custom Fluid & Responsive Grid System Structure: Mobile-first (min-width) Syntax: SCSS Grid: Float-based Created by: Your Name Date: MM/DD/YY */ *, *:before, *:after { box-sizing: border-box; } //Moble-first Media Queries Mixin @mixin forLargeScreens($width) { @media (min-width: $width/16+em) { @content } } //Main Container .container-12 { width: 100%; //Change this value to ANYTHING you want, no need to edit anything else. max-width: 1200px; padding: 0 1.67%; margin: auto; } //Grid .grid { //Global Properties - Mobile-first &-1, &-2, &-3, &-4, &-5, &-6, &-7, &-8, &-9, &-10, &-11, &-12 { width: 100%; } @include forLargeScreens(640) { //Totally arbitrary width, it's only a starting point. //Global Properties - Large screens &-1, &-2, &-3, &-4, &-5, &-6, &-7, &-8, &-9, &-10, &-11, &-12 { float: left; margin: 0 .83%; } //Grid 12 Columns .grid { &-1 { width:6.67%; } &-2 { width:15%; } &-3 { width:23.33%; } &-4 { width:31.67%; } &-5 { width:40%; } &-6 { width:48.33%; } &-7 { width:56.67%; } &-8 { width:65%; } &-9 { width:73.33%; } &-10 { width:81.67%; } &-11 { width:90%; } &-12 { width:98.33%; } } } //Clear Floated Elements - http://davidwalsh.name/css-clear-fix .clear, .row { &:before, &:after { content: ''; display: table; } &:after { clear: both; } } //Use rows to nest containers .row { margin-bottom: 10px; &:last-of-type { margin-bottom: 0; } } //Legacy IE .clear { zoom: 1; } Let's recap our CSS grid requirements: 12 columns: Starting from .grid-1 to .grid-12. 1200px wide to account for 1280px screens: The .container-12 container has max-width: 1200px; Fluid and relative units (percentages) for the columns and gutters: The percentages go from 6.67% to 98.33%. Mobile-first: We added the mobile-first mixin (using min-width) and nested the grid inside of it. The SCSS syntax: The whole file is Sass-based. Reusable: As long as we're using 12 columns and we're using the mobile-first approach, we can use this CSS grid multiple times. Simple to use and understand: The class names are very straightforward. The .grid-6 grid is used for an element that spans 6 columns, .grid-7 is used for an element that spans 7 columns, and so on. Easily scalable: If we want to use 980px instead of 1200px, all we need to do is change the value in the .container-12 max-width property. Since all the elements are using relative units (percentages), everything will adapt proportionally to the new width—to any width for that matter. Pretty sweet if you ask me. Summary A lot to digest here, eh? Creating our custom CSS with the traditional floats technique was a matter of identifying the pattern where the addition of a new column was a matter of increasing the value by 100. Now, we can create a 12-column grid at any width we want. Resources for Article: Further resources on this subject: Role of AngularJS[article] Managing Images[article] Angular Zen [article]
Read more
  • 0
  • 0
  • 12511

article-image-3d-websites
Packt
23 May 2014
10 min read
Save for later

3D Websites

Packt
23 May 2014
10 min read
(For more resources related to this topic, see here.) Creating engaging scenes There is no adopted style for a 3D website. No metaphor can best describe the process of designing the 3D web. Perhaps what we know the most is what does not work. Often, our initial concept is to model the real world. An early design that was used years ago involved a university that wanted to use its campus map to navigate through its website. One found oneself dragging the mouse repeatedly, as fast as one could, just to get to the other side of campus. A better design would've been a book shelf where everything was in front of you. To view the chemistry department, just grab the chemistry book, and click on the virtual pages to view the faculty, curriculum, and other department information. Also, if you needed to cross-reference this with the math department's upcoming schedule, you could just grab the math book. Each attempt adds to our knowledge and gets us closer to something better. What we know is what most other applications of computer graphics learned—that reality might be a starting point, but we should not let it interfere with creativity. 3D for the sake of recreating the real world limits our innovative potential. Following this starting point, strip out the parts bound by physics, such as support beams or poles that serve no purpose in a virtual world. Such items make the rendering slower by just existing. Once we break these bounds, the creative process takes over—perhaps a whimsical version, a parody, something dark and scary, or a world-emphasizing story. Characters in video games and animated movies take on stylized features. The characters are purposely unrealistic or exaggerated. One of the best animations to exhibit this is Chris Landreth's The Spine, Ryan (Academy Award for best-animated short film in 2004), and his earlier work in Psychological Driven Animation, where the characters break apart by the ravages of personal failure (https://www.nfb.ca/film/ryan). This demonstration will describe some of the more difficult technical issues involved with lighting, normal maps, and the efficient sharing of 3D models. The following scene uses 3D models and textures maps from previous demonstrations but with techniques that are more complex. Engage thrusters This scene has two lampposts and three brick walls, yet we only read in the texture map and 3D mesh for one of each and then reuse the same models several times. This has the obvious advantage that we do not need to read in the same 3D models several times, thus saving download time and using less memory. A new function, copyObject(), was created that currently sits inside the main WebGL file, although it can be moved to mesh3dObject.js. In webGLStart(), after the original objects were created, we call copyObject(), passing along the original object with the unique name, location, rotation, and scale. In the following code, we copy the original streetLight0Object into a new streetLight1Object: streetLight1Object = copyObject( streetLight0Object, "streetLight1", streetLight1Location, [1, 1, 1], [0, 0, 0] ); Inside copyObject(), we first create the new mesh and then set the unique name, location (translation), rotation, and scale: function copyObject(original, name, translation, scale, rotation) { meshObjectArray[ totalMeshObjects ] = new meshObject(); newObject = meshObjectArray[ totalMeshObjects ]; newObject.name = name; newObject.translation = translation; newObject.scale = scale; newObject.rotation = rotation; The object to be copied is named original. We will not need to set up new buffers since the new 3D mesh can point to the same buffers as the original object: newObject.vertexBuffer = original.vertexBuffer; newObject.indexedFaceSetBuffer = original.indexedFaceSetBuffer; newObject.normalsBuffer = original.normalsBuffer; newObject.textureCoordBuffer = original.textureCoordBuffer; newObject.boundingBoxBuffer = original.boundingBoxBuffer; newObject.boundingBoxIndexBuffer = original.boundingBoxIndexBuffer; newObject.vertices = original.vertices; newObject.textureMap = original.textureMap; We do need to create a new bounding box matrix since it is based on the new object's unique location, rotation, and scale. In addition, meshLoaded is set to false. At this stage, we cannot determine if the original mesh and texture map have been loaded since that is done in the background: newObject.boundingBoxMatrix = mat4.create(); newObject.meshLoaded = false; totalMeshObjects++; return newObject; } There is just one more inclusion to inform us that the original 3D mesh and texture map(s) have been loaded inside drawScene(): streetLightCover1Object.meshLoaded = streetLightCover0Object.meshLoaded; streetLightCover1Object.textureMap = streetLightCover0Object.textureMap; This is set each time a frame is drawn, and thus, is redundant once the mesh and texture map have been loaded, but the additional code is a very small hit in performance. Similar steps are performed for the original brick wall and its two copies. Most of the scene is programmed using fragment shaders. There are four lights: the two streetlights, the neon Products sign, and the moon, which sets and rises. The brick wall uses normal maps. However, it is more complex here; the use of spotlights and light attenuation, where the light fades over a distance. The faint moon light, however, does not fade over a distance. Opening scene with four light sources: two streetlights, the Products neon sign, and the moon This program has only three shaders: LightsTextureMap, used by the brick wall with a texture normal map; Lights, used for any object that is illuminated by one or more lights; and Illuminated, used by the light sources such as the moon, neon sign, and streetlight covers. The simplest out of these fragment shaders is Illuminated. It consists of a texture map and the illuminated color, uLightColor. For many objects, the texture map would simply be a white placeholder. However, the moon uses a texture map, available for free from NASA that must be merged with its color: vec4 fragmentColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); gl_FragColor = vec4(fragmentColor.rgb * uLightColor, 1.0); The light color also serves another purpose, as it will be passed on to the other two fragment shaders since each adds its own individual color: off-white for the streetlights, gray for the moon, and pink for the neon sign. The next step is to use the shaderLights fragment shader. We begin by setting the ambient light, which is a dim light added to every pixel, usually about 0.1, so nothing is pitch black. Then, we make a call for each of our four light sources (two streetlights, the moon, and the neon sign) to the calculateLightContribution() function: void main(void) { vec3 lightWeighting = vec3(uAmbientLight, uAmbientLight, uAmbientLight); lightWeighting += uStreetLightColor * calculateLightContribution(uSpotLight0Loc, uSpotLightDir, false); lightWeighting += uStreetLightColor * calculateLightContribution(uSpotLight1Loc, uSpotLightDir, false); lightWeighting += uMoonLightColor * calculateLightContribution(uMoonLightPos, vec3(0.0, 0.0, 0.0), true); lightWeighting += uProductTextColor * calculateLightContribution(uProductTextLoc, vec3(0.0, 0.0, 0.0), true); All four calls to calculateLightContribution() are multiplied by the light's color (white for the streetlights, gray for the moon, and pink for the neon sign). The parameters in the call to calculateLightContribution(vec3, vec3, vec3, bool) are: location of the light, its direction, the pixel's normal, and the point light. This parameter is true for a point light that illuminates in all directions, or false if it is a spotlight that points in a specific direction. Since point lights such as the moon or neon sign have no direction, their direction parameter is not used. Therefore, their direction parameter is set to a default, vec3(0.0, 0.0, 0.0). The vec3 lightWeighting value accumulates the red, green, and blue light colors at each pixel. However, these values cannot exceed the maximum of 1.0 for red, green, and blue. Colors greater than 1.0 are unpredictable based on the graphics card. So, the red, green, and blue light colors must be capped at 1.0: if ( lightWeighting.r > 1.0 ) lightWeighting.r = 1.0; if ( lightWeighting.g > 1.0 ) lightWeighting.g = 1.0; if ( lightWeighting.b > 1.0 ) lightWeighting.b = 1.0; Finally, we calculate the pixels based on the texture map. Only the street and streetlight posts use this shader, and neither have any tiling, but the multiplication by uTextureMapTiling was included in case there was tiling. The fragmentColor based on the texture map is multiplied by lightWeighting—the accumulation of our four light sources for the final color of each pixel: vec4 fragmentColor = texture2D(uSampler, vec2(vTextureCoord.s*uTextureMapTiling.s, vTextureCoord.t*uTextureMapTiling.t)); gl_FragColor = vec4(fragmentColor.rgb * lightWeighting.rgb, 1.0); } In the calculateLightContribution() function, we begin by determining the angle between the light's direction and point's normal. The dot product is the cosine between the light's direction to the pixel and the pixel's normal, which is also known as Lambert's cosine law (http://en.wikipedia.org/wiki/Lambertian_reflectance): vec3 distanceLightToPixel = vec3(vPosition.xyz - lightLoc); vec3 vectorLightPosToPixel = normalize(distanceLightToPixel); vec3 lightDirNormalized = normalize(lightDir); float angleBetweenLightNormal = dot( -vectorLightPosToPixel, vTransformedNormal ); A point light shines in all directions, but a spotlight has a direction and an expanding cone of light surrounding this direction. For a pixel to be lit by a spotlight, that pixel must be in this cone of light. This is the beam width area where the pixel receives the full amount of light, which fades out towards the cut-off angle that is the angle where there is no more light coming from this spotlight: With texture maps removed, we reveal the value of the dot product between the pixel normal and direction of the light if ( pointLight) { lightAmt = 1.0; } else { // spotlight float angleLightToPixel = dot( vectorLightPosToPixel, lightDirNormalized ); // note, uStreetLightBeamWidth and uStreetLightCutOffAngle // are the cosines of the angles, not actual angles if ( angleLightToPixel >= uStreetLightBeamWidth ) { lightAmt = 1.0; } if ( angleLightToPixel > uStreetLightCutOffAngle ) { lightAmt = (angleLightToPixel - uStreetLightCutOffAngle) / (uStreetLightBeamWidth - uStreetLightCutOffAngle); } } After determining the amount of light at that pixel, we calculate attenuation, which is the fall-off of light over a distance. Without attenuation, the light is constant. The moon has no light attenuation since it's dim already, but the other three lights fade out at the maximum distance. The float maxDist = 15.0; code snippet says that after 15 units, there is no more contribution from this light. If we are less than 15 units away from the light, reduce the amount of light proportionately. For example, a pixel 10 units away from the light source receives (15-10)/15 or 1/3 the amount of light: attenuation = 1.0; if ( uUseAttenuation ) { if ( length(distanceLightToPixel) < maxDist ) { attenuation = (maxDist - length(distanceLightToPixel))/maxDist; } else attenuation = 0.0; } Finally, we multiply the values that make the light contribution and we are done: lightAmt *= angleBetweenLightNormal * attenuation; return lightAmt; Next, we must account for the brick wall's normal map using the shaderLightsNormalMap-fs fragment shader. The normal is equal to rgb * 2 – 1. For example, rgb (1.0, 0.5, 0.0), which is orange, would become a normal (1.0, 0.0, -1.0). This normal is converted to a unit value or normalized to (0.707, 0, -0.707): vec4 textureMapNormal = vec4( (texture2D(uSamplerNormalMap, vec2(vTextureCoord.s*uTextureMapTiling.s, vTextureCoord.t*uTextureMapTiling.t)) * 2.0) - 1.0 ); vec3 pixelNormal = normalize(uNMatrix * normalize(textureMapNormal.rgb) ); A normal mapped brick (without red brick texture image) reveals how changing the pixel normal altersthe shading with various light sources We call the same calculateLightContribution() function, but we now pass along pixelNormal calculated using the normal texture map: calculateLightContribution(uSpotLight0Loc, uSpotLightDir, pixelNormal, false); From here, much of the code is the same, except we use pixelNormal in the dot product to determine the angle between the normal and the light sources: float angleLightToTextureMap = dot( -vectorLightPosToPixel, pixelNormal ); Now, angleLightToTextureMap replaces angleBetweenLightNormal because we are no longer using the vertex normal embedded in the 3D mesh's .obj file, but instead we use the pixel normal derived from the normal texture map file, brickNormalMap.png. A normal mapped brick wall with various light sources Objective complete – mini debriefing This comprehensive demonstration combined multiple spot and point lights, shared 3D meshes instead of loading the same 3D meshes, and deployed normal texture maps for a real 3D brick wall appearance. The next step is to build upon this demonstration, inserting links to web pages found on a typical website. In this example, we just identified a location for Products using a neon sign to catch the users' attention. As a 3D website is built, we will need better ways to navigate this virtual space and this is covered in the following section.
Read more
  • 0
  • 0
  • 12252
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-materials-and-why-they-are-essential
Packt
08 Jul 2015
11 min read
Save for later

Materials, and why they are essential

Packt
08 Jul 2015
11 min read
In this article by Ciro Cardoso, author of the book Lumion3D Best Practices, we will see materials, and why they are essential. In the 3D world, materials and textures are nearly as important as the 3D geometry that composes the scene. A material defines the optical properties of an object when hit by a ray of light. In other words, a material defines how the light interacts with the surface, and textures can help not only to control the color (diffuse), but also the reflections and glossiness. (For more resources related to this topic, see here.) It's not difficult to understand that textures are another essential part of a good material, and if your goal is to achieve believable results, you need textures or images of real elements like stone, wood, brick, and other natural elements. Textures can bring detail to your surface that otherwise would require geometry to look good. In that case, how can Lumion help you and, most importantly, what are the best practices to work with materials? Let's have a look at the following section which will provide the answer. A quick overview of Lumion's materials Lumion always had a good library of materials to assign to your 3D model, The reality is that Physically-Based Rendering (PBR) is more of a concept than a set of rules, and each render engine will implement slightly differently. The good news for us as users is that these materials follow realistic shading and lighting systems to accurately represent real-world materials. You can find excellent information regarding PBR on the following sites: http://www.marmoset.co/toolbag/learn/pbr-theory http://www.marmoset.co/toolbag/learn/pbr-practice https://www.allegorithmic.com/pbr-guide More than 600 materials are already prepared to be assigned directly to your 3D model and, by default, they should provide a realistic and appropriate material. The Lumion team has also made an effort to create a better and simpler interface, as you can see in the following screenshot: The interface was simplified, showing only the most common and essential settings. If you need more control over the material, click on the More… button to have access to extra functionalities. One word of caution: the material preview, which in this case is the sphere, will not reflect the changes you perform using the settings available. For example, if you change the main texture, the sphere will continue to show the previous material. A good practice to tweak materials is to assign the material to the surface, use the viewport to check how the settings are affecting the material, and then do a quick render. The viewport will try to show the final result, but there's nothing like a quick render to see how the material really looks when Lumion does all the lighting and shading calculations. Working with materials in Lumion – three options There are three options to work with materials in Lumion: Using Lumion's materials Using the imported materials that you can create on your favorite modeling application Creating materials using Lumion's Standard material Let's have a look at each one of these options and see how they can help you and when they best suit your project. Using Lumion's materials The first option is obvious; you are using Lumion and it makes sense using Lumion's materials, but you may feel constrained by what is available at Lumion's material library. However, instead of thinking, "I only have 600 materials and I cannot find what I need!", you need to look at the materials library also as a template to create other materials. For example, if none of the brick materials is similar to what you need, nothing stops you from using a brick material, changing the Gloss and Reflection values, and loading a new texture, creating an entirely new material. This is made possible by using the Choose Color Map button, as shown in the following screenshot: When you click on the Choose Color Map button, a new window appears where you can navigate to the folder where the texture is saved. What about the second square? The one with a purple color? Let's see the answer in the following section. Normal maps and their functionality The purple square you just saw is where you can load the normal map. And what is a normal map? Firstly, a normal map is not a bump map. A bump map uses a color range from black to white and in some ways is more limited than a normal map. The following screenshots show the clear difference between these two maps: The map on the left is a bump map and you can see that the level of detail is not the same that we can get with a normal map. A normal map consists of red, green, and blue colors that represent the x, y, and z coordinates. This allows a 2D image to represent depth and Lumion uses this depth information to fake lighting details based on the color associated with the 3D coordinate. The perks of using a normal map Why should you use normal maps? Keep in mind that Lumion is a real-time rendering engine and, as you saw previously, there is the need to keep a balance between detail and geometry. If you add too much detail, the 3D model will look gorgeous but Lumion's performance will suffer drastically. On the other hand, you can have a low-poly 3D model and fake detail with a normal map. Using a normal map for each material has a massive impact on the final quality you can get with Lumion. Since these maps are so important, how can you create one? Tips to create normal maps As you will understand, we cannot cover all the different techniques to create normal maps. However, you may find something to suit your workflow in the following list: Photoshop using an action script called nDo: Teddy Bergsman is the author of this fantastic script. It is a free script that creates a very accurate normal map of any texture you load in Photoshop in seconds. To download and see how to install this script, visit the following link: http://www.philipk.net/ndo.html Here you can find a more detailed tutorial on how to use this nDo script: http://www.philipk.net/tutorials/ndo/ndo.html This script has three options to create normal maps. The default option is Smooth, which gives you a blurry normal map. Then you have the Chisel Hard option to generate a very sharp and subtle normal map but you don't have much control over the final result. The Chisel Soft option is similar to the Chisel Hard except that you have full control over the intensity and bevel radius. This script also allows you to sculpt and combine several normal maps. Using the Quixel NDO application: From the same creator, we have a more capable and optimized application called Quixel NDO. With this application, you can sculpt normal maps in real-time, build your own normal maps without using textures, and preview everything with the 3DO material preview. This is quite useful because you don't have to save the normal map and see how it looks in Lumion. 3DO (which comes free with NDO) has a physically based renderer and lets you load a 3D model to see how the texture looks. Find more information including a free trial here: http://quixel.se/dev/ndo GIMP with the normalmap plugin: If you want to use free software, a good alternative is GIMP. There is a great plugin called normalmap, which does good work not only by creating a normal map but also by providing a preview window to see the tweaks you are making. To download this plugin, visit the following link: https://code.google.com/p/gimp-normalmap/ Do it online with NormalMap-Online: In case you don't want to install another application, the best option is doing it online. In that case, you may want to have a look at NormalMap-Online, as shown in the following screenshot: The process is extremely simple as you can see from the preceding screenshot. You load the image and automatically get a normal map, and on the right-hand side there is a preview to show how the normal map and the texture work together. Christian Petry is the man behind this tool that will help to create sharp and accurate normal maps. He is a great guy and if you like this online application, please consider supporting an application that will save you time and money. Find this online tool here: http://cpetry.github.io/NormalMap-Online/ Don't forget to use a good combination of Strength and Blur/Sharp to create a well-balanced map. You need the correct amount of detail; otherwise your normal map will be too noisy in terms of detail. However, Lumion being a user-friendly application gives you a hand on this topic by providing a tool to create a normal map automatically from a texture you import. Creating a normal map with Lumion's relief feature By now, creating a normal map from a texture is not something too technical or even complex, but it can be time consuming if you need to create a normal map for each texture. This is a wise move because it will remove the need for extra detail for the model to look good. With this in mind, Lumion's team created a new feature that allows you to create a normal map for any texture you import. After loading the new texture, the next step is to click on the Create Normal Map button, as highlighted in the following screenshot: Lumion then creates a normal map based on the texture imported, and you have the ability to invert the map by clicking on the Flip Normal Map direction button, as highlighted in the preceding screenshot. Once Lumion creates the normal map, you need a way to control how the normal map affects the material and the light. For that, you need to use the Relief slider, as shown in the following screenshot: Using this slider is very intuitive; you only need to move the slider and see the adjustments on the viewport, since the material preview will not be updated. The previous screenshot is a good example of that, because even when we loaded a wood texture, the preview still shows a concrete material. Again, this means you can easily use the settings from one material and use that as a base to create something completely new. But how good is the normal map that Lumion creates for you? Have a look for yourself in the following screenshot: On the left hand side, we have a wood floor material with a normal map that Lumion created. The right-hand side image is the same material but the normal map was created using the free nDo script for Photoshop. There is a big difference between the image on the left and the image on the right, and that is related to the normal maps used in this case. You can see clearly that the normal map used for the image on the right achieves the goal of bringing more detail to the surface. The difference is that the normal map that Lumion creates in some situations is too blurry, and for that reason we end up losing detail. Before we explore a few more things regarding creating custom materials in Lumion, let's have a look at another useful feature in Lumion. Summary Physically based rendering materials aren't that scary, don't you agree? In reality, Lumion makes this feature almost unnoticeable by making it so simple. You learned what this feature involves and how you can take full advantage of materials that make your render more believable. You learned the importance of using normal maps and how to create them using a variety of tools for all flavors. You also saw how we can easily improve material reflections without compromising the speed and quality of the render. You also learned another key aspect of Lumion: flexibility to create your own materials using the Standard material. The Standard material, although slightly different from the other materials available in Lumion, lets you play with the reflections, glossiness, and other settings that are essential. On top of all of this, you learned how to create textures. Resources for Article: Further resources on this subject: Unleashing the powers of Lumion [article] Mastering Lumion 3D [article] What is Lumion? [article]
Read more
  • 0
  • 0
  • 12207

article-image-flexbox-css
Packt
09 Mar 2016
8 min read
Save for later

Flexbox in CSS

Packt
09 Mar 2016
8 min read
In this article by Ben Frain, the author of Responsive Web Design with HTML5 and CSS3, Second Edition, we will look at Flexbox and its uses. In 2015, we have better means to build responsive websites than ever. There is a new CSS layout module called Flexible Box (or Flexbox as it is more commonly known) that now has enough browser support to make it viable for everyday use. It can do more than merely provide a fluid layout mechanism. Want to be able to easily center content, change the source order of markup, and generally create amazing layouts with relevant ease? Flexbox is the layout mechanism for you. (For more resources related to this topic, see here.) Introducing Flexbox Here's a brief overview of Flexbox's superpowers: It can easily vertically center contents It can change the visual order of elements It can automatically space and align elements within a box, automatically assigning available space between them It can make you look 10 years younger (probably not, but in low numbers of empirical tests (me) it has been proven to reduce stress) The bumpy path to Flexbox Flexbox has been through a few major iterations before arriving at the relatively stable version we have today. For example, consider the changes from the 2009 version (http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/), the 2011 version (http://www.w3.org/TR/2011/WD-css3-flexbox-20111129/), and the 2014 version we are basing our examples on (http://www.w3.org/TR/css-flexbox-1/). The syntax differences are marked. These differing specifications mean there are three major implementation versions. How many of these you need to concern yourself with depends on the level of browser support you need. Browser support for Flexbox Let's get this out of the way up front: there is no Flexbox support in Internet Explorer 9, 8, or below. For everything else you'd likely want to support (and virtually all mobile browsers), there is a way to enjoy most (if not all) of Flexbox's features. You can check the support information at http://caniuse.com/. Now, let's look at one of its uses. Changing source order Since the dawn of CSS, there has only been one way to switch the visual ordering of HTML elements in a web page. That was achieved by wrapping elements in something set to display: table and then switching the display property on the items within, between display: table-caption (puts it on top), display: table-footer-group (sends it to the bottom), and display: table-header-group (sends it to just below the item set to display: table-caption). However, as robust as this technique is, it was a happy accident, rather than the true intention of these settings. However, Flexbox has visual source re-ordering built in. Let's have a look at how it works. Consider this markup: <div class="FlexWrapper">     <div class="FlexItems FlexHeader">I am content in the Header.</div>     <div class="FlexItems FlexSideOne">I am content in the SideOne.</div>     <div class="FlexItems FlexContent">I am content in the Content.</div>     <div class="FlexItems FlexSideTwo">I am content in the SideTwo.</div>     <div class="FlexItems FlexFooter">I am content in the Footer.</div> </div> You can see here that the third item within the wrapper has a HTML class of FlexContent—imagine that this div is going to hold the main content for the page. OK, let's keep things simple. We will add some simple colors to more easily differentiate the sections and just get these items one under another in the same order they appear in the markup. .FlexWrapper {     background-color: indigo;     display: flex;     flex-direction: column; }   .FlexItems {     display: flex;     align-items: center;     min-height: 6.25rem;     padding: 1rem; }   .FlexHeader {     background-color: #105B63;    }   .FlexContent {     background-color: #FFFAD5; }   .FlexSideOne {     background-color: #FFD34E; }   .FlexSideTwo {     background-color: #DB9E36; }   .FlexFooter {     background-color: #BD4932; } That renders in the browser like this:   Now, suppose we want to switch the order of .FlexContent to be the first item, without touching the markup. With Flexbox it's as simple as adding a single property/value pair: .FlexContent {     background-color: #FFFAD5;     order: -1; } The order property lets us revise the order of items within a Flexbox simply and sanely. In this example, a value of -1 means that we want it to be before all the others. If you want to switch items around quite a bit, I'd recommend being a little more declarative and add an order number for each. This makes things a little easier to understand when you combine them with media queries. Let's combine our new source order changing powers with some media queries to produce not just a different layout at different sizes but different ordering. As it's generally considered wise to have your main content at the beginning of a document, let's revise our markup to this: <div class="FlexWrapper">     <div class="FlexItems FlexContent">I am content in the Content.</div>     <div class="FlexItems FlexSideOne">I am content in the SideOne.</div>     <div class="FlexItems FlexSideTwo">I am content in the SideTwo.</div>     <div class="FlexItems FlexHeader">I am content in the Header.</div>     <div class="FlexItems FlexFooter">I am content in the Footer.</div> </div> First the page content, then our two sidebar areas, then the header and finally the footer. As I'll be using Flexbox, we can structure the HTML in the order that makes sense for the document, regardless of how things need to be laid out visually. For the smallest screens (outside of any media query), I'll go with this ordering: .FlexHeader {     background-color: #105B63;     order: 1; }   .FlexContent {     background-color: #FFFAD5;     order: 2; }   .FlexSideOne {     background-color: #FFD34E;     order: 3; }   .FlexSideTwo {     background-color: #DB9E36;     order: 4; }   .FlexFooter {     background-color: #BD4932;     order: 5; } Which gives us this in the browser:   And then, at a breakpoint, I'm switching to this: @media (min-width: 30rem) {     .FlexWrapper {         flex-flow: row wrap;     }     .FlexHeader {         width: 100%;     }     .FlexContent {         flex: 1;         order: 3;     }     .FlexSideOne {         width: 150px;         order: 2;     }     .FlexSideTwo {         width: 150px;         order: 4;     }     .FlexFooter {         width: 100%;     } } Which gives us this in the browser: In that example, the shortcut flex-flow: row wrap has been used. That allows the flex items to wrap onto multiple lines. It's one of the poorer supported properties, so depending upon how far back support is needed, it might be necessary to wrap the content and two side bars in another element. Summary There are near endless possibilities when using the Flexbox layout system and due to its inherent "flexiness", it's a perfect match for responsive design. If you've never built anything with Flexbox before, all the new properties and values can seem a little odd and it's sometimes disconcertingly easy to achieve layouts that have previously taken far more work. To double-check implementation details against the latest version of the specification, make sure you check out http://www.w3.org/TR/css-flexbox-1/. I think you'll love building things with Flexbox. To check out the other amazing things you can do with Flexbox, have a look at Responsive Web Design with HTML5 and CSS3, Second Edition. The book also features a plethora of other awesome tips and tricks related to responsive web design. Resources for Article: Further resources on this subject: CodeIgniter Email and HTML Table [article] ASP.Net Site Performance: Improving JavaScript Loading [article] Adding Interactive Course Material in Moodle 1.9: Part 1 [article]
Read more
  • 0
  • 0
  • 12122

article-image-managing-images
Packt
14 Apr 2015
11 min read
Save for later

Managing Images

Packt
14 Apr 2015
11 min read
Cats, dogs and all sorts of memes, the Internet as we know it today is dominated by images. You can open almost any web page and you'll surely find images on the page. The more interactive our web browsing experience becomes, the more images we tend to use. So, it is tremendously important to ensure that the images we use are optimized and loaded as fast as possible. We should also make sure that we choose the correct image type. In this article by Dewald Els, author of the book Responsive Design High Performance,we will talk about, why image formats are important, conditional loading, visibility for DOM elements, specifying sizes, media queries, introducing sprite sheets, and caching. Let's talk basics. (For more resources related to this topic, see here.) Choosing the correct image format Deciding what image format to use is usually the first step you take when you start your website. Take a look at this table for an overview and comparison ofthe available image formats: Format Features GIF 256 colors Support for animation Transparency PNG 256 colors True colors Transparency JPEG/JPG 256 colors True colors From the preceding listed formats, you can conclude that, if you had a complex image that was 1000 x 1000 pixels, the image in the JPEG format would be the smallest in file size. This also means that it would load the fastest. The smallest image is not always the best choice though. If you need to have images with transparent parts, you'll have to use the PNG or GIF formats and if you need an animation, you are stuck with using a GIF format or the lesser know APNG format. Optimizing images Optimizing your image can have a huge impact on your overall website performance. There are some great applications to help you with image optimization and compression. TinyPNG is a great example of a site that helps you to compress you PNG's images online for free. They also have a Photoshop plugin that is available for download at https://tinypng.com/. Another great application to help you with JPG compression is JPEGMini. Head over to http://www.jpegmini.com/ to get a copy for either Windows or Mac OS X. Another application that is worth considering is Radical Image Optimization Tool (RIOT). It is a free program and can be found at http://luci.criosweb.ro/riot/. RIOT is a Windows application. Viewing as JPEG is not the only image format that we use in the Web; you can also look at a Mac OS X application called ImageOptim (http://www.imageoptim.com) It is also a free application and compresses both JPEG and PNG images. If you are not on Mac OS X, you can head over to https://tinypng.com/. This handy little site allows you to upload your image to the site, where it is then compressed. The optimized images are then linked to the site as downloadable files. As JPEG image formats make up the majority of most web pages, with some exceptions, lets take a look at how to make your images load faster. Progressive images Most advanced image editors such as Photoshop and GIMP give you the option to encode your JPEG images using either baseline or progressive. If you Save For Web using Photoshop, you will see this section at the top of the dialog box: In most cases, for use on web pages, I would advise you to use the Progressive encoding type. When you save an image using baseline, the full image data of every pixel block is written to the file one after the other. Baseline images load gradually from the top-left corner. If you save an image using the Progressive option, then it saves only a part of each of these blocks to the file and then another part and so on, until the entire image's information is captured in the file. When you render a progressive image, you will see a very grainy image display and this will gradually become sharper as it loads. Progressive images are also smaller than baseline images for various technical reasons. This means that they load faster. In addition, they appear to load faster when something is displayed on the screen. Here is a typical example of the visual difference between loading a progressive and a baseline JPEG image: Here, you can clearly see how the two encodings load in a browser. On the left, the progressive image is already displayed whereas the baseline image is still loading from the top. Alright, that was some really basic stuff, but it was extremely important nonetheless. Let's move on to conditional loading. Adaptive images Adaptive images are an adaptation of Filament Group's context-aware image sizing experiment. What does it do? Well, this is what the guys say about themselves: "Adaptive images detects your visitor's screen size and automatically creates, caches, and delivers device appropriate re-scaled versions of your web page's embedded HTML images. No mark-up changes needed. It is intended for use with Responsive Designs and to be combined with Fluid Images techniques." It certainly trumps the experiment in the simplicity of implementation. So, how does it work? It's quite simple. There is no need to change any of your current code. Head over to http://adaptive-images.com/download.htm and get the latest version of adaptive images. You can place the adaptive-images.php file in the root of your site. Make sure to add the content of the .htaccess file to your own as well. Head over to the index file of your site and add this in the <head> tags: <script>document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/';</script> Note that it is has to be in the <head> tag of your site. Open the adaptive-images.php file and add you media query values into the $resolutions variable. Here is a snippet of code that is pretty self-explanatory: $resolutions   = array(1382, 992, 768, 480);$cache_path   = "ai-cache";$jpg_quality   = 80;$sharpen       = TRUE;$watch_cache   = TRUE;$browser_cache = 60*60*24*7; The $resolution variable accepts the break-points that you use for your website. You can simply add the value of the screen width in pixels. So, in the the preceding example, it would read 1382 pixels as the first break-point, 992 pixels as the second one, and so on. The cache path tells adaptive images where to store the generated resized images. It's a relative path from your document root. So, in this case, your folder structure would read as document_root/a-cache/{images stored here}. The next variable, $jpg_quality, sets the quality of any generated JPGs images on a scale of 0 to 100. Shrinking images could cause blurred details. Set $sharpen to TRUE to perform a sharpening process on rescaled images. When you set $watch_cache to TRUE, you force adaptive images to check that the adapted image isn't stale; that is, it ensures that the updated source images are recached. Lastly, $browser_cache sets how long the browser cache should last for. The values are seconds, minutes, hours, days (7 days by default). You can change the last digit to modify the days. So, if you want images to be cached for two days, simply change the last value to 2. Then,… oh wait, that's all? It is indeed! Adaptive images will work with your existing website and they don't require any markup changes. They are also device-agnostic and follow a mobile-first philosophy. Conditional loading Responsive designs combine three main techniques, which are as follows: Fluid grids Flexible images Media queries The technique that I want to focus on in this section is media queries. In most cases, developers use media queries to change the layout, width height, padding, font size and so on, depending on conditions related to the viewport. Let's see how we can achieve conditional image loading using CSS3's image-set function: .my-background-img {background-image: image-set(url(icon1x.jpg) 1x,url(icon2x.jpg) 2x);} You can see in the preceding piece of CSS3 code that the image is loaded conditionally based on its display type. The second statement url(icon2x.jpg) 2x would load the hi-resolution image or retina image. This reduces the number of CSS rules we have to create. Maintaining a site with a lot of background images can become quite a chore if a separate rule exists for each one. Here is a simple media query example: @media screen and (max-width: 480px) {   .container {       width: 320px;   }} As I'm sure you already know, this snippet tells the browser that, for any device with a viewport of fewer than 480 pixels, any element with the class container has to be 320 pixels wide. When you use media queries, always make sure to include the viewport <meta> tag in the head of your HTML document, as follows: <meta name="viewport" content="width=device-width, initial-scale=1"> I've included this template here as I'd like to start with this. It really makes it very easy to get started with new responsive projects: /* MOBILE */@media screen and (max-width: 480px) {   .container {       width: 320px;   }}/* TABLETS */@media screen and (min-width: 481px) and (max-width: 720px) {   .container {       width: 480px;   }}/* SMALL DESKTOP OR LARGE TABLETS */@media screen and (min-width: 721px) and (max-width: 960px) {   .container {       width: 720px;   }}/* STANDARD DESKTOP */@media screen and (min-width: 961px) and (max-width: 1200px) {   .container {       width: 960px;   }}/* LARGE DESKTOP */@media screen and (min-width: 1201px) and (max-width: 1600px) {   .container {       width: 1200px;   }}/* EXTRA LARGE DESKTOP */@media screen and (min-width: 1601px) {   .container {       width: 1600px;   }} When you view a website on a desktop, it's quite a common thing to have a left and a right column. Generally, the left column contains information that requires more focus and the right column contains content with a bit less importance. In some cases, you might even have three columns. Take the social website Facebook as an example. At the time of writing this article, Facebook used a three-column layout, which is as follows:   When you view a web page on a mobile device, you won't be able to fit all three columns into the smaller viewport. So, you'd probably want to hide some of the columns and not request the data that is usually displayed in the columns that are hidden. Alright, we've done some talking. Well, you've done some reading. Now, let's get into our code! Our goal in this section is to learn about conditional development, with the focus on images. I've constructed a little website with a two-column layout. The left column houses the content and the right column is used to populate a little news feed. I made a simple PHP script that returns a JSON object with the news items. Here is a preview of the different screens that we will work on:   These two views are a result of the queries that are shown in the following style sheet code: /* MOBILE */@media screen and (max-width: 480px) {}/* TABLETS */@media screen and (min-width: 481px) and (max-width: 720px) {} Summary Managing images is no small feat in a website. Almost all modern websites rely heavily on images to present content to the users. In this article we looked at which image formats to use and when. We also looked at how to optimize your images for websites. We discussed the difference between progressive and optimized images as well. Conditional loading can greatly help you to load your site faster. In this article, we briefly discussed how to use conditional loading to improve your site's performance. Resources for Article: Further resources on this subject: A look into responsive design frameworks [article] Building Responsive Image Sliders [article] Creating a Responsive Project [article]
Read more
  • 0
  • 0
  • 12081

article-image-creating-attention-grabbing-pricing-tables
Packt
17 Feb 2014
6 min read
Save for later

Creating attention-grabbing pricing tables

Packt
17 Feb 2014
6 min read
(For more resources related to this topic, see here.) Let's revisit the mockup of how our client would like the pricing tables to look on desktop-sized screens: Let's see how close we can get to the desired result, and what we can work out for other viewport sizes. Setting up the variables, files, and markup As shown in the preceding screenshot, there are a few tables in this design. We can begin by adjusting a few fundamental variables for all tables. These are found in _variables.less. Search for the tables section and adjust the variables for background, accented rows, and borders as desired. I've made these adjustments as shown in the following lines of code: // Tables // ------------------------- ... @table-bg: transparent; // overall background-color @table-bg-accent: hsla(0,0,1%,.1); // for striping @table-bg-hover: hsla(0,0,1%,.2); @table-bg-active: @table-bg-hover; @table-border-color: #ccc; // table and cell border Save the file, compile it to CSS, and refresh to see the result as shown in the following screenshot: That's a start. Now we need to write the more specific styles. The _page-contents.less file is now growing long, and the task before us is extensive and highly focused on table styles. To carry the custom styles, let's create a new LESS file for these pricing tables: Create _pricing-tables.less in the main less folder. Import it into __main.less just after _page-contents.less as shown in the following line: @import "_pricing-tables.less"; Open _pricing-tables.less in your editor and begin writing your new styles. But before we begin writing styles, let's review the markup that we'll be working with. We have the following special classes already provided in the markup on the parent element of each respective table:   package package-basic package package-premium package package-pro   Thus, for the first table, you'll see the following markup on its parent div: <div class="package package-basic col-lg-4"> <table class="table table-striped"> ... Similarly, we'll use package package-premium and package package-pro for the second and third table, respectively. These parent containers obviously also provide basic layout instructions using the col-md-4 class to set up a three-column layout in medium viewports. Next, we will observe the markup for each table. We see that the basic table and table-striped classes have been applied: <table class="table table-striped"> The table uses the <thead> element for its top-most block. Within this, there is <th> spanning two columns, with an <h2> heading for the package name and <div class="price"> to markup the dollar amount: <thead><tr><th colspan="2"><h2>Basic Plan</h2><div class="price">$19</div></th></tr></thead> Next is the tfoot tag with the Sign up Now! button: <tfoot><tr><td colspan="2"><a href="#" class="btn">Sign upnow!</a></td></tr></tfoot> Then is the tbody tag with the list of features laid out in a straightforward manner in rows with two columns: <tbody><tr><td>Feature</td><td>Name</td></tr><tr><td>Feature</td><td>Name</td></tr><tr><td>Feature</td><td>Name</td></tr><tr><td>Feature</td><td>Name</td></tr><tr><td>Feature</td><td>Name</td></tr></tbody> And finally, of course, the closing tags for the table and parent div tags: </table></div><!-- /.package .package-basic --> Each table repeats this basic structure. This gives us what we need to start work! Beautifying the table head To beautify the thead element of all of our tables, we'll do the following: Align the text at the center Add a background color—for now, add a gray color that is approximately a midtone similar to the colors we'll apply to the final version Turn the font color white Convert the h2 heading to uppercase Increase the size of the price table Add the necessary padding all around the tables We can apply many of these touches with the following lines of code. We'll specify the #signup section as the context for these special table styles: #signup {table {border: 1px solid @table-border-color;thead th {text-align: center;background-color: @gray-light;color: #fff;padding-top: 12px;padding-bottom: 32px;h2 {text-transform: uppercase;}}}} In short, we've accomplished everything except increasing the size of the price tables. We can get started on this by adding the following lines of code, which are still nested within our #signup table selector: .price { font-size: 7em; line-height: 1;} This yields the following result: This is close to our desired result, but we need to decrease the size of the dollar sign. To give ourselves control over that character, let's go to the markup and wrap a span tag around it: <em class="price"><span>$</span>19</em> Remember to do the same for the other two tables. With this new bit of markup in place, we can nest this within our styles for .price: .price {...span {font-size: .5em;vertical-align: super;} These lines reduce the dollar sign to half its size and align it at the top. Now to recenter the result, we need to add a bit of negative margin to the parent .price selector: .price {margin-left: -0.25em;... The following screenshot shows the result: Styling the table body and foot By continuing to focus on the styles that apply to all three pricing tables, let's make the following adjustments: Add left and right padding to the list of features Stretch the button to full width Increase the button size We can accomplish this by adding the following rules: #signup {table {...tbody {td {padding-left: 16px;padding-right: 16px;}}a.btn {.btn-lg;display: block;width: 100%;background-color: @gray-light;color: #fff;}}} Save the file, compile it to CSS, and refresh the browser. You should see the following result: We're now ready to add styles to differentiate our three packages.
Read more
  • 0
  • 0
  • 12033
article-image-scalability-limitations-and-effects
Packt
23 Aug 2013
26 min read
Save for later

Scalability, Limitations, and Effects

Packt
23 Aug 2013
26 min read
(For more resources related to this topic, see here.) HTML5 limitations If you haven't noticed by now, many of the HTML5 features you will use either have failsafes, multiple versions, or special syntax to enable your code to cover the entire spectrum of browsers and supported HTML5 feature sets within them. As time passes and standards become solidified, one can assume that many of these failsafes and other content display measures will mature into a single standard that all browsers will share. However, in reality this process may take a while and even at its best, developers may still have to utilize many of these failsafe features indefinitely. Therefore, a solid understanding of when, where, and why to use these failsafe measures will enable you develop your HTML5 web pages in a way that can be viewed as intended on all modern browsers. To aid developers in overcoming these previously stated issues, many frameworks and external scripts have been created and open sourced, allowing for a more universal development environment saving developers countless hours when starting each new project. Modernizr (http://modernizr.com) has quickly become a must-have addition for many HTML5 developers as it contains many of the conditions and verifications needed to allow developers to write less code and cover more browsers. Modernizr does all this by checking for a large majority (more then 40) of the new features available in HTML5 in the clients browser and reporting back if they are available or not in a matter of milliseconds. This will allow you as the developer to determine if you should display an alternate version of your content or a warning to the user. Getting your web content to display properly in all browsers is and always has been the biggest challenge for any web developer and when it comes to creating cutting edge interesting content, the challenge usually becomes harder. To allow you to better understand how these features look without the use of third-party integration, we will avoid using external libraries for the time being. It is worth noting how each of these features and others look in all browsers. Therefore make sure to test the examples as well as your own work in not just your favorite browser, but many of the other popular choices as well. Object manipulation with CSS3 Prior to the advent of CSS3, web developers used a laundry list of content manipulation, asset preparation, and asset presentation techniques in order to get their web page layout the way they wanted in every browser. Most of these techniques would be considered "hacks" as they would pretty much be a work around to enable the browser to do something it normally wouldn't. Features such as rounded corners, drop shadows, and transforms were all absent from a web developer's arsenal and the process of getting things the way you want could get mind numbing. Understandably, the excitement level surrounding CSS3 for all web developers is very high as it enables developers to perform more content manipulation techniques then ever before without the need for prior preparation or special browser hacks. Although the list of available properties in CSS3 is massive, let's cover some of the newest and most exciting of the lot. box-shadow It's true that some designers and developers say drop shadows are a part of the past, but the usage of shadowing HTML elements is still a popular design choice for many. In the past, web developers needed to perform tricks such as stretching small gradient images or creating the shadow directly into their background image to achieve this effect in their HTML documents. CSS3 has solved this issue by creating the box-shadow property to allow for drop shadow like effects on your HTML elements. To remind us how this effect was accomplished in ActionScript 3, let's review this code snippet: var dropShadow:DropShadowFilter = new DropShadowFilter();dropShadow.distance = 0;dropShadow.angle = 45;dropShadow.color = 0x333333;dropShadow.alpha = 1;dropShadow.blurX = 10;dropShadow.blurY = 10;dropShadow.strength = 1;dropShadow.quality = 15;dropShadow.inner = false;var mySprite:Sprite = new Sprite();mySprite.filters = new Array(dropShadow); As mentioned before, the new box-shadow property in CSS3 allows you to append these shadowing effects with relative ease and many of the same configuration properties: .box-shadow-example { box-shadow: 3px 3px 5px 6px #000000;} Despite the lack of property names on each of the values applied to this style, you can see that many of the value types coincide with what was appended to the drop shadow we created in ActionScript 3. This box-shadow property is assigned to the .box-shadow-example class and therefore will be applied to any element that has that classname appended to it. By creating a div element with the box-shadow-example class, we can alter our content to look something like the following: <div class="box-shadow-example">CSS3 box-shadow Property</div> As straightforward as this CSS property is to add to your project, it declares a lot of values all in a single line. Let's review each of these values in order that we can understand them better for future usage. To simplify the identification of each of the variables in the property, each of these have been updated to be different: box-shadow: 1px 2px 3px 4px #000000; These variables are explained as follows: The initial value (1px) is the shadow's horizontal offset or if the shadow is going to the left or to the right. A positive value would place the shadow on the right of the element, a negative offset will put the shadow on the left. The second value (2px) is the vertical offset, and just like the horizontal offset value, a negative number would generate a shadow going up and a positive value would generate the shadow going down. The third value (3px) is the blur radius that controls how much blur effect will be added to the shadow. Declaring a value, for example, 0 would create no blur and display a very sharp looking shadow. Negative values placed into the blur radius will be ignored and render no different then using 0. The fourth value (4px) and last of the numerical properties is the spread radius. The spread radius controls how far the drop shadow blur will spread past the initial shadow size declaration. If a value 0 is used, the shadow will display with the default blur radius set and apply no changes. Positive numerical values will yield a shadow that blurs further and negative value will make the shadow blur smaller. The final value is the hexadecimal color value, which states the color that the shadow will be in. Alternatively, you could use box-shadow to apply the shadow effect to the interior of your element rather then the exterior. With ActionScript 3, this was accomplished by appending dropShadow.inner = true; to the list of parameters in your DropShadowFiler object. The CSS3 syntax to apply box-shadow properties in this manner is very similar as all that is required is the addition of the inset keyword. Consider the following code snippet, for example: .box-shadow-example { box-shadow: 3px 3px 5px 6px #666666 inset;} This would produce a shadow that would look like the following screenshot: text-shadow Just like the box-shadow property, text-shadow lives up to its name by creating the same drop-shadowing effect, specifically for text: text-shadow: 2px 2px 6px #ff0000; Like box-shadow, the initial two values for text-shadow are the horizontal and vertical offsets for the shadow placement. The third value, which is optional is the blur size and the fourth value is the hexadecimal color: border-radius Just like element or text shadowing, adding rounded corners to your elements prior to CSS3 was a chore. Developers would usually append separate images or use other object manipulation techniques to achieve this effect on the typically square or rectangle shaped elements. With the addition of the border-radius setting in CSS3, developers can easily and dynamically set element corner roundness with only a couple of line of CSS all without the usage of vector 9 slicing like in Flash. Since HTML elements have four corners, when appending the border-radius styling, we can either target each corner individually, or all the corners at once. In order to easily append a border radius setting to all the corners at once, we would create our CSS properties as follows: #example { background-color:#ff0000; // Red background width: 200px; height: 200px;border-radius: 10px;} The preceding CSS not only appends a 10px border radius to all of the corners of the #example element, by using all the properties, which the modern browsers use, we can be assured that the effect will be visible to all users attempting to view this content: As mentioned above, each of the individual corners of the element can be targeted to only append the radius to a specific part of the element: #example { border-top-left-radius: 0px; // This is doing nothing border-top-right-radius: 5px; border-bottom-right-radius: 20px; border-bottom-left-radius: 100px;} The preceding CSS now removes our #example element's left border radius by setting it to 0px and sets a specific radius to each of the other corners. It's worth noting here that setting a border radius equal to 0 is no different than leaving that property completely out of the CSS styles: Fonts Dealing with customized fonts in Flash has had its ups and downs over the years. Any Flash developer who has needed to incorporate and use customized fonts in their Flash applications probably knows the pain that comes with choosing a font embedding method as well as making sure it works properly for users who don't have the font installed on their computer viewing the Flash application. CSS3 font embedding has implemented a "no fuss" way to include custom fonts into your HTML5 documents with the addition of the @font-face declaration: @font-face { font-family: ClickerScript; src: url('ClickerScript-Regular.ttf'), url('ClickerScript-Regular .otf'), url('ClickerScript-Regular .eot');} CSS can now directly reference your TTF, OTF, or EOT font which can be placed on your web server for accessibility. With the font source declared in our CSS document and a unique font-family identification applied to it, we can start using it on specific elements by using the font-family property: #example { font-family: ClickerScript;} Since we declared a specific font family name in the @font-face property, we can use that custom name on pretty much any element henceforth. Custom fonts can be applied to almost anything that contains text in your HTML document. Form elements such as button labels and text inputs also can be styled to used your custom fonts. You can even remake assets such as website logos in pure HTML and CSS with the same custom fonts used in the original asset creation. Acceptable font formats Like many of the other embedding methods for assets online, fonts needs to be converted into multiple formats to enable all common modern browsers to display them properly. Almost all of the available browsers will be able to handle the common True Type Fonts (.ttffile types) or Open Type Fonts (.otffile types), so embedding one of those two formats will be all that is needed. Unfortunately Internet Explorer 9 does not have support built in for either of those two popular formats and requires fonts to be saved in the EOT file format. External font libraries Many great services have appeared online in the last couple of years allowing web developers to painlessly prepare and embed fonts into their websites. Google's Web Fonts archive available at http://www.google.com/webfonts hosts a large set of open source fonts which can be added to your project without the need to worry about licensing or payment issues. Simply add a couple of extras lines of code into your HTML document and you are ready to go. Another great site that is worth checking out is Font Squirrel, which can be found at http://www.fontsquirrel.com. Like Google Web Fonts, Font Squirrel hosts a large archive of web-ready fonts with the copy-and-paste-ready code snippets to add them to your document. Another great feature on this site is the @font-face generator which give you the ability to convert your preexisting fonts into all the web compatible formats. Before getting carried away and converting all your favorite fonts into web ready formats and integrating them into your work, it is worth noting the End User License Agreement or EULA that came with the font to begin with. Converting many available fonts for use on the web will break license agreements and could cause legal issues for you down the road. Opacity More commonly known as "alpha" to the Flash developer, setting the opacity of an element not only allows you to change the look and feel of your designs, but allows you to add features like content that fades in and out. As simple as this concept seems, it is relatively new to the available list of CSS properties available to web developers. Setting the opacity of an element is extremely easy and looks something like the following: #example { opacity: 0.5;} As you can see from the preceding example, like ActionScript 3, the opacity value is a numerical value between 0 and 1. The preceding example would display a element at 50 percent transparency. The opacity property in CSS3 is now supported in all the major browsers, so there is no need to worry about using alternative property syntax when declaring it. RGB and RGBA coloring When dealing with color values in CSS, many developers would typically use hexadecimal values, which would resemble something like #000000 to declare the usage of the color black. Colors can also be implemented in their RGB representation in CSS by utilizing the rgb() or rgba() calls in place of the hexadecimal value. As you can see by the method name, the rgba color lookup in CSS also requires a forth parameter which declares the colors alpha transparency or opacity amount. Using RGBA in CSS3 rather than hexadecimal colors can be beneficial for a couple of reasons. Consider you have just created a div element which will be displayed on top of existing content within your web page layout. If you ever wanted to set a background color to the div as a specific color but wish for only that background to be semi transparent and not the interior content, the RGBA color declaration now allows you to do this easily as you can set the colors transparency: #example { // Background opacity background: rgba(0, 0, 0, 0.5); // Black 50% opacity // Box-shadow box-shadow: 1px 2px 3px 4px rgba(255, 255, 255, 0.8); // White 80% opacity // Text opacity color: rgba(255, 255, 255, 1); // White no transparency color: rgb(255, 255, 255); // This would accomplish the same styling // Text Drop Shadows (with opacity) text-shadow: 5px 5px 3px rgba(135, 100, 240, 0.5);} As you can see in the preceding example, you can freely use RGB and RGBA values rather than hexadecimal anywhere color values are required in CSS syntax. Element transforms Personally, Ifind CSS3 transforms to be one of the most exciting and fun new features in CSS. Transforming assets in the Flash IDE as well as with ActionScript has always been easily accessible and easy to implement. Transforming HTML elements is a relatively new feature to CSS and is still gaining full support by all the modern browsers. Transforming an element allows you to manipulate its shape and size by opening up a ton of possibilities for animations and visual effects to assets without the need to prepare the source before hand. When we refer to "transforming an element", we are actually describing a number of properties that can be applied to the transformation to give it different characteristics. If you have transformed objects in Flash or possibly in Photoshop before, these properties may be familiar to you. Translate As a Flash developer used to primarily dealing with X and Y coordinates when positioning elements, the CSS3 Translate Transform property is a very handy way of placing elements and it works on the same principal. The translate property takes two parameters which are the X and the Y values to translate, or effectively move the element: transform:translate(-25px, -25px); Unfortunately, to get your transforms to work in all browsers, you will need to target each of them when you append transform styles. Therefore, the standard transform style and property would now look something like this: transform:translate(-25px, -25px);-ms-transform:translate(-25px, -25px); /* IE 9 */-moz-transform:translate(-25px, -25px); /* Firefox */-webkit-transform:translate(-25px, -25px); /* Safari and Chrome */-o-transform:translate(-25px, -25px); /* Opera */ Rotate Rotation is pretty self-explanatory and extremely easy to implement. The rotate properties take a single parameter to specify the amount of rotation, in degrees, to apply to the specific element: transform:rotate(45deg);-ms-transform:rotate(45deg); /* IE 9 */-moz-transform:rotate(45deg); /* Firefox */-webkit-transform:rotate(45deg); /* Safari and Chrome */-o-transform:rotate(45deg); /* Opera */ It is worth noting that regardless of the fact that the supplied value is always intended to be a value in degrees, the value must always have deg appended for the value to be properly recognized. Scale Just like rotate transforms, scaling is pretty straightforward. The scale property requires two parameters, which declare the scale amount for both X and Y: transform:scale(0.5, 2);-ms-transform:scale(0.5, 2); /* IE 9 */-moz-transform:scale(0.5, 2); /* Firefox */-webkit-transform:scale(0.5, 2); /* Safari and Chrome */-o-transform:scale(0.5, 2); /* Opera */ Skew Skewing a element will result in the angling of the X and Y axes: transform:skew(10deg, 20deg);-ms-transform:skew(10deg, 20deg); /* IE 9 */-moz-transform:skew(10deg, 20deg); /* Firefox */-webkit-transform:skew(10deg, 20deg); /* Safari and Chrome */-o-transform:skew(10deg, 20deg); /* Opera */ The following illustration is a representation of skewing an image with the preceding properties: Matrix The matrix properties combine all of the preceding transforms into a single property and can easily eliminate many extra lines of CSS in your source: transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20);/* IE 9 */-ms-transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20);/* Firefox */-moz-transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20); /* Safari and Chrome */ -webkit-transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20);/* Opera */-o-transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20); The preceding example utilizes the CSS transform matrix property to apply multiple transform styles in a single call. The matrix property requires six parameters to rotate, scale, move, and skew the element. Using the matrix property is only really useful when you actually need to implement all of the transform properties at once. If you only need to utilize one aspect of element transforms, you will be better off using just that CSS style property. 3D transforms Up until now, all of the transform properties we have reviewed have been two dimensional transformations. CSS3 now also supports 3D as well as 2D transforms.One of the best parts of CSS3 3D transforms is the fact that many devices and browsers support hardware acceleration allowing this complex graphical processing to be done on your video cards GPU. At the time of writing this, only Chrome, Safari, and firefox have support for CSS 3D transforms. Interested in what browsers will support all these great HTML5 features before you start developing? Check out http://caniuse.com to see what popular browsers support in a simple, easy-to-use website. When dealing with elements in a 3D world, we make use of the Z coordinate, which allows the use of some new transform properties. transform:rotateX(angle)transform:rotateY(angle)transform:rotateZ(angle)transform:translateZ(px)transform:scaleZ(px) Let's create a 3D cube from HTML elements to put all of these properties into a working example. To start creating our 3D cube, we will begin by writing the HTML elements which will contain the cube as well as the elements which will be making up the cube itself: <body> <div class="container"> <div id="cube"> <div class="front"></div> <div class="back"></div> <div class="right"></div> <div class="left"></div> <div class="top"></div> <div class="bottom"></div> </div> </div></body> This HTML creates a simple layout for our cube by not only creating each of the six sides, which makes up a cube with specific class names, but the container for the entire cube as well as the main container to display all of our page content. Of course, since there is no internal content in these containers and no styling yet, opening this HTML file in your browser would yield an empty page. So let's start writing our CSS to make all of these elements visible and position each to form our three dimensional cube. We will start by setting up our main containers which will position our content and contain our cubes sides: .container { width: 640px; height: 360px; position: relative; margin: 200px auto; /* Currently only supported by Webkit browsers. */ -webkit-perspective: 1000px; perspective: 1000px;}#cube { width: 640px; height: 320px; position: absolute; /* Let the transformed child elements preserve the 3D transformations: */ transform-style: preserve-3d; -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d;} The container class is our main element, which contains all of the other elements within this example. After appending a width and height, we set the top margin to 200px to push the display down the page a bit for better viewing and the left and right margins to auto which will align this element in the center of the page: #cube div { display: block; position: absolute; border: 1px solid #000000; width: 640px; height: 320px; opacity:0.8;} By defining properties to the #cube div, we set the styles to every div element within the #cube element. We are also kind of cheating the system of cube by setting the width and height to rectangular proportions as the intention is to add videos to each of the cube sides once we structure and position it. With the basic cube-side styles appended, its time to start transforming each of the sides to form the three-dimensional cube. We will start with the front of the cube by translating it on the Z axis, bringing it closer to the perspective: #cube .front {-webkit-transform: translateZ(320px); -moz-transform: translateZ(320px); transform: translateZ(320px);} In order to append this style to our element in all modern browsers, we will need to specify the property in multiple syntaxes for each browser that doesn't support the default transform property: The preceding screenshot shows what has happened to the .front div after appending a Z translation of 320px. The larger rectangle is the .front div, which is now 320px closer to our perspective. For simplicity's sake, let's do the same to the .back div and push it 320px away from the perspective: #cube .back { -webkit-transform: rotateX(-180deg) rotate(-180deg) translateZ(320px); -moz-transform: rotateX(-180deg) rotate(-180deg) translateZ(320px); transform: rotateX(-180deg) rotate(-180deg) translateZ(320px);} As you can see from the preceding code, to properly move the .back element into place without placing it upside down, we flip the element by 180 degrees on the X axis and then translate Z by 320px just like we did for .front. Note that we didn't set a negative value on the translate Z because the element was flipped. With the .back CSS styles in place, our cube should look like the following: Now the smallest rectangle visible is the element with the classname .back, the largest is our .front element, and the middle rectangle is the remaining elements to be transformed. To position the sides of our cubes we will need to rotate the side elements on the Y axis to get them to face the proper direction. Once they are rotated into place, we can translate the position on the Z axis to push it out from the center as we did with the front and back faces: #cube .right { -webkit-transform: rotateY(90deg) translateZ( 320px ); -moz-transform: rotateY(90deg) translateZ( 320px ); transform: rotateY(90deg) translateZ( 320px );} With the right side in place, we can do the same to the left side but rotate it in the opposite direction to get it facing the other way: #cube .left {-webkit-transform: rotateY(-90deg) translateZ( 320px ); -moz-transform: rotateY(-90deg) translateZ( 320px ); transform: rotateY(-90deg) translateZ( 320px );} Now that we have all four sides of our cube aligned properly, we can finalize the cube positioning by aligning the top and bottom sides. To properly size the top and bottom we will set their own width and height to override the initial values set in the #cube div styles: #cube .top { width: 640px; height: 640px; -webkit-transform: rotateX(90deg) translateZ( 320px ); -moz-transform: rotateX(90deg) translateZ( 320px ); transform: rotateX(90deg) translateZ( 320px );}#cube .bottom { width: 640px; height: 640px; -webkit-transform: rotateX(-90deg) translateZ( 0px ); -moz-transform: rotateX(-90deg) translateZ( 0px ); transform: rotateX(-90deg) translateZ( 0px );} To properly position the top and bottom sides, we rotate the .top and .bottom elements +-90 degrees on the X axis to get them to face up and down, and only need to translate the top on the Z axis to raise it to the proper height to connect with all of the other sides. With all of those transforms appended to our layout, the resulting cube should look like the following: Although it looks 3D, since there is nothing in the containers, the perspective isn't really showing off our cube very well. So let's add some content such as a video in each of the sides of the cube to get a better visualization of our work. Within each of the sides, let's add the same HTML5 video element code: <video width="640" height="320" autoplay="true" loop="true"> <source src = "cube-video.mp4" type="video/mp4"> <source src = "cube-video.webm" type="video/webm"> Your browser does not support the video tag.</video> Since we have not added the element playback controls in order to display more visible area of the cube, our video element is set to autoplay the video as well as loop the playback on completion. Now we get a result that properly demonstrates what 3D transforms can do and is a little more visually appealing: Since we set the opacity of each of the cube sides, we can now see all four videos playing on each side, pretty cool! Since we are already here, why not kick it up one more notch and add user interaction to this cube so we can spin it around and see the video on each side. To perform this user interaction, we need to use JavaScript to translate the mouse coordinates on the page document to the X and Y 3D rotation of our cube. So let's start by creating the JavaScript to listen for mouse events: window.addEventListener("load", init, false);function init() { // Listen for mouse movement window.addEventListener('mousemove', onMouseMove, false);}function onMouseMove(e) { var mouseX = 0; var mouseY = 0; // Get the mouse position if (e.pageX || e.pageY) { mouseX = e.pageX; mouseY = e.pageY; } else if (e.clientX || e.clientY) { mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } console.log("Mouse Position: x:" + mouseX + " y:" + mouseY);} As you can see from the preceding code example, when the mousemove event fires and calls the onMouseMove function, we need to run some conditionals to properly parse the proper mouse position. Since, like so many other parts of web development, retrieving the mouse coordinates differs from browser to browser, we have added a simple condition to attempt to gather the mouse X and Y in a couple of different ways. With the mouse position ready to be translated into the transform rotation of our cube, there is one final bit of preparation we need to complete prior to setting the CSS style updates. Since different browsers support the application of CSS transforms in different syntaxes, we need to figure out, in JavaScript, which syntax to use during runtime to allow our script to run on all browsers. The following code example does just that. By setting a predefined array of the possible property values and attempting to check the type of each as an element style property, we can find which element is not undefined and know it can be used for CSS transform styles: // Get the support transform propertyvar availableProperties = [ 'transform', 'MozTransform', 'WebkitTransform', 'msTransform', 'OTransform' ];// Loop over each of the propertiesfor (var i = 0; i < availableProperties.length; i++) { // Check if the type of the property style is a string (ie. valid) if (typeof document.documentElement.style[availableProperties[i]] == 'string'){ // If we found the supported property, assign it to a variable // for later use. var supportedTranformProperty = availableProperties[i]; }} Now that we have the user's mouse position and the proper syntax for CSS transform updates for our cube, we can put it all together and finally have 3D rotational control of our video cube: <script> var supportedTranformProperty; window.addEventListener("load", init, false); function init() { // Get the support transform property var availableProperties = ['transform', 'MozTransform', 'WebkitTransform', 'msTransform', 'OTransform']; for (var i = 0; i < availableProperties.length; i++) { if (typeof document.documentElement. style[availableProperties[i]] == 'string'){ supportedTranformProperty = availableProperties }} // Listen for mouse movement window.addEventListener('mousemove', onMouseMove, false); } function onMouseMove(e) { // Get the mouse position if (e.pageX || e.pageY) { mouseX = e.pageX; mouseY = e.pageY; } else if (e.clientX || e.clientY) { mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;} // Update the cube rotation rotateCube(mouseX, mouseY); } function rotateCube(posX, posY) { // Update the CSS transform styles document.getElementById("cube").style[supportedTranformProperty] = 'rotateY(' + posX + 'deg) rotateX(' + posY * -1 + 'deg)'; }</script> Regardless of the fact we have attempted to allow for multi browser use of this example, it is worth opening it up in each to see how something like 3D transforms with heavy internal content run. During the time of writing this, all WebKit browsers were the easy choice when viewing content like this, as browsers such as firefox and Internet Explorer render this example at a much slower and lower quality output: Transitions With CSS3, we can add an effect when changing from one style to another, without using Flash animations or JavaScripts: div { transition: width 2s; -moz-transition: width 2s; /* Firefox 4 */ -webkit-transition: width 2s; /* Safari and Chrome */ -o-transition: width 2s; /* Opera */} If the duration is not specified, the transition will have no effect, because the default value is 0: div { transition: width 2s, height 2s, transform 2s; -moz-transition: width 2s, height 2s, -moz-transform 2s; -webkit-transition: width 2s, height 2s, -webkit-transform 2s; -o-transition: width 2s, height 2s,-o-transform 2s;} It should be worth noting that Internet Explorer currently does not have support for CSS3 transitions. Browser compatibility If you haven't noticed yet, the battle of browser compatibility is one of the biggest aspects of a web developer's job. Over time, many great services and applications have been created to help developers overcome these hurdles in a much simpler manner than trial-and-error techniques. Websites such as http://css3test.com, http://caniuse.com, and http://html5readiness.com are all great resources to keep on top of HTML5 specification developer and browser support for all the features within.
Read more
  • 0
  • 0
  • 11943

article-image-introducing-web-application-development-rails
Packt
25 Feb 2015
8 min read
Save for later

Introducing Web Application Development in Rails

Packt
25 Feb 2015
8 min read
In this article by Syed Fazle Rahman, author of the book Bootstrap for Rails,we will learn how to present your application in the best possible way, which has been the most important factor for every web developer for ages. In this mobile-first generation, we are forced to go with the wind and make our application compatible with mobiles, tablets, PCs, and every possible display on Earth. Bootstrap is the one stop solution for all woes that developers have been facing. It creates beautiful responsive designs without any extra efforts and without any advanced CSS knowledge. It is a true boon for every developer. we will be focusing on how to beautify our Rails applications through the help of Bootstrap. We will create a basic Todo application with Rails. We will explore the folder structure of a Rails application and analyze which folders are important for templating a Rails Application. This will be helpful if you want to quickly revisit Rails concepts. We will also see how to create views, link them, and also style them. The styling in this article will be done traditionally through the application's default CSS files. Finally, we will discuss how we can speed up the designing process using Bootstrap. In short, we will cover the following topics: Why Bootstrap with Rails? Setting up a Todo Application in Rails Analyzing folder structure of a Rails application Creating views Styling views using CSS Challenges in traditionally styling a Rails Application (For more resources related to this topic, see here.) Why Bootstrap with Rails? Rails is one the most popular Ruby frameworks which is currently at its peak, both in terms of demand and technology trend. With more than 3,100 members contributing to its development, and tens of thousands of applications already built using it, Rails has created a standard for every other framework in the Web today. Rails was initially developed by David Heinemeier Hansson in 2003 to ease his own development process in Ruby. Later, he became generous enough to release Rails to the open source community. Today, it is popularly known as Ruby on Rails. Rails shortens the development life cycle by moving the focus from reinventing the wheel to innovating new features. It is based on the convention of the configurations principle, which means that if you follow the Rails conventions, you would end up writing much less code than you would otherwise write. Bootstrap, on the other hand, is one of the most popular frontend development frameworks. It was initially developed at Twitter for some of its internal projects. It makes the life of a novice web developer easier by providing most of the reusable components that are already built and are ready to use. Bootstrap can be easily integrated with a Rails development environment through various methods. We can directly use the .css files provided by the framework, or can extend it through its Sass version and let Rails compile it. Sass is a CSS preprocessor that brings logic and functionality into CSS. It includes features like variables, functions, mixins, and others. Using the Sass version of Bootstrap is a recommended method in Rails. It gives various options to customize Bootstrap's default styles easily. Bootstrap also provides various JavaScript components that can be used by those who don't have any real JavaScript knowledge. These components are required in almost every modern website being built today. Bootstrap with Rails is a deadly combination. You can build applications faster and invest more time to think about functionality, rather than rewrite codes. Setting up a Todo application in Rails I assume that you already have basic knowledge of Rails development. You should also have Rails and Ruby installed in your machine to start with. Let's first understand what this Todo application will do. Our application will allow us to create, update, and delete items from the Todo list. We will first analyze the folders that are created while scaffolding this application and which of them are necessary for templating the application. So, let's dip our feet into the water: First, we need to select our workspace, which can be any folder inside your system. Let's create a folder named Bootstrap_Rails_Project. Now, open the terminal and navigate to this folder. It's time to create our Todo application. Write the following command to create a Rails application named TODO: rails new TODO This command will execute a series of various other commands that are necessary to create a Rails application. So, just wait for sometime before it stops executing all the codes. If you are using a newer version of Rails, then this command will also execute bundle install command at the end. Bundle install command is used to install other dependencies. The output for the preceding command is as follows: Now, you should have a new folder inside Bootstrap_Rails_Project named TODO, which was created by the preceding code. Here is the output: Analyzing folder structure of a Rails application Let's navigate to the TODO folder to check how our application's folder structure looks like: Let me explain to you some of the important folders here: The first one is the app folder. The assets folder inside the app folder is the location to store all the static files like JavaScript, CSS, and Images. You can take a sneak peek inside them to look at the various files. The controllers folder handles various requests and responses of the browser. The helpers folder contains various helper methods both for the views and controllers. The next folder mailers, contains all the necessary files to send an e-mail. The models folder contains files that interact with the database. Finally, we have the views folder, which contains all the .erb files that will be complied to HTML files. So, let's start the Rails server and check out our application on the browser: Navigate to the TODO folder in the terminal and then type the following command to start a server: rails server You can also use the following command: rails s You will see that the server is deployed under the port 3000. So, type the following URL to view the application: http://localhost:3000. You can also use the following URL: http://0.0.0.0:3000. If your application is properly set up, you should see the default page of Rails in the browser: Creating views We will be using Rails' scaffold method to create models, views, and other necessary files that Rails needs to make our application live. Here's the set of tasks that our application should perform: It should list out the pending items Every task should be clickable, and the details related to that item should be seen in a new view We can edit that item's description and some other details We can delete that item The task looks pretty lengthy, but any Rails developer would know how easy it is to do. We don't actually have to do anything to achieve it. We just have to pass a single scaffold command, and the rest will be taken care of. Close the Rails server using Ctrl + C keys and then proceed as follows: First, navigate to the project folder in the terminal. Then, pass the following command: rails g scaffold todo title:string description:text completed:boolean This will create a new model called todo that has various fields like title, description, and completed. Each field has a type associated with it. Since we have created a new model, it has to be reflected in the database. So, let's migrate it: rake db:create db:migrate The preceding code will create a new table inside a new database with the associated fields. Let's analyze what we have done. The scaffold command has created many HTML pages or views that are needed for managing the todo model. So, let's check out our application. We need to start our server again: rails s Go to the localhost page http://localhost:3000 at port number 3000. You should still see the Rails' default page. Now, type the URL: http://localhost:3000/todos. You should now see the application, as shown in the following screenshot: Click on New Todo, you will be taken to a form which allows you to fill out various fields that we had earlier created. Let's create our first todo and click on submit. It will be shown on the listing page: It was easy, wasn't it? We haven't done anything yet. That's the power of Rails, which people are crazy about. Summary This article was to brief you on how to develop and design a simple Rails application without the help of any CSS frontend frameworks. We manually styled the application by creating an external CSS file styles.css and importing it into the application using another CSS file application.css. We also discussed the complexities that a novice web designer might face on directly styling the application. Resources for Article: Further resources on this subject: Deep Customization of Bootstrap [article] The Bootstrap grid system [article] Getting Started with Bootstrap [article]
Read more
  • 0
  • 0
  • 11788

article-image-bootstrap-box
Packt
07 Aug 2015
6 min read
Save for later

Bootstrap in a Box

Packt
07 Aug 2015
6 min read
In this article written by Snig Bhaumik, author of the book Bootstrap Essentails, we explain the concept of Bootstrap, responsive design patterns, navigation patterns, and the different components that are included in Bootstrap. (For more resources related to this topic, see here.) Responsive design patterns Here are the few established and well-adopted patterns in Responsive Web Design: Fluid design: This is the most popular and easiest option for responsive design. In this pattern, larger screen multiple columns layout renders as a single column in a smaller screen in absolutely same sequence. Column drop: In this pattern also, the page gets rendered in a single column; however, the order of blocks gets altered. That means, if a content block is visible first in order in case of a larger screen, that might be rendered as second or third in case of a smaller screen. Layout shifter: This is a complex but powerful pattern where the whole layout of the screen contents gets altered in case of a smaller screen. This means that you need to develop different page layouts for large, medium, and small screens. Navigation patterns You should take care of the following things while designing a responsive web page. These are essentially the major navigational elements that you would concentrate on while developing a mobile friendly and responsive website: Menu bar Navigation/app bar Footer Main container shell Images Tabs HTML forms and elements Alerts and popups Embedded audios and videos, and so on You can see that there are lots of elements and aspects you need to take care of to create a fully responsive design. While all of these are achieved by using various features and technologies in CSS3, it is of course not an easy problem to solve without a framework that could help you do so. Precisely, you need a frontend framework that takes care of all the pains of technical responsive design implementation and releases you only for your brand and application design. Now, we introduce Bootstrap that would help you design and develop a responsive web design in a much optimized and efficient way. Introducing Bootstrap Simply put, Bootstrap is a frontend framework for faster and easier web development in the new standard of mobile-first philosophy. It uses HTML, CSS, and JavaScript. In August 2010, Twitter released Bootstrap as Open Source. There are quite a few similar frontend frameworks available in the industry, but Bootstrap is arguably the most popular framework in the lot. It is evident when we see Bootstrap is the most starred project in GitHub since 2012. Until now, you must be in a position to fathom why and where we need to use Bootstrap for web development; however, just to recap, here are the points in short. The mobile-first approach A responsive design Automatic browser support and handling Easy to adapt and get going What Bootstrap includes The following diagram demonstrates the overall structure of Bootstrap: CSS Bootstrap comes with fundamental HTML elements styled, global CSS classes, classes for advanced grid patterns, and lots of enhanced and extended CSS classes. For example, this is how the HTML global element is configured in Bootstrap CSS: html { font-family: sans-serif; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } This is how a standard HR HTML element is styled: hr { height: 0; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; } Here is an example of new classes introduced in Bootstrap: .glyphicon { position: relative; top: 1px; display: inline-block; font-family: 'Glyphicons Halflings'; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } Components Bootstrap offers a rich set of reusable and built-in components, such as breadcrumbs, progress bars, alerts, and navigation bars. The components are technically custom CSS classes specially crafted for the specific purpose. For example, if you want to create a breadcrumb in your page, you simply add a DIV tag in your HTML using Bootstrap’s breadcrumb class: <ol class="breadcrumb"> <li><a href="#">Home</a></li> <li><a href="#">The Store</a></li> <li class="active">Offer Zone</li> </ol> In the background (stylesheet), this Bootstrap class is used to create your breadcrumb: .breadcrumb { padding: 8px 15px; margin-bottom: 20px; list-style: none; background-color: #f5f5f5; border-radius: 4px; } .breadcrumb > li { display: inline-block; } .breadcrumb > li + li:before { padding: 0 5px; color: #ccc; content: "/ 0a0"; } .breadcrumb > .active { color: #777; } Please note that these set of code blocks are simply snippets. JavaScript Bootstrap framework comes with a number of ready-to-use JavaScript plugins. Thus, when you need to create Popup windows, Tabs, Carousels or Tooltips, and so on, you just use one of the prepackaged JavaScript plugins. For example, if you need to create a tab control in your page, you use this: <div role="tabpanel"> <ul class="nav nav-tabs" role="tablist"> <li role="presentation" class="active"><a href="#recent" aria-controls="recent" role="tab" data-toggle="tab">Recent Orders</a></li> <li role="presentation"><a href="#all" aria-controls="al" role="tab" data-toggle="tab">All Orders</a></li> <li role="presentation"><a href="#redeem" aria-controls="redeem" role="tab" data-toggle="tab">Redemptions</a></li> </ul>   <div class="tab-content"> <div role="tabpanel" class="tab-pane active" id="recent"> Recent Orders</div> <div role="tabpanel" class="tab-pane" id="all">All Orders</div> <div role="tabpanel" class="tab-pane" id="redeem">Redemption History</div> </div> </div> To activate (open) a tab, you write this JavaScript code: $('#profileTab li:eq(1) a').tab('show'); As you could guess by looking at the syntax of this JavaScript line that the Bootstrap JS plugins are built on top of jQuery. Thus, the JS code you would write for Bootstrap are also all based on jQuery. Customization Even though Bootstrap offers most (if not all) standard features and functionalities for Responsive Web Design, there might be several cases when you would want to customize and extend the framework. One of the very basic requirements for customization would be to deploy your own branding and color combinations (themes) instead of the Bootstrap default ones. There can be several such use cases where you would want to change the default behavior of the framework. Bootstrap offers very easy and stable ways to customize the platform. When you use the Bootstrap CSS, all the global and fundamental HTML elements automatically become responsive and would properly behave as the client device on which the web page is browsed. The built-in components are also designed to be responsive. As the developer, you shouldn’t be worried about how these advanced components would behave in different devices and client agents. Summary In this article we have discussed the basics of Bootstarp along with a brief explanation on the design patterns and the navigation patterns. Resources for Article: Further resources on this subject: Deep Customization of Bootstrap [article] The Bootstrap grid system [article] Creating a Responsive Magento Theme with Bootstrap 3 [article]
Read more
  • 0
  • 0
  • 11725
article-image-introduction-rwd-frameworks
Packt
29 Mar 2013
8 min read
Save for later

Introduction to RWD frameworks

Packt
29 Mar 2013
8 min read
(For more resources related to this topic, see here.) Certainly, whether you are a beginner designer or an expert, creating a responsive website from the ground up can be convoluted. This is probably because of some indispensable technical issues in RWD, such as determining the proper number of columns in the grid and calculating the percentage of the width for each column, determining the correct breakpoint, and other technicalities that usually appear in the development stage. Many threads regarding the issues of creating responsive websites are open on StackOverflow: CSS Responsive grid 1px gap issue (http://stackoverflow.com/questions/12797183/cssresponsive-grid-1px-gap-issue) @media queries - one rule overrides another? (http://stackoverflow.com/questions/12822984/media-queriesone-rule-overrides-another) Why use frameworks? Following are a few reasons why using a framework is considered a good option: Time saver: If done right, using a framework could obviously save a lot of time. A framework generally comes with predefined styles and rules, such as the width of the gird, the button styles, font sizes, form styles, CSS reset, and other aspects to build a website. So, we don't have to repeat the same process from the beginning but simply follow the instructions to apply the styles and structure the markup. Bootstrap, for example, has been equipped with grid styles (http://twitter.github.com/bootstrap/scaffolding.html), basic styles (http://twitter.github.com/bootstrap/base-css.html), and user interface styles (http://twitter.github.com/bootstrap/components.html). Community and extension: A popular framework will most likely have an active community that extends the framework functionality. jQuery UI Bootstrap is perhaps a good example in this case; it is a theme for jQuery UI that matches the look and feel of the Bootstrap original theme. Also, Skeleton, has been extended to the WordPress theme (http://themes.simplethemes.com/skeleton/) and to Drupal (http://demo.drupalizing.com/?theme=skeleton). Cross browser compatibility : This task of assuring how the web page is displayed on different browsers is a really painful one. With a framework, we can minimize this hurdle, since the developers, most likely, have done this job before the framework is released publicly. Foundation is a good example in this case. It has been tested in the iOS, Android, and Windows Phone 7 browsers (http://foundation.zurb.com/docs/support.html). Documentation: A good framework also comes with documentation. The documentation will be very helpful when we are working with a team, to get members on the same page and make them follow the standard code-writing convention. Bootstrap ( http://twitter.github.com/bootstrap/getting-started.html) and Foundation ( http://foundation.zurb.com/docs/index.php), for example, have provided detailed documentation on how to use the framework. There are actually many responsive frameworks to choose from, such as Skeleton, Bootstrap, and Foundation. Let's take a look. Skeleton Skeleton (http://www.getskeleton.com/) is a minimal responsive framework; if you have been working with the 960.gs framework (http://960.gs/), Skeleton should immediately look familiar. Skeleton is 960 pixels wide with 16 columns in its basic grid; the only difference is that the grid is now responsive by integrating the CSS3 media queries. In case this is the first time you have heard about 960.gs or Grid System, you can follow the screencast tutorial by Jeffrey Way available at http://learncss.tutsplus.com/lesson/css-frameworks/. In this screencast, he shows how Grid System works and also guides you to create a website with 960.gs. It is a good place to start with Grid System. Bootstrap Bootstrap (http://twitter.github.com/bootstrap/) was originally built by Mark Otto (http://markdotto.com) and only intended for internal use in Twitter. Short story: Bootstrap was then launched as a free software for public. In it's early development, the responsive feature was not yet included; it was then added in Version 2 in response to the increasing demand for RWD. Bootstrap has a lot more added features as compared to Skeleton. It is packed with styled user interface components of commonly-used interfaces on a website, such as buttons, navigation, pagination, and forms. Beyond that, Bootstrap is also powered with some custom jQuery plugins, such as a tab, carousel, popover, and modal box. To get started with Bootstrap, you can follow the tutorial series (http://www.youtube.com/playlist?list=PLA615C8C2E86B555E) by David Cochran (https://twitter.com/davidcochran). He has thoroughly explained from the basics to utilizing the plugins in this series. Bootstrap has been associated with Twitter so far, but since the author has departed from Twitter and Bootstrap itself has grown beyond expectation, Bootstrap is likely to get separated from the Twitter brand as well (http://blog.getbootstrap.com/2012/09/29/onward/). Foundation Foundation (http://foundation.zurb.com) was built by a team at ZURB (http://www.zurb.com/about/), a product design agency based in California. Similar to Bootstrap, Foundation is beyond just a responsive CSS framework; it is equipped with predefined styles for a common web user interface, such as buttons (http://foundation.zurb.com/docs/components/buttons.html), navigation (http://foundation.zurb.com/docs/components/top-bar.html), and forms. In addition to this, it has also been powered up with some jQuery plugins. A few high-profile brands, such as Pixar (http://projection.pixar.com/) and National Geographic Channel (http://globalcloset.education.nationalgeographic.com/), have built their website on top of this framework. Who is using these frameworks? Now, apart from the two high-profile names we have mentioned in the preceding section, it will be nice to see what other brands and websites have been doing with these frameworks to get inspired. Let's take a look. Hivemind Hivemind is a design firm based in Wisconsin. Their website (www.ourhivemind.com) has been built using Skeleton. As befits the Skeleton framework, their website is very neat, simple, and well structured. The following screenshot shows how it responds in different viewport sizes: Living.is Living.is (http://living.is) is a social sharing website for living room stuff, ideas, and inspiration, such as sofas, chairs, and shelves. Their website has been built using Bootstrap. If you have been examining the Bootstrap UI components yourself, you will immediately recognize this from the button styles. The following screenshot shows how the Living.is page is displayed in the large viewport size: When viewed in a smaller viewport, the menu navigation is concatenated, turning into a navigation button with three stripes, as shown in the following screenshot. This approach now seems to be a popular practice, and this type of button is generally agreed to be a navigation button; the new Google Chrome website has also applied this button approach in their new release. When we click or tap on this button, it will expand the navigation downward, as shown in the following screenshot: To get more inspiration from websites that are built with Bootstrap, you can visit http://builtwithbootstrap.com/. However, the websites listed are not all responsive. Swizzle Swizzle (www.getswizzle.com) is an online service and design studio based in Canada. Their website is built on Foundation. The following screenshot shows how it is displayed in the large viewport size: Swizzle used a different way to deliver their navigation in a smaller viewport. Rather than expanding the menu as Bootstrap does, Swizzle replaces the menu navigation with a MENU link that refers to the navigation at the footer. The cons Using a framework also comes with its own problems. The most common problems found when adopting a framework are as follows: Excessive codes: Since a framework is likely to be used widely, it needs to cover every design scenario, and so it also comes with extra styles that you might not need for your website. Surely, you can sort out the styles and remove them, but this process, depending on the framework, could take a lot of time and could also be a painful task. Learning curve: The first time, it is likely that you will need to spend some time to learn how the framework works, including examining the CSS classes, the ID, and the names, and structuring HTML properly. But, this probably will only happen in your first try and won't be an issue once you are familiar with the framework. Less flexibility: A framework comes with almost everything set up, including the grid width, button styles, and border radius, and follows the standard of its developers. If things don't work the way we want them to, changing it could take a lot of time, and if it is not done properly, it could ruin all other code structure. TOther designers may also have particular issues regarding using a framework; you can further follow the discussion on this matter at http://stackoverflow.com/questions/203069/ what-is-the-best-css-framework-and-are-they-worth-the-effort. The CSS Trick forum has also opened a similar thread on this topic at http://css-tricks.com/forums/discussion/11904/css-frameworks-the-pros-and-cons/p1. Summary In this article we discussed some basic things about Responsive Web Design framework. Resources for Article : Further resources on this subject: Creating mobile friendly themes [Article] Tips and Tricks for Getting Started with OpenGL and GLSL 4.0 [Article] Debugging REST Web Services [Article]
Read more
  • 0
  • 0
  • 11699

Packt
29 Oct 2013
10 min read
Save for later

RESS – The idea and the Controversies

Packt
29 Oct 2013
10 min read
(For more resources related to this topic, see here.) The RWD concept appeared first in 2010 in an article by Ethan Marcotte (available at http://alistapart.com/article/responsive-web-design). He presented an approach that allows us to progressively enhance page design within different viewing contexts with the help of fluid grids, flexible images, and media queries. This approach was opposed to the one that separates websites geared toward specific devices. Instead of two or more websites (desktop and mobile), we could have one that adapts to all devices. The technical foundation of RWD (as proposed in Marcotte's article) consists of three things, fluid grids, flexible images, and media queries. Illustration: Fluid (and responsive) grid adapts to device using both column width and column count Fluid grid is basically nothing more than a concept of dividing the monitor width into modular columns, often accompanied by some kind of a CSS framework (some of the best-known examples were the 960 grid system, blueprint, pure, 1140px grid, and elastic), that is, a base stylesheet that simplifies and standardizes writing website-specific CSS. What makes it fluid is the use of relative measurements like %, em, or rem. With changing the screen (or the window), the number of these columns changes (thanks to CSS statements enclosed in media queries). This allows us to adjust the design layout to device capabilities (screen width and pixel density in particular). Images in such a layout become fluid by using a simple technique of setting width, x% or max-width, 100% in CSS, which causes the image to scale proportionally. With those two methods and a little help from media queries, one can radically change the page layout and handle this enormous, up to 800 percent, difference between the thinnest and the widest screen (WQXGA's 2560px/iPhone's 320px). This is a big step forward and a good base to start creating One Web, that is, to use one URL to deliver content to all the devices. Unfortunately, that is not enough to achieve results that would provide an equally great experience and fast loading websites for everybody. The RESS idea Besides screen width, we may need to take into account other things such as bandwidth and pay-per-bandwidth plans, processor speed, available memory, level of HTML/CSS compatibility, monitoring color depth, and possible navigation methods (touch screen, buttons, and keyboard). On a practical level, it means we may have to optimize images and navigation patterns, and reduce page complexity for some devices. To make this possible, some Server Side solutions need to be engaged. We may use Server Side just for optimizing images. Server Side optimization lets us send pages with just some elements adjusted or a completely changed page; we can rethink the application structure to build a RESTful web interface and turn our Server Side application into a web service. The more we need to place responsibility for device optimization on the Server Side, the closer we get to the old way of disparate desktops and mobile web's separate mobile domains, such as iPhone, Android, or Windows applications. There are many ways to build responsive websites but there is no golden rule to tell you which way is the best. It depends on the target audience, technical contexts, money, and time. Ultimately, the way to be chosen depends on the business decisions of the website owner. When we decide to employ Server Side logic to optimize components of a web page designed in a responsive way, we are going the RESS (Responsive Web Design with Server Side components) way. RESS was proposed by Luke Wroblewski on his blog as a result of his experiences on extending RWD with Server Side components. Essentially, the idea was based on storing IDs of resources (such as images) and serving different versions of the same resource, optimized for some defined classes of devices. Device detection and assigning them to respective classes can be based on libraries such as WURFL or YABFDL. Controversies It is worth noting that both of these approaches raised many controversies. Introducing RWD has broken some long-established rules or habits such as standard screen width (the famous 960px maximum page width limit). It has put in question the long-practiced ways of dealing with mobile web (such as separate desktop and mobile websites). It is no surprise that it raises both delight and rage. One can easily find people calling this fool's gold, useless, too difficult, a fad, amazing, future proof, and so on. Each of those opinions has a reason behind it, for better or worse. A glimpse of the following opinions may help us understand some of the key benefits and issues related to RWD. "Separate mobile websites are a good thing" You may have heard this line in an article by Jason Grigsby, Css media query for mobile is fool's gold , available at http://blog.cloudfour.com/css-media-query-for-mobile-is-fools-gold/. Separate mobile websites allow reduction of bandwidth, prepare pages that are less CPU and memory intensive, and at the same time allow us to use some mobile-only features such as geolocation. Also, not all mobile browsers are wise enough to understand media queries. That is generally true and media queries are not enough in most scenarios, but with some JavaScript (Peter-Paul Koch blog available at, http://www.quirksmode.org/blog/archives/2010/08/combining_media.html#more, describes a method to exclude some page elements or change the page structure via JS paired with media queries), it is possible to overcome many of those problems. At the same time, making a separate mobile website introduces its own problems and requires significant additional investment that can easily get to tens or hundreds of times more than the RWD solution (detecting devices, changing application logic, writing separate templates, integrating, and testing the whole thing). Also, at the end of the day, your visitors may prefer the mobile version, but this doesn't have to be the case. Users are often accessing the same content via various devices and providing consistent experience across all of them becomes more and more important. The preceding controversy is just a part of a wider discussion on channels to provide content on the Internet. RWD and RESS are relatively new kids on the block. For years, technologies to provide content for mobile devices were being built and used, from device-detection libraries to platform-specific applications (such as iStore, Google Play, and MS). When, in 2010, US smartphone users started to spend more time using their mobile apps than browsers (Mobile App Usage Further Dominates Web, Spurred by Facebook, at http://blog.flurry.com/bid/80241/Mobile-App-Usage-Further-Dominates-Web-Spurred-by-Facebook), some hailed it as dangerous for the Web (Apps: The Web Is The Platform, available at http://blog.mozilla.org/webdev/2012/09/14/apps-the-web-is-the-platform/). A closer look at stats reveals though, that most of this time was spent on playing games. No matter how much time kids can spend playing Angry Birds now, after more than two years from then, people still prefer to read the news via a browser rather than via native mobile applications. The Future of Mobile News report from October 2012 reveals that for accessing news, 61 percent mobile users prefer a browser while 28 percent would rather use apps (Future of Mobile News, http://www.journalism.org/analysis_report/future_mobile_news). The British government is not keen on apps either, as they say, "Our position is that native apps are rarely justified" (UK Digital Cabinet Office blog, at http://digital.cabinetoffice.gov.uk/2013/03/12/were-not-appy-not-appy-at-all/). Recently, Tim Berners-Lee, the inventor of the Web, criticized closed world apps such as those released by Apple for threatening openness and universality that the architects of the Internet saw as central to its design. He explains it the following way, "When you make a link, you can link to anything. That means people must be able to put anything on the Web, no matter what computer they have, what software they use, or which human language they speak and regardless of whether they have a wired or a wireless Internet connection." This kind of thinking goes in line with the RWD/RESS philosophy to have one URL for the same content, no matter what way you'd like to access it. Nonetheless, it is just one of the reasons why RWD became so popular during the last year. "RWD is too difficult" CSS coupled with JS can get really complex (some would say messy) and requires a lot of testing on all target browsers/platforms. That is or was true. Building RWD websites requires good CSS knowledge and some battlefield experience in this field. But hey, learning is the most important skill in this industry. It actually gets easier and easier with new tools released nearly every week. "RWD means degrading design" Fluid layouts break the composition of the page; Mobile First and Progressive Enhancement mean, in fact, reducing design to a few simplistic and naive patterns. Actually the Mobile First concept contains two concepts. One is design direction and the second is the structure of CSS stylesheets, in particular the order of media queries. With regard to design direction, the Mobile First concept is meant to describe the sequence of designs. First the design for a mobile should be created and then for a desktop. While there are several good reasons for using this approach, one should never forget the basic truth that at the end of the day only the quality of designs matters, not the order they were created in. With regard to the stylesheet structure, Mobile First means that we first write statements for small screens and then add statements for wider screens, such as @media screen and (min-width: 480px). It is a design principle meant to simplify the whole thing. It is assumed here that CSS for small screens is the simplest version, which will be progressively enhanced for larger screens. The idea is smart and helps to maintain a well-structured CSS but sometimes the opposite, the Desktop First approach, seems natural. Typical examples are tables with many columns. The Mobile First principle is not a religious dogma and should not be treated as such. As a side note, it remains an open question why this is still named Mobile First, while the new iPad-related statements should come here at the end (min-width: 2000px). There are some examples of rather poor designs made by RWD celebrities. But there are also examples of great designs that happened, thanks to the freedom that RWD gave to the web design world. The rapid increase in Internet access via mobile devices during 2012 made RWD one of the hottest topics in web design. The numbers vary across countries and websites but no matter what numbers you look at, one thing is certain, mobile is already big and will soon get even bigger (valuable stats on mobile use are available at http://www.thinkwithgoogle.com/mobileplanet/en/). Statistics are not the only reason why Responsive Web Design became popular. Equally important are the benefits for web designers, users, website owners, and developers. Summary This article, as discussed, covered the RESS idea, as well as the controversies associated with it. Resources for Article: Further resources on this subject: Introduction to RWD frameworks [Article] Getting started with Modernizr using PHP IDE [Article] Understanding Express Routes [Article]
Read more
  • 0
  • 0
  • 11690
Modal Close icon
Modal Close icon