Agility, Java programming, New technologies and more…
  • rss
  • Home
  • Management
  • Agile Programming
  • Technology
  • Linux
  • Event
  • Android app
  • Contact
  • About the author
  • English
  • Francais

Doing Responsive Web Design: yes, but easily!

Fabian Piau | Tuesday July 23rd, 2013 - 07:00 PM
  • Print
  • Twitter
  • LinkedIn
  • Facebook
  • Pocket

 Version française disponible

Not so long ago, I was talking about the “Mobile theme” feature included in the Jetpack plugin to ensure that your WordPress blog is accessible on mobile devices by making its content legible.

I will not change my mind about this great plugin because it works very well and each new version of Jetpack brings lots of improvements. Also, the fact that there is nothing to configure, just a button to activate the theme is a big advantage, you can hardly do better. Yes, but… if you are not scared of doing some programming, there is something even better!

I’m talking about Responsive Web Design, a very trendy concept that is not going to fade away. With Responsive Web Design, the site is unified on all platforms and automatically adapts to the screen size. The identity of your site remains the same (theme, images, colors…) and it saves you from maintaining different versions: desktop, mobile, tablet… The management of your site is simplified and its maintenance becomes much easier.

Responsive Web Design

Before, there were few screen resolutions available (usually people were using a 1024 x 768 resolution or, for the lucky ones, a 1280 x 1024 resolution), it was the time of the 17 and 19 inch CRT monitors (ouch, my eyes are hurting… ok I am talking about ancient history). Today, there are hundreds of different sizes and resolutions on the market, Internet is everywhere on your TV, in your car or even in your fridge (well I guess I see a little bit too far, but this all-connected world is maybe not so far). In short, it is no longer possible to work on fixed resolutions on a case by case basis.

Of course, in the case of a specific application, there are arguments against the Responsive Design. A web application will have slower performance compared to a native app. But it is not the point here. I want to focus on general websites with a broad target audience (a newspaper, an online shop…). These websites need to be available on mobile devices and they should avoid using dedicated mobile versions (I am talking about the famous URL beginning with “m”). For instance m.facebook.com, m.linkedin.com or m.lequipe.fr which will disappear sooner or later.


Test by yourself

Right now, you can change the size of your browser window, you will see that this blog will automatically adapt (if you see bugs or have any idea for improvement, let me know!)

CarmaBlog in 1024 x 768

CarmaBlog in 1024 x 768

CarmaBlog in 400 x 768

CarmaBlog in 400 x 768


You have probably noticed it, there are different changes as the width of the window decreases:

  • The main menu becomes smaller before being replaced by a drop-down list.
  • Some blocks are moving on a new line (RSS icon and search box).
  • The secondary content disappears in favor of the principal. On a small screen, we want to get to the point (articles in my case) and avoid too much scrolling.
  • The shadow effect and the background disappear. On small screens, dozens of pixels can represent 10% of the whole size, you have to take care of that.
  • Images are resizing dynamically to avoid excessive disproportions.


Plenty of Responsive frameworks…

Many frameworks exist to help you achieve a responsive site. The best known is probably Bootstrap, by the way that’s the only one I already used on a project. There are plenty of others:

  • Foundation
  • Gumby
  • Unsemantic
  • Skeleton
  • Pure
  • KnaCSS


Home-made Responsive

It is also possible to make Responsive Web Design by yourself, without any framework. Actually, my blog is a good example. Some code of CSS, some code of Javascript and a few hours of work, that’s what you need. The final result may be not compatible with IE6, it certainly does not show great and smooth animations, but it will be more than enough in most cases.

The secret is to use media queries available from CSS3, below are some code samples:

@media all and (max-width:1000px) {
	.sidebar div {
		display:none;
	}
}

If screen width is less than 1000 pixels, the right and left sidebars are hidden.


@media all and (min-width:870px) and (max-width:975px) {
	#menu ul li {
		font-size:.7em;
	}
	#header_image {
		height:150px;
	}
}

