diff --git a/css/webform.element.help.css b/css/webform.element.help.css
new file mode 100644
index 00000000..c7b9b914
--- /dev/null
+++ b/css/webform.element.help.css
@@ -0,0 +1,30 @@
+/**
+ * @file
+ * Element help styles.
+ */
+
+.webform-element-help {
+  display: inline-block;
+  line-height: 1em;
+  width: 1em;
+  background: #0074bd;
+  border-radius: 50%;
+  font-weight: bold;
+  text-align: center;
+  margin: 0 .2em;
+}
+
+.webform-element-help:link,
+.webform-element-help:visited {
+  border: 2px solid #0074bd;
+  background: #0074bd;
+  color: #fff;
+}
+
+.webform-element-help:focus,
+.webform-element-help:active,
+.webform-element-help:hover {
+  border: 2px solid #31708f;
+  background: #31708f;
+  color: #fff;
+}
diff --git a/includes/webform.theme.inc b/includes/webform.theme.inc
index 8469cc71..79ffaf8d 100644
--- a/includes/webform.theme.inc
+++ b/includes/webform.theme.inc
@@ -13,6 +13,7 @@ use Drupal\Core\Template\Attribute;
 use Drupal\Component\Utility\Xss;
 use Drupal\image\Entity\ImageStyle;
 use Drupal\webform\Element\WebformCodeMirror;
+use Drupal\webform\Element\WebformHtmlEditor;
 use Drupal\webform\WebformMessageManagerInterface;
 use Drupal\webform\Utility\WebformYaml;
 use Drupal\webform\Utility\WebformDateHelper;
@@ -873,6 +874,30 @@ function template_preprocess_webform_composite_telephone(array &$variables) {
 // Element templates
 /******************************************************************************/
 
+/**
+ * Prepares variables for element help.
+ *
+ * Default template: webform-element-help.html.twig.
+ *
+ * @param array $variables
+ *   An associative array containing the following key:
+ *   - element: The webform element.
+ *   - help: The help content.
+ */
+function template_preprocess_webform_element_help(array &$variables) {
+  $variables['help_icon'] = [
+    '#type' => 'link',
+    '#title' => '?',
+    '#url' => Url::fromRoute('<none>', [], ['fragment' => 'help']),
+    '#attributes' => [
+      'title' => $variables['help'],
+      // Add 'data-webform-help' attribute which support HTML markup.
+      'data-webform-help' => WebformHtmlEditor::stripTags($variables['help']),
+      'class' => ['webform-element-help'],
+    ],
+  ];
+}
+
 /**
  * Prepares variables for a managed file element.
  *
diff --git a/js/webform.element.help.js b/js/webform.element.help.js
new file mode 100644
index 00000000..689fa81e
--- /dev/null
+++ b/js/webform.element.help.js
@@ -0,0 +1,36 @@
+/**
+ * @file
+ * JavaScript behaviors for element help icon (tooltip).
+ */
+
+(function ($, Drupal) {
+
+  'use strict';
+
+  // @see http://api.jqueryui.com/tooltip/
+  Drupal.webform = Drupal.webform || {};
+
+  Drupal.webform.elementHelpIcon = Drupal.webform.elementHelpIcon || {};
+  Drupal.webform.elementHelpIcon.options = Drupal.webform.elementHelpIcon.options || {};
+
+  /**
+   * Element help icon.
+   *
+   * @type {Drupal~behavior}
+   */
+  Drupal.behaviors.webformElementHelpIcon = {
+    attach: function (context) {
+      $(context).find('.webform-element-help').once('webform-element-help').each(function () {
+        var $link = $(this);
+
+        var options = $.extend({}, Drupal.webform.elementHelpIcon.options);
+        // Use 'data-webform-help' attribute which can include HTML markup.
+        options.content = $(this).attr('data-webform-help');
+        $link.tooltip(options).on('click', function (event) {
+          event.preventDefault();
+        });
+      });
+    }
+  };
+
+})(jQuery, Drupal);
diff --git a/js/webform.element.html_editor.js b/js/webform.element.html_editor.js
index 42f3b6e6..9bb010ab 100644
--- a/js/webform.element.html_editor.js
+++ b/js/webform.element.html_editor.js
@@ -56,7 +56,7 @@
           format_tags: 'p;h2;h3;h4;h5;h6',
           // Autogrow.
           extraPlugins: 'autogrow',
-          autoGrow_minHeight: 100,
+          autoGrow_minHeight: 60,
           autoGrow_maxHeight: 300
         };
 
