diff --git a/css/webform.css b/css/webform.css
index 036d199..60cb215 100644
--- a/css/webform.css
+++ b/css/webform.css
@@ -10,6 +10,20 @@ input.webform-calendar {
 html.js input.webform-calendar {
   display: inline;
 }
+fieldset.webform-container {
+  background: transparent;
+  border: none;
+  padding: 0;
+  margin: 0;
+  position: static;
+  height: auto;
+  width: auto;
+  left: auto;
+  top: auto;
+}
+fieldset.webform-container legend.webform-container-legend {
+  display: none;
+}
 .webform-container-inline label {
   display: inline;
   margin-right: 1em;
diff --git a/webform.module b/webform.module
index 35ecb36..f426746 100644
--- a/webform.module
+++ b/webform.module
@@ -3031,7 +3031,13 @@ function theme_webform_element($variables) {
   }
   $wrapper_attributes['class'] = array_merge($wrapper_classes, $wrapper_attributes['class']);
   $wrapper_attributes['id'] = 'webform-component-' . $parents;
-  $output = '<div ' . drupal_attributes($wrapper_attributes) . '>' . "\n";
+
+  // If there are multiple elements, a label cannot point to all of them.
+  // Removing the ID on the element will remove the label "for" attribute.
+  $multiple_elements = count(element_children($element)) > 1;
+  if ($multiple_elements) {
+    $variables['element']['#id'] = NULL;
+  }
 
   // If #title_display is none, set it to invisible instead - none only used if
   // we have no title at all to use.
@@ -3045,6 +3051,7 @@ function theme_webform_element($variables) {
   }
   $prefix = isset($element['#field_prefix']) ? '<span class="field-prefix">' . _webform_filter_xss($element['#field_prefix']) . '</span> ' : '';
   $suffix = isset($element['#field_suffix']) ? ' <span class="field-suffix">' . _webform_filter_xss($element['#field_suffix']) . '</span>' : '';
+  $output = '';
 
   switch ($element['#title_display']) {
     case 'inline':
@@ -3070,9 +3077,27 @@ function theme_webform_element($variables) {
     $output .= ' <div class="description">' . $element['#description'] . "</div>\n";
   }
 
-  $output .= "</div>\n";
+  // If this is a group of elements, display as a fieldset for accessibility.
+  // This legend is *always* hidden by CSS, and it's intentional that is be
+  // hidden because fieldset legends cannot be styled adequately (i.e. cannot
+  // be "display: inline"). The "label" tag is rendered above, inline, or hidden
+  // like normal, while the "legend" tag provides screenreader accessibility,
+  // allowing each element name to be repeated.
+  if ($multiple_elements) {
+    $grouped_output = $output;
+    $output = '';
+    $output .= '<fieldset class="webform-container">';
+    $output .= '<legend class="webform-container-legend">' . $element['#title'] . '</legend>';
+    $output .= $grouped_output;
+    $output .= '</fieldset>';
+  }
 
-  return $output;
+  // Then wrap the whole thing in our main wrapper.
+  $wrapped_output = '<div ' . drupal_attributes($wrapper_attributes) . '>' . "\n";
+  $wrapped_output .= $output;
+  $wrapped_output .= "</div>\n";
+
+  return $wrapped_output;
 }
 
 /**