If screen width is between 870 pixels and 975 pixels, the header and the menu are smaller.


@media all and (max-width:870px) {
	#menu {
		display:none;
	}
	#menuselect select {
		display:block;
	}
	#header_image {
		height:80px;
	}
}

If screen width is less than 870 pixels, the menu is replaced by a drop-down list. The header image is shrunk a second time.


@media all and (max-width:585px) {
	img:not(.fixed):not(.avatar):not(.wp-smiley):not(#sb-player) {
		height:auto !important;
		max-width:80%;
		min-width:70px;
	}
}

If screen width is less than 585 pixels, images are minimized. Images with CSS classes “wp-smiley”, “fixed”, “avatar” or with the ID “sb-player” are not affected. I had to do that because I had the problem of having some icons like smileys getting magnified, also some strange behavior with the embedded slideshow of Shadowbox.js player… I also add a restriction on the height (because I think you need a good view to see the content of an image smaller than 70 pixels).

Note: I use the “!important” keyword to redefine a style already present. The value specified with the “!important” will always overwrite the others.


I also wrote some Javascript to create the drop-down list that replaces the menu. I do not show the code here (it is very specific to my site), but be aware that the function have no more than 15 lines. I took advantage of the fact that jQuery was already included in the project, to save me from some additional lines of code.

All put together, to make my site responsive, I wrote more or less 200 lines of CSS code (with the format above so many lines with only one closing brace). It is not as complicated as you might think.

There is one last important thing. In the header of your pages, add this meta tag to indicate that your site is suitable for mobile devices:

<meta name='viewport' content='width=device-width, initial-scale=1.0'>


Inspection

At the end, the longest and tedious part was to refine styles depending on the resolution. There is no secret, this is an iterative and manual process: change the CSS, refresh the page and check results.

To help you, you can use Responsinator, a good tool to test a site with the most common screen resolutions corresponding to famous devices. You can also install Firesizer, a Firefox extension to know the resolution of the browser window, very useful when building your media queries.

Related posts

Maven siteMaven Site, one step further devoxxDevoxx UK 2018 – Day 2 IT jobsComputing jobs simplified overview microservices-legoMicroservices architecture – Best practices
Comments
5 Comments »
Categories
Agile programming
Tags
css, design, mobile computing, responsive, wordpress
Comments rss Comments rss

First steps with Apache Camel

Fabian Piau | Friday May 11th, 2012 - 09:05 AM
  • Print
  • Twitter
  • LinkedIn
  • Facebook
  • Pocket

 Version française disponible

Note
To learn more about Camel, you can read a free sample of the chapter 1 of “Camel in Action”, the reference book.

Raphaël Delaporte (@rafdelaporte) proposed us to tame a camel this week at Nantes JUG.

Camel photo

Don’t be fooled by the picture ! Our computerized camel is not lazy… Let’s focus back on an attractive presentation of Apache Camel.

Apache Camel logo

Apache Camel relies on the Enterprise Integration Patterns – EIP (not to be confused with the concept of Design Patterns used for objects designing).


EIP Patterns

Here are the main patterns from simple to more complex (this is a slide from the presentation).

Entreprise Integration Patterns

Entreprise Integration Patterns

By combining multiple patterns, the possibilities are almost endless. You can find the list of Patterns implemented in Camel on the official website of the framework.

A comprehensive book on the subject exists “Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions”. The author is none other than the creator of this concept, needless to say that this is the reference book.


Make EIP with Apache Camel

There are three basic elements in Camel to implement the EIP :

  • Route
  • Processor
  • Endpoint

A route is conceptualized as follows : the binding of two endpoints by a processor. Thus, we have a start endpoint and a end endpoint, an endpoint is associated with a resource. A route symbolizes a more or less complex treatment (processor) depending on what you want to achieve and the EIP you have chosen to implement.

To meet your needs, you can use nesting and chained routes, apply different treatments throughout the route, etc.


