diff --git a/includes/common.inc b/includes/common.inc
index 2de18d1fe3560c6ddfe802eb7fd79fa7df7d8a29..2a84bffd14ec7850a7034bfc09f5eccbb43dcceb 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -3987,6 +3987,8 @@ function element_info($type) {
         $cache[$element_type]['#type'] = $element_type;
       }
     }
+    // Allow modules to alter the element type defaults.
+    drupal_alter('element_info', $cache);
   }
 
   return $cache[$type];
diff --git a/modules/system/system.api.php b/modules/system/system.api.php
index 7aead6c9b9b6b41a47925bab24539f60c9396d94..8986270b2942d808d015e7489b4567c0163cf205 100644
--- a/modules/system/system.api.php
+++ b/modules/system/system.api.php
@@ -115,6 +115,24 @@ function hook_elements() {
   return $type;
 }
 
+/**
+ * Alter the element type information returned from modules.
+ *
+ * A module may implement this hook in order to alter the element type defaults
+ * defined by a module.
+ *
+ * @param &$type
+ *   All element type defaults as collected by hook_elements().
+ *
+ * @see hook_elements()
+ */
+function hook_element_info_alter(&$type) {
+  // Decrease the default size of textfields.
+  if (isset($type['textfield']['#size'])) {
+    $type['textfield']['#size'] = 40;
+  }
+}
+
 /**
  * Perform cleanup tasks.
  *