diff --git a/includes/common.inc b/includes/common.inc
index 74e437e8f8c5b16837acd132ff34909121ee9c28..3f26c4949ff246f1ac827891d1293078d9f0aa04 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -3094,10 +3094,10 @@ function drupal_clear_css_cache() {
 }
 
 /**
- * Prepare a string for use as a valid identifier (element, class or ID name).
+ * Prepare a string for use as a valid CSS identifier (element, class or ID name).
  *
  * http://www.w3.org/TR/CSS21/syndata.html#characters shows the syntax for valid
- * identifiers (including element names, classes, and IDs in selectors.)
+ * CSS identifiers (including element names, classes, and IDs in selectors.)
  *
  * @param $identifier
  *   The identifier to clean.
@@ -3106,11 +3106,11 @@ function drupal_clear_css_cache() {
  * @return
  *   The cleaned identifier.
  */
-function drupal_clean_html_identifier($identifier, $filter = array(' ' => '-', '_' => '-', '[' => '-', ']' => '')) {
+function drupal_clean_css_identifier($identifier, $filter = array(' ' => '-', '_' => '-', '[' => '-', ']' => '')) {
   // By default, we filter using Drupal's coding standards.
   $identifier = strtr($identifier, $filter);
 
-  // Valid characters in a identifier are:
+  // Valid characters in a CSS identifier are:
   // - the hyphen (U+002D)
   // - a-z (U+0030 - U+0039)
   // - A-Z (U+0041 - U+005A)
@@ -3135,7 +3135,7 @@ function drupal_clean_html_identifier($identifier, $filter = array(' ' => '-', '
  *   The cleaned class name.
  */
 function drupal_html_class($class) {
-  return drupal_clean_html_identifier(drupal_strtolower($class));
+  return drupal_clean_css_identifier(drupal_strtolower($class));
 }
 
 /**
@@ -3148,7 +3148,15 @@ function drupal_html_class($class) {
  */
 function drupal_html_id($id) {
   $seen_ids = &drupal_static(__FUNCTION__, array());
-  $id = drupal_clean_html_identifier(drupal_strtolower($id));
+  $id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
+
+  // As defined in http://www.w3.org/TR/html4/types.html#type-name, HTML IDs can
+  // only contain letters, digits ([0-9]), hyphens ("-"), underscores ("_"),
+  // colons (":"), and periods ("."). We strip out any character not in that
+  // list. Note that the CSS spec doesn't allow colons or periods in identifiers
+  // (http://www.w3.org/TR/CSS21/syndata.html#characters), so we strip those two
+  // characters as well.
+  $id = preg_replace('/[^A-Za-z0-9\-_]/', '', $id);
 
   // Ensure IDs are unique. The first occurrence is held but left alone.
   // Subsequent occurrences get a number appended to them. This incrementing
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index 35c8bf52fb9427ea2f4244efee8d8869c792cb95..fe37b416ac4fb63d6f4cdc6f7d38153bd26984e0 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -573,47 +573,54 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
 }
 
 /**
- * Test for drupal_add_css().
+ * Test for cleaning HTML identifiers.
  */
-class DrupalCSSIdentifierTestCase extends DrupalUnitTestCase {
+class DrupalHTMLIdentifierTestCase extends DrupalUnitTestCase {
   public static function getInfo() {
     return array(
-      'name' => 'CSS identifiers',
-      'description' => 'Test the functions drupal_html_class() and drupal_html_id() for expected behavior',
+      'name' => 'HTML identifiers',
+      'description' => 'Test the functions drupal_html_class(), drupal_html_id() and drupal_clean_css_identifier() for expected behavior',
       'group' => 'System',
     );
   }
 
   /**
-   * Tests that drupal_html_class() cleans the class name properly.
+   * Tests that drupal_clean_css_identifier() cleans the identifier properly.
    */
   function testDrupalCleanCSSIdentifier() {
-    // Verify that no valid ASCII characters are stripped from the class name.
-    $class = 'abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789';
-    $this->assertIdentical(drupal_clean_html_identifier($class, array()), $class, t('Verify valid ASCII characters pass through.'));
+    // Verify that no valid ASCII characters are stripped from the identifier.
+    $identifier = 'abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789';
+    $this->assertIdentical(drupal_clean_css_identifier($identifier, array()), $identifier, t('Verify valid ASCII characters pass through.'));
 
-    // Verify that no valid UTF-8 characters are stripped from the class name.
-    $class = '¡¢£¤¥';
-    $this->assertIdentical(drupal_clean_html_identifier($class, array()), $class, t('Verify valid UTF-8 characters pass through.'));
+    // Verify that valid UTF-8 characters are not stripped from the identifier.
+    $identifier = '¡¢£¤¥';
+    $this->assertIdentical(drupal_clean_css_identifier($identifier, array()), $identifier, t('Verify valid UTF-8 characters pass through.'));
 
-    // Verify that invalid characters (including non-breaking space) are stripped from the class name.
-    $this->assertIdentical(drupal_clean_html_identifier('invalid !"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ class', array()), 'invalidclass', t('Strip invalid characters.'));
+    // Verify that invalid characters (including non-breaking space) are stripped from the identifier.
+    $this->assertIdentical(drupal_clean_css_identifier('invalid !"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ identifier', array()), 'invalididentifier', t('Strip invalid characters.'));
   }
 
   /**
    * Tests that drupal_html_class() cleans the class name properly.
    */
-  function testDrupalCSSClass() {
+  function testDrupalHTMLClass() {
     // Verify Drupal coding standards are enforced.
     $this->assertIdentical(drupal_html_class('CLASS NAME_[Ü]'), 'class-name--ü', t('Enforce Drupal coding standards.'));
   }
 
   /**
-   * Tests that drupal_html_id() cleans the id name properly.
+   * Tests that drupal_html_id() cleans the ID properly.
    */
-  function testDrupalCSSId() {
+  function testDrupalHTMLId() {
+    // Verify that letters, digits, and hyphens are not stripped from the ID.
+    $id = 'abcdefghijklmnopqrstuvwxyz-0123456789';
+    $this->assertIdentical(drupal_html_id($id), $id, t('Verify valid characters pass through.'));
+
+    // Verify that invalid characters are stripped from the ID.
+    $this->assertIdentical(drupal_html_id('invalid,./:@\\^`{Ãœidentifier'), 'invalididentifier', t('Strip invalid characters.'));
+
     // Verify Drupal coding standards are enforced.
-    $this->assertIdentical(drupal_html_id('ID NAME_[Ü]'), 'id-name--ü', t('Enforce Drupal coding standards.'));
+    $this->assertIdentical(drupal_html_id('ID NAME_[1]'), 'id-name--1', t('Enforce Drupal coding standards.'));
 
     // Reset the static cache so we can ensure the unique id count is at zero.
     drupal_static_reset('drupal_html_id');