In Apache Camel, a route can be defined in two ways :

  • Either by using the Java language (Domain Specific Language – DSL). Apache Camel provides an API. This is a very handy way, specially inside an IDE with autocomplete feature.
  • Or using XML. More verbose so a little less readable and finally a bit less convenient. I recommend you to use DSL when routes become complex.

In the following, we will favor the Java syntax. Note that in all cases, some XML will be required for the configuration of Camel (Camel context, datasources, etc.).

Here is a simple example of route :

import org.apache.camel.builder.RouteBuilder;

public class MyFirstRoute extends RouteBuilder {
    @Override
    public void configure() thwrows Exception {
        // My first route
        from('file:/Users/fabian/src').to('file:/Users/fabian/dest').end();

        // We can define more routes here
        // ...
    }
}

The .end() keyword is not mandatory, but highly advisable to clearly delineate routes (maintainability). In this example, the treatment is very simple, there is only one route, so it is not really necessary.



The presentation was mainly demos-based. Raphaël showed us some textbook cases starting from a correctly configured Maven project (Spring dependencies, Camel, contexts…) :

  • Move files from one directory to another (this is the code snippet above). All files created in the src folder will be moved in the dest folder. This route can be written in one single line… And shows us the power of such a tool.
  • Create files corresponding to pooled messages in a JMS queue. For the presentation, Raphaël has used Apache ActiveMQ, a JMS message broker. This case illustrates the Splitter pattern.
  • Pool messages in a JMS queue according to their content. This case illustrates the Content-based Router pattern.
  • The route is as follows, assuming queue.in exists in ActiveMQ and that they are pooled messages :

    import org.apache.camel.builder.RouteBuilder;
    
    public class MyContentBasedRoute extends RouteBuilder {
        @Override
        public void configure() thwrows Exception {
            from('amq:queue.in')
                .choice()
                    .when(header('JMSCorrelationID').isEqualTo('nantes'))
                        .to('amq:queue.nantes')
                    .when(header('JMSCorrelationID').isEqualTo('rennes'))
                        .to('amq:queue.rennes')
                    .otherwise()
                        .to('amq:queue.others')
            .end();
        }
    }
    

    From the ActiveMQ admin console, we create a few messages to test the different scenarios. Message is routed to the right queue according to its header.

    It is possible to chain predicates with the usual logical operators in order to create more complex routing criteria. In our example, the predicate is simple and is only based on the message’s header. It could also be based on the body to make a finer routing messages.

  • Create JMS messages from the content of an XML file. This case illustrates the Dynamic Router pattern.
  • Content of messages_jug.xml :

    <jug>
        <nantes>Hello from Nantes</nantes>
        <paris>Hello from Paris</paris>
        <rennes>Hello from Rennes</nantes>
        <nantes>Hello again from Nantes</nantes>
        <paris>Hello again from Paris</paris>
        [...]
    </jug>
    

    With Camel, we want to extract the various messages and send them into a queue.

    Here is the code of the corresponding route :

    import org.apache.camel.builder.RouteBuilder;
    
    public class MyDynamicRoute extends RouteBuilder {
        @Override
        public void configure() thwrows Exception {
            from('files:/Users/fabian/src/messages_jug.xml')
                .split(xpath('/jug/child::*'))
            .to('amq:queue.jugs');
        }
    }
    

    It could have been a different treatment. For example : filtering on messages from Nantes and routed them to another file. The possibilities are endless.


    Camel Optimizations

    What about unavailability ? What’s going on with the message processing if the machine crashes and does not have the time to route the message ? Unfortunately, you lose the message ! It was consumed in the source queue, but has never reach its destination. Solution is to pass the route in transactional mode. This is done by adding .transacted() just after .from(...) and making sure that your JMS datasource is in transactional mode too (see XML configuration).

    We also note that the treatment is single-threaded by default. An improvement is to enable the processor’s parallelization (in our case, a split processor) by adding this custom option .parallelProcessing() just after .split(...).

    We talked about file and jms, but there is so much more components available in Camel thanks to a very active community. This page lists all the components available. Including jdbc, ftp, gmail, atom, pop, imap among others.


    Make EIP with Spring Integration

    Raphaël told us about Spring Integration, an alternative to Camel. When using Spring Integration, you have no choice and you must use the XML notation exclusively.

    According to Raphaël, SI fits better with Spring Batch, but the goal was not to blame one tool or the other. And each one has pros and cons.

    Here is the example of transferring files from one directory to another, but written with Spring Integration :

    <channel id='myFirstChannel' />
    
    <file:inbound-channel-adapter id='filesIn'
            channel='myFirstChannel'
            directory='file:/Users/fabian/src' />
           
    <file:outbound-channel-adapter id='filesOut'
            channel='myFirstChannel'
            directory='files:/Users/fabian/dest' />
    

    The concept of route is not present, SI defines a channel which connects two components. This is clearly the Spring philosophy, which places the notion of component at the center. Components are injected and can be linked together (this is logical because SI is developped by SpringSource).

    Actually, the term route is only used by Camel. Spring Integration is closer to the EIP concepts by using same terms, such as channel.

    Another difference, the channel appears concretely in Spring Integration but the route is implicit in Camel (no route() keyword). If we come back to our first route :

    from('file:/Users/fabian/src').to('file:/Users/fabian/dest');
    

    The route is symbolized by the “.” between the two endpoints. It is not possible to configure it. At this level, Spring Integration is more advanced with the ability to configure a particular type of channel.

