24

I am looking for a way to select and display a list of countries, preferably with flags. Any suggestions?

I started of by trying this jQuery plugin http://www.graphicpush.com/website-language-dropdown-with-jquery, but as the list of countries I have is quite large it turned out that the performance was really bad (too many http requests to images). Also the list is bulky when it is larger than 50 elements.

7
  • 5
    did you google it? or try anything first? we are not going to do all the work for u :-p
    – Naftali
    Mar 23, 2011 at 18:18
  • 1
    See Writing the Perfect Question
    – gideon
    Mar 23, 2011 at 18:26
  • Maybe try downloading all the flags and use a batch image converter to reduce their size ?
    – Pepe
    Mar 23, 2011 at 18:44
  • Try populating a select element with the country names, and then displaying a small flag icon when the onchange event is triggered. You can also use a flag "sprite" (think many images in one) and manipulate the background-position instead.
    – user1385191
    Mar 23, 2011 at 18:45
  • I've looked into the sprite solution, but it would be a tedious job converting the ~80 images into a sprite..
    – Mr.B
    Mar 23, 2011 at 18:51

5 Answers 5

37

Just wanted to suggest a (imho) smarter way of doing the flags sprite.

The idea is to save the flags in a grid according to the country iso2 code.

1st letter -> vertical position
2nd letter -> horizontal position

Examples (for 16x11px flags + 4x4px spacing):

Austria = AT
A = 1   => vertically 1st row       => y = (1-1)*(11+4)  = 0
T = 20  => horizontally 20th column => x = (20-1)*(16+4) = 380

United States = US
U = 21  => vertically 21st row      => y = (21-1)*(11+4) = 300
S = 19  => horizontally 19th column => x = (19-1)*(16+4) = 360

This way I can calculate the flag location with a very easy function on the client side without the need of 200+ extra style definitions.

Sample jQuery plugin:

(function($) {
    // size = flag size + spacing
    var default_size = {
        w: 20,
        h: 15
    };

    function calcPos(letter, size) {
        return -(letter.toLowerCase().charCodeAt(0) - 97) * size;
    }

    $.fn.setFlagPosition = function(iso, size) {
        size || (size = default_size);

        return $(this).css('background-position',
            [calcPos(iso[1], size.w), 'px ', calcPos(iso[0], size.h), 'px'].join(''));
    };
})(jQuery);

Demo Usage:

$('.country i').setFlagPosition('es');

http://jsfiddle.net/roberkules/TxAhb/

And here my flag sprite:

enter image description here

3
  • 5
    Elegant! Very elegant!! I wish I had this solution about a year ago :)
    – Mr.B
    Jun 20, 2012 at 15:56
  • 4
    +1 for a very elegant solution.
    – Doodloo
    Aug 7, 2014 at 12:39
  • 1
    This is a very neat solution Jan 14, 2016 at 17:11
31

Note from the future: jQuery UI autocomplete now supports custom rendering by default, see http://api.jqueryui.com/autocomplete/#method-_renderItem.

It's pretty easy. Things you need:

  1. jQuery UI auto-complete
  2. UI auto-complete html extension
  3. A list of country names/codes
  4. A CSS sprite with all flags

Remember, Google is your friend. Blend the ingredients well, carefully whisk some javascript in, and it's done - in 7 lines of code:

var countries = [["Argentina", "ar"], ...];

var countryNames = countries.map(function(country){
  return {
      label: '<div class="flag '+country[1].toLowerCase()+'">'+country[0]+'</div>',
      value: country[0]
  }
});

$('#country').autocomplete({
  source: countryNames,
  html: true
});

Here's this code in action

7
  • Great! I didnt search for sprite with flags. Now I have all I need. Thanks a lot Ricardo!
    – Mr.B
    Mar 24, 2011 at 8:37
  • I like this answer a lot, upvoted it but the jsbin is failing for me Aug 19, 2011 at 7:51
  • fixed it for you :) it will probably break again in the future since it links directly to 3rd party sources. Aug 21, 2011 at 7:30
  • @RicardoTomasi, the jsbin code does not show the flag accurately. For example the flag of Bangladesh is shown beside Belgium. Sep 15, 2012 at 11:18
  • @IstiaqueAhmed this question is over 1.5 years old. As I said above, it's going to break because it's all built on top of third-party resources. This time it seems the sprite image has been changed (github.com/lafeber/world-flags-sprite/tree/master/images). Sep 16, 2012 at 23:58
1