diff --git a/modules/webform_examples/config/install/webform.webform.example_style_guide.yml b/modules/webform_examples/config/install/webform.webform.example_style_guide.yml
index 3cf0dd0b..754e36d0 100644
--- a/modules/webform_examples/config/install/webform.webform.example_style_guide.yml
+++ b/modules/webform_examples/config/install/webform.webform.example_style_guide.yml
@@ -385,6 +385,10 @@ elements: |
       '#title': 'Title displayed after'
       '#title_display': after
       '#description': 'This is a description.'
+    title_help:
+      '#type': textfield
+      '#title': 'Title with help (tooltip)'
+      '#help': 'This is help displayed in a tooltip. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante.'
     title_display_inline:
       '#type': textfield
       '#title': 'Title displayed inline'
@@ -398,7 +402,7 @@ elements: |
     description_display_tooltip:
       '#type': textfield
       '#title': 'Description displayed in tooltip'
-      '#description': 'This description is displayed in a tooltip.  Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante.'
+      '#description': 'This description is displayed in a tooltip. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante.'
       '#description_display': tooltip
   container_elements:
     '#type': details
diff --git a/src/Element/WebformHtmlEditor.php b/src/Element/WebformHtmlEditor.php
index 428f413c..490f2ffc 100644
--- a/src/Element/WebformHtmlEditor.php
+++ b/src/Element/WebformHtmlEditor.php
@@ -251,7 +251,20 @@ class WebformHtmlEditor extends FormElement {
         ];
       }
     }
+  }
 
+  /**
+   * Strip dis-allowed HTML tags from HTML text.
+   *
+   * @param $text
+   *   HTML text.
+   *
+   * @return string
+   *   HTML text with dis-allowed HTML tags removed.
+   */
+  public static function stripTags($text) {
+    $allowed_tags = '<' . implode('><', static::getAllowedTags()) . '>';
+    return strip_tags($text, $allowed_tags);
   }
 
 }