Related posts

springQCon London 2016 – Spring Framework 5 – Preview & Roadmap Maven siteMaven Site, one step further Java 11A Java 11 migration successful story Java EE vs SpringJava EE & CDI vs. Spring
Comments
3 Comments »
Categories
Agile programming
Tags
camel, eip, entreprise integration pattern, jug
Comments rss Comments rss
Page 9 of 151…7891011…15
Download CarmaBlog App

RSS feeds

  • RSS feed RSS - Posts
  • RSS feed RSS - Comments

Most viewed posts

  • Changing the language in Firefox - 116,369 views
  • Using Google Forms / Drive / Docs to create an online survey - 64,395 views
  • FAQ – Online survey with Google Forms / Drive / Docs - 56,229 views
  • Customizing Gnome 3 (Shell) - 30,805 views
  • The meaning of URL, URI, URN - 18,403 views
  • Java EE & CDI vs. Spring - 15,984 views
  • Open Street Map, better map than Google Maps? - 15,796 views
  • Comparing NoSQL: Couchbase & MongoDB - 14,690 views
  • API, REST, JSON, XML, HTTP, URI… What language do you speak? - 13,728 views
  • First steps with Apache Camel - 13,590 views

Recent Comments

  • Fabian Piau on FAQ – Online survey with Google Forms / Drive / DocsOui, dans Google Forms, vous pouvez empêcher les p…
  • BENECH Fabien on FAQ – Online survey with Google Forms / Drive / DocsBonjour, J'ai crée 1 questionnaire via Forms,…
  • SANKARA TIDIANE on Free online MongoDB trainingJ'aimerai suivre
  • Pauline on FAQ – Online survey with Google Forms / Drive / DocsMerci Fabian, mais le but étant que nos clients pu…
  • Fabian Piau on FAQ – Online survey with Google Forms / Drive / DocsProbablement mais ces options sont en général paya…