As mentioned by commenters, a CSS sprite is the proper solution here. Fortunately, there are many CSS sprites of flags freely available. This one looks pretty good.

We will have to tweak the dropdown code to accomodate that pre-made CSS sprite. I've gone ahead and done that for you. Here's a live demo.

languageswitcher.js

@@ -44,10 +44,11 @@
        source.removeAttr("autocomplete");
        var selected = source.find("option:selected");
        var options = $("option", source);
-       $("#country-select").append('<dl id="target" class="dropdown"></dl>')
-       $("#target").append('<dt class="' + selected.val() + '"><a href="#"><span class="flag"></span><em>' + selected.text() + '</em></a></dt>')
-       $("#target").append('<dd><ul></ul></dd>')
+        $("#country-select").append('<dl id="target" class="dropdown f16"></dl>')
+        $("#target").append('<dt><a href="#"><em class="flag ' + selected.val().toLowerCase() + '">' + selected.text() + '</em></a></dt>');
+        $("#target").append('<dd><ul></ul></dd>');
+        var $drop = $("#target dd ul");
        options.each(function(){
-           $("#target dd ul").append('<li class="' + $(this).val() + '"><a href="' + $(this).attr("title") + '"><span class="flag"></span><em>' + $(this).text() + '</em></a></li>');
+            $drop.append('<li><a href="' + $(this).attr("title") + '"><em class="flag ' + $(this).val().toLowerCase() + '">' + $(this).text() + '</em></a></li>');
            });
    }

languageswitcher.css

@@ -45,6 +45,8 @@

 .dropdown dd { position: relative; }

+.dropdown ul { max-height:350px; overflow-y:auto; overflow-x:hidden; }
+
 .dropdown a {
    text-decoration: none;
    outline: 0;
@@ -52,6 +54,7 @@
    display: block;
    width: 130px;
    overflow: hidden;
+    white-space:nowrap;
    }

 .dropdown dt a {
@@ -107,23 +110,6 @@
        padding: 2px 10px;
        }

-   .dropdown dd ul li a span,
-   .dropdown dt a span {
-       float: left;
-       width: 16px;
-       height: 11px;
-       margin: 2px 6px 0 0;
-       background-image: url(flags.png);
-       background-repeat: no-repeat;
-       cursor: pointer;
-       }
-
-       .us a span { background-position: 0 0 }
-       .uk a span { background-position: -16px 0 }
-       .fr a span { background-position: -32px 0 }
-       .de a span { background-position: -48px 0 }
-       .nl a span { background-position: -64px 0 }
-
    .dropdown dd ul li a em,
    .dropdown dt a em {
        font-style: normal;
@@ -138,3 +124,5 @@

        .dropdown dd ul li a:hover { background-color: rgba(255,255,255,.1); }
        .dropdown dd ul li a:hover em { color: #fff; }
+
+.flag { padding-left:18px; }

The CSS changes I made were Q&D hacks; you'll probably want to spend some time polishing them. I removed all of the flag-specific stuff from languageswitcher.css since we're using flag16.css.

Also, if the country code doesn't exist in the CSS sprite, the flag shown will default to the African Union's flag since it is the first image in the sprite. In the demo, several of the countries in my example list don't have a sprite image. Watch out for that.

2
  • Thanks for the elaborate solution! I was a bit intimidated at first by looking at the code here, but when I saw the live demo I saw that it wasn't as complicated as a thought. I went with the autocomplete solution this time. But I will keep this solution in mind for the future. Thanks again Josh!
    – Mr.B
    Mar 24, 2011 at 17:15
  • @Mr.B: The code as presented above is just a udiff, which makes it easy to see exactly what changes I made to the original code from your link.
    – josh3736
    Mar 24, 2011 at 18:10
0

Here's a file with the list of countries and links to their flags (some of the links might not be working though but most of them are) Excel File

0

You can also use flags from http://www.famfamfam.com/lab/icons/flags/ and simply use CSS for positioning the appropriate flag.

----EDITED----

If i need to show flag of my country then i would do mapping from CSS like

<span class='np'></span>

.np {
background: url(./flags_preview_large.png) -172px -397px no-repeat;
width: 14px;
height: 20px;
}

2
  • It would be useful to add an example.
    – Manolo
    Nov 10, 2013 at 10:33
  • Ok i had added a clear example with html tag (span tag) that show map of Nepal with the help of CSS mapping which is all defined above.
    – Anil Prz
    Nov 17, 2013 at 9:07

Not the answer you're looking for? Browse other questions tagged or ask your own question.