diff --git a/src/Plugin/WebformElementBase.php b/src/Plugin/WebformElementBase.php
index 77f3993c..91583745 100644
--- a/src/Plugin/WebformElementBase.php
+++ b/src/Plugin/WebformElementBase.php
@@ -183,6 +183,7 @@ class WebformElementBase extends PluginBase implements WebformElementInterface {
     $properties = [
       // Element settings.
       'title' => '',
+      'help' => '',
       'description' => '',
       'default_value' => '',
       // Form display.
@@ -565,6 +566,7 @@ class WebformElementBase extends PluginBase implements WebformElementInterface {
 
     // Add inline title display support.
     if (isset($element['#title_display']) && $element['#title_display'] == 'inline') {
+      $element['#_title_display'] = $element['#title_display'];
       unset($element['#title_display']);
       $element['#wrapper_attributes']['class'][] = 'webform-element--title-inline';
     }
@@ -1659,6 +1661,22 @@ class WebformElementBase extends PluginBase implements WebformElementInterface {
       '#required' => TRUE,
       '#attributes' => ['autofocus' => 'autofocus'],
     ];
+    $form['element']['help'] = [
+      '#type' => 'webform_html_editor',
+      '#title' => $this->t('Help'),
+      '#description' => $this->t('A tooltip displayed after the title.'),
+      '#states' => [
+        'invisible' => [
+          [':input[name="properties[title_display]"]' => ['value' => 'invisible']],
+          'or',
+          [':input[name="properties[title_display]"]' => ['value' => 'attribute']],
+          'or',
+          [':input[name="properties[title_display]"]' => ['value' => 'inline']],
+          'or',
+          [':input[name="properties[title_display]"]' => ['value' => '']],
+        ]
+      ]
+    ];
     $form['element']['description'] = [
       '#type' => 'webform_html_editor',
       '#title' => $this->t('Description'),
diff --git a/src/Tests/Element/WebformElementAllowsTagsTest.php b/src/Tests/Element/WebformElementAllowsTagsTest.php
index fbfb8b3c..c6a47c2c 100644
--- a/src/Tests/Element/WebformElementAllowsTagsTest.php
+++ b/src/Tests/Element/WebformElementAllowsTagsTest.php
@@ -19,7 +19,7 @@ class WebformElementAllowsTagsTest extends WebformTestBase {
   protected static $testWebforms = ['test_element_allowed_tags'];
 
   /**
-   * Test element element allowed tags.
+   * Test element allowed tags.
    */
   public function testAllowsTags() {
     // Check <b> tags is allowed.
diff --git a/src/Tests/Element/WebformElementHelpTest.php b/src/Tests/Element/WebformElementHelpTest.php
new file mode 100644
index 00000000..272abbcd
--- /dev/null
+++ b/src/Tests/Element/WebformElementHelpTest.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\webform\Tests\Element;
+
+use Drupal\webform\Tests\WebformTestBase;
+
+/**
+ * Tests for element help.
+ *
+ * @group Webform
+ */
+class WebformElementHelpTest extends WebformTestBase {
+
+  /**
+   * Webforms to load.
+   *
+   * @var array
+   */
+  protected static $testWebforms = ['test_element_help'];
+
+  /**
+   * Test element help.
+   */
+  public function testHelp() {
+    $this->drupalGet('webform/test_element_help');
+
+    // Check basic help.
+    $this->assertRaw('<a href="#help" title="{This is an example of help}" data-webform-help="{This is an example of help}" class="webform-element-help">?</a>');
+
+    // Check help with HTML markup.
+    $this->assertRaw('<a href="#help" title="{This is an example of help with HTML markup}" data-webform-help="{This is an example of help with &lt;b&gt;HTML markup&lt;/b&gt;}" class="webform-element-help">?</a>');
+
+    // Check help with XSS.
+    $this->assertRaw('<a href="#help" title="{This is an example of help with XSS alert(&quot;XSS&quot;)}" data-webform-help="{This is an example of help with &lt;b&gt;XSS alert(&quot;XSS&quot;)&lt;/b&gt;}" class="webform-element-help">?</a>');
+
+    // Check help with inline title.
+    $this->assertRaw('<a href="#help" title="{This is an example of help with an inline title}" data-webform-help="{This is an example of help with an inline title}" class="webform-element-help">?</a>
+help_inline</label>');
+  }
+
+}
diff --git a/templates/webform-element-help.html.twig b/templates/webform-element-help.html.twig
new file mode 100644
index 00000000..78d8fedf
--- /dev/null
+++ b/templates/webform-element-help.html.twig
@@ -0,0 +1,17 @@
+{#
+/**
+ * @file
+ * Theme implementation for webform element help
+ *
+ * Available variables
+ * - element: form element
+ * - help: Help content.
+ * - help_icon: Help icon.
+ *
+ * @see template_preprocess_webform_element_help()
+ *
+ * @ingroup themeable
+ */
+#}
+{{ attach_library('webform/webform.element.help') }}
+{{ help_icon }}
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml
new file mode 100644
index 00000000..5c0020c1
--- /dev/null
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml
@@ -0,0 +1,143 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_test
+open: null
+close: null
+uid: null
+template: false
+id: test_element_help
+title: 'Test: Element: Help'
+description: 'Test element #help property.'
+category: 'Test: Element'
+elements: |
+  help:
+    '#type': textfield
+    '#title': help
+    '#help': '{This is an example of help}'
+  help_required:
+    '#type': textfield
+    '#title': help_required
+    '#required': true
+    '#help': '{This is an example of help for a required element}'
+  help_html:
+    '#type': textfield
+    '#title': help_html
+    '#help': '{This is an example of help with <b>HTML markup</b>}'
+  help_xss:
+    '#type': textfield
+    '#title': help_xss
+    '#help': '{This is an example of help with <b>XSS <script>alert("XSS")</b>}'
+  help_checkbox:
+    '#type': checkbox
+    '#title': help_checkbox
+    '#help': '{This is an example of help}'
+  help_inline:
+    '#type': textfield
+    '#title': help_inline
+    '#title_display': inline
+    '#help': '{This is an example of help with an inline title}'
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_unsaved: false
+  form_disable_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  submission_label: ''
+  submission_log: false
+  submission_user_columns: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_start_label: ''
+  wizard_complete: true
+  wizard_complete_label: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  limit_total: null
+  limit_total_message: ''
+  limit_user: null
+  limit_user_message: ''
+  purge: none
+  purge_days: null
+  entity_limit_total: null
+  entity_limit_user: null
+  results_disabled: true
+  results_disabled_ignore: true
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
diff --git a/webform.libraries.yml b/webform.libraries.yml
index 76d88efe..25944d4e 100644
--- a/webform.libraries.yml
+++ b/webform.libraries.yml
@@ -403,6 +403,18 @@ webform.element.flexbox:
     layout:
       css/webform.element.flexbox.css: {}
 
+webform.element.help:
+  version: VERSION
+  css:
+    component:
+      css/webform.element.help.css: {}
+  js:
+    js/webform.element.help.js: {}
+  dependencies:
+    - core/drupal
+    - core/jquery.once
+    - core/jquery.ui.tooltip
+
 webform.element.html_editor:
   version: VERSION
   css:
diff --git a/webform.module b/webform.module
index 190cb115..323b83ab 100644
--- a/webform.module
+++ b/webform.module
@@ -588,6 +588,10 @@ function webform_theme() {
       'variables' => ['element' => [], 'value' => NULL, 'webform_submission' => NULL, 'options' => []],
     ],
 
+    'webform_element_help' => [
+      'variables' => ['help' => NULL],
+    ],
+
     'webform_element_managed_file' => [
       'variables' => ['element' => [], 'value' => NULL, 'webform_submission' => NULL, 'options' => [], 'file' => NULL],
     ],
@@ -749,14 +753,43 @@ function webform_preprocess_radios(&$variables) {
 
 /**
  * Prepares variables for form label templates.
- *
- * @see \Drupal\webform\Element\WebformOtherBase::processWebformOther
  */
 function webform_preprocess_form_element_label(&$variables) {
-  $element = $variables['element'];
+  $element = &$variables['element'];
+
+  // Unset 'for' attribute.
+  // @see \Drupal\webform\Element\WebformOtherBase::processWebformOther
   if (isset($element['#attributes']['for']) && $element['#attributes']['for'] === FALSE) {
     unset($variables['attributes']['for']);
   }
+
+  // Restructure the label's title to
+  if (!empty($element['#help'])) {
+    $variables['title'] = [
+      'title' => $variables['title'],
+      'help' => [
+          '#theme' => 'webform_element_help',
+        ] + array_intersect_key($element, array_flip(['#help'])),
+    ];
+
+    $title_display = (isset($element['#_title_display'])) ? $element['#_title_display'] : $element['#title_display'];
+    if ($title_display == 'inline') {
+      $variables['title']['title']['#weight'] = 0;
+      $variables['title']['help']['#weight'] = -1;
+    }
+  }
+}
+
+/**
+ * Prepares variables for form element templates.
+ */
+function webform_preprocess_form_element(&$variables) {
+  $element = &$variables['element'];
+
+  // Add #help and #_title_display to label.
+  // Note: #_title_display is used to track inline titles
+  // @see \Drupal\webform\Plugin\WebformElementBase::prepare
+  $variables['label'] += array_intersect_key($element, array_flip(['#help', '#_title_display']));
 }
 
 /**