Recent posts

  • How to write a blog post? At least my way! - 2 years and 5 months ago
  • Bot Attacks: You are not alone… - 4 years and 3 weeks ago
  • Flagger – Monitor your Canary deployments with Grafana - 4 years and 10 months ago
  • Flagger – Canary deployments on Kubernetes - 4 years and 11 months ago
  • Flagger – Get Started with Istio and Kubernetes - 5 years and 2 weeks ago
  • Expedia CoderDojo in London - 5 years and 9 months ago
  • Volunteering at Devoxx4Kids - 6 years and 1 week ago
  • A Java 11 migration successful story - 6 years and 4 months ago
  • Tips to make your WordPress website secure - 6 years and 7 months ago
  • Devoxx UK 2018 – Day 2 - 6 years and 11 months ago
  • Devoxx UK 2018 – Day 1 - 6 years and 11 months ago
  • Wise, Revolut and Monzo, a small revolution for travelers and expats - 7 years and 3 months ago
  • Autocomplete for Git - 7 years and 11 months ago
  • Swagger, the automated API documentation - 8 years and 2 months ago
  • Microservices architecture – Best practices - 8 years and 7 months ago
Buy me a coffee

Language

  • Français
  • English

Follow me!

Follow me on Linkedin
Follow me on Twitter
Follow me on Stackoverflow
Follow me on Github
Follow me on Rss
Link to my Contact

Email subscription

Enter your email address to receive notifications of new posts.

Tags

.net agile agility android bash best practices blog cache cloud computing conference continuous integration css developer devoxx docker eclipse extreme programming firefox flagger google helm hibernate istio java job jug kubernetes london mobile computing overview performance plugin programmer script security sharing society spring tdd test tool ubuntu windows wordpress

Links

  • Blog Ippon Technologies
  • Blog Publicis Sapient
  • Blog Zenika
  • Classpert
  • CommitStrip
  • Coursera
  • Le Touilleur Express
  • Les Cast Codeurs Podcast
  • OCTO talks !
  • The Twelve-Factor App

Categories

  • Event (15)
  • Linux (3)
  • Management (8)
  • Agile programming (29)
  • Technology (45)

Archives

  • December 2022 (1)
  • April 2021 (1)
  • June 2020 (1)
  • May 2020 (2)
  • July 2019 (1)
  • May 2019 (1)
  • December 2018 (1)
  • October 2018 (1)
  • June 2018 (1)
  • May 2018 (1)
  • January 2018 (1)
  • May 2017 (1)
  • March 2017 (1)
  • October 2016 (1)
  • April 2016 (2)
  • March 2016 (1)
  • November 2015 (1)
  • May 2015 (1)
  • February 2015 (1)
  • December 2014 (1)
  • November 2014 (1)
  • September 2014 (2)
  • August 2014 (1)
  • July 2014 (2)
  • June 2014 (1)
  • April 2014 (1)
  • March 2014 (1)
  • February 2014 (2)
  • January 2014 (1)
  • December 2013 (1)
  • November 2013 (1)
  • October 2013 (3)
  • September 2013 (5)
  • July 2013 (1)
  • June 2013 (1)
  • May 2013 (1)
  • April 2013 (1)
  • March 2013 (2)
  • February 2013 (1)
  • January 2013 (2)
  • December 2012 (2)
  • October 2012 (1)
  • September 2012 (1)
  • July 2012 (1)
  • May 2012 (1)
  • April 2012 (1)
  • March 2012 (1)
  • February 2012 (1)
  • January 2012 (2)
  • December 2011 (1)
  • November 2011 (2)
  • October 2011 (2)
  • September 2011 (1)
  • July 2011 (1)
  • June 2011 (2)
  • April 2011 (1)
  • March 2011 (1)
  • February 2011 (1)
  • January 2011 (2)
  • November 2010 (2)
  • September 2010 (1)
  • August 2010 (1)
  • July 2010 (1)
  • June 2010 (1)
  • May 2010 (1)
  • April 2010 (1)
  • March 2010 (1)
  • February 2010 (1)
  • December 2009 (1)
  • November 2009 (1)
  • October 2009 (2)
  • September 2009 (2)
  • August 2009 (3)
  • July 2009 (1)
  • June 2009 (2)
Follow me on Twitter
Follow me on Linkedin
Follow me on Stackoverflow
Follow me on Rss
Link to my Contact
Follow me on Github
 
Fabian Piau | © 2009 - 2025
All Rights Reserved | Top ↑