Submit your widget

CSS3 Mask Passwords Like the iPhone

Created 13 years ago   Views 6443   downloads 1341    Author zurb
CSS3 Mask Passwords Like the iPhone
View DemoDownload
Share |

Passwords are all about security – In some cases passwords are simply about the reassuring appearance of security. A site that has password protection is, to many users, secure – whether the site is really secure or not. When you eliminate masking you might be saving your users a few seconds irritation, but you'll be damaging your own credibility.

Nielsen's research was largely based on mobile devices, but mobile devices have one advantage that desktops do not have – ease of obfuscation. If a phone didn't mask passwords it wouldn't be the end of the world, because users can much more easily conceal their actions on a tiny device than a full size machine.

How to Implement It on Your Site

Here's how we'll help your visitors keep their security while improving password masking—with just some javascript and CSS magic.

  1. Put a standard text input where the password input would be and label it 'password' for the user.
  2. Create a real, hidden password field which the javascript will copy the password into with a type and ID of password.
  3. When the user submits the form, send the username and real password fields, while discarding the fake one they typed into. (Since the field they typed into has been converted to bullet characters we can't submit that field).

The Code

This version of the solution is written as a Prototype behaviour and requires the lowpro behaviours plugin, but the code isn't terribly complex and could be adapted to most any system. Here's the behaviour itself:

// Behavior Class for Awesome Passwords    
var AwesomePassword = Behavior.create({

password_string : null,
password_field_id : null,
password_length : null,

initialize : function (config) {
this.password_string = "";
this.password_length = 0;
this.password_field_id = config['password_field_id'];
this.password_field = $(this.password_field_id);
this.hidden_password_field = $(config['hidden_password']);

onblur : function(e) {
this.password_string = "";
this.password_length = "";

onkeyup : function(e) {
if(e.which == 8) {
this.password_string = this.password_string.substr(0,this.password_field.value.length);

onkeypress : function(e) {
var source = Event.element(e);
if ( == this.password_field_id) this._awesomeify_password(source,e);
_awesomeify_password : function(source,e) {
// Mask Field With Bullets
var bullet_string = "";

// Loop through and add bullets
for( i = 0; i < this.password_field.value.length; i++ ) {
bullet_string += String.fromCharCode(8226);

// Fill bullets
this.password_field.value = bullet_string;

// If valid Password Character Update Password String
if( String.fromCharCode(e.which).match(/[a-zA-Z0-9!-)]/) && String.fromCharCode(e.which).match(/[a-zA-Z0-9!-)]/).first ) {
this.password_string += String.fromCharCode(e.which);

var password_field = this.password_field;
// Wait for user to stop typeing
setTimeout(function() {
setTimeout(function() {
password_field.value = password_field.value.replace(/.$/,String.fromCharCode(8226));
}, 500);
onsubmit : function(e) {
this.hidden_password_field.value = this.password_string;
return true;


With that in place you simply have to attach the behaviour when the page loads:

// Attaches the behavior to the form, password_field_id is the id of the visible form field, hidden_password is the id of the hidden field containing the real password the user types in  , these behaviors get applied onload 
'form.awesome' : AwesomePassword({ password_field_id : 'password', hidden_password : 'realPassword' })


Solved! Sort of.

Does this solve the problem? Well, mostly. It's a nice interaction and it does seem to strike a middle ground between fully masked and Nielsen's total unmasking rallying cry. Security expert Bruce Schneier actually backs this Blackberry/iPhone method, as he refers to it, as an "excellent compromise."

However, it also introduces a few problems: it doesn't work well in older browsers and doesn't play nice with browsers trying to autofill the saved password. The ideal solution is in the hands of the browser manufacturers, and making type=password fields act this way by default as they already do on mobile.

Security online will only become a bigger deal as we and our users invest more and more of our lives in other sites. There will come a day when passwords are seen as hilariously antiquated, and retina scanning or voice identification (or colonic maps, yikes) are the truly secure ways we identify ourselves. Until then we'll keep looking for awesome solutions.