diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index f17df18..39e102b 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -240,7 +240,7 @@ public function elementType($none_supported = FALSE, $default_empty = FALSE, $in
       }
     }
     if ($this->options['element_type']) {
-      return SafeMarkup::checkPlain($this->options['element_type']);
+      return $this->options['element_type'];
     }
 
     if ($default_empty) {
@@ -268,7 +268,7 @@ public function elementLabelType($none_supported = FALSE, $default_empty = FALSE
       }
     }
     if ($this->options['element_label_type']) {
-      return SafeMarkup::checkPlain($this->options['element_label_type']);
+      return $this->options['element_label_type'];
     }
 
     if ($default_empty) {
@@ -288,7 +288,7 @@ public function elementWrapperType($none_supported = FALSE, $default_empty = FAL
       }
     }
     if ($this->options['element_wrapper_type']) {
-      return SafeMarkup::checkPlain($this->options['element_wrapper_type']);
+      return $this->options['element_wrapper_type'];
     }
 
     if ($default_empty) {
diff --git a/core/modules/views/templates/views-view-fields.html.twig b/core/modules/views/templates/views-view-fields.html.twig
index a8aa00b..be8edc6 100644
--- a/core/modules/views/templates/views-view-fields.html.twig
+++ b/core/modules/views/templates/views-view-fields.html.twig
@@ -11,13 +11,15 @@
  *   - class: The safe class ID to use.
  *   - handler: The Views field handler controlling this field.
  *   - inline: Whether or not the field should be inline.
- *   - inline_html: Either div or span based on the 'inline' flag.
- *   - wrapper_prefix: A complete wrapper containing the inline_html to use.
- *   - wrapper_suffix: The closing tag for the wrapper.
+ *   - wrapper_element: An HTML element for a wrapper.
+ *   - wrapper_attributes: List of attributes for wrapper element.
  *   - separator: An optional separator that may appear before a field.
  *   - label: The field's label text.
- *   - label_html: The full HTML of the label to use including configured
- *     element type.
+ *   - label_element: An HTML element for a label wrapper.
+ *   - label_attributes: List of attributes for label wrapper.
+ *   - label_suffix: Colon after the label.
+ *   - element_type: An HTML element for the field content.
+ *   - element_attributes: List of attributes for HTML element for field content.
  * - row: The raw result from the query, with all data it fetched.
  *
  * @see template_preprocess_views_view_fields()
@@ -31,11 +33,24 @@ See http://api.drupal.org/api/function/theme_views_view_fields/8 for details.
 After copying this file to your theme's folder and customizing it, remove this
 HTML comment.
 -->
-{% for field in fields %}
+{% for field in fields -%}
   {{ field.separator }}
-
-  {{ field.wrapper_prefix }}
-    {{ field.label_html }}
+  {%- if field.wrapper_element -%}
+    <{{ field.wrapper_element }}{{ field.wrapper_attributes }}>
+  {%- endif %}
+  {%- if field.label -%}
+    {%- if field.label_element -%}
+      <{{ field.label_element }}{{ field.label_attributes }}>{{ field.label }}{{ field.label_suffix }}</{{ field.label_element }}>
+    {%- else -%}
+      {{ field.label }}{{ field.label_suffix }}
+    {%- endif %}
+  {%- endif %}
+  {%- if field.element_type -%}
+    <{{ field.element_type }}{{ field.element_attributes }}>{{ field.content }}</{{ field.element_type }}>
+  {%- else -%}
     {{ field.content }}
-  {{ field.wrapper_suffix }}
-{% endfor %}
+  {%- endif %}
+  {%- if field.wrapper_element -%}
+    </{{ field.wrapper_element }}>
+  {%- endif %}
+{%- endfor %}
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 236b6d0..cae5c75 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -101,18 +101,7 @@ function template_preprocess_views_view_fields(&$variables) {
         if ($classes = $object->handler->elementClasses($row->index)) {
           $attributes['class'][] = $classes;
         }
-        $attributes = new Attribute($attributes);
-
-        $pre = '<' . $object->element_type;
-        $pre .= $attributes;
-        $field_output = $pre . '>' . $field_output . '</' . $object->element_type . '>';
-      }
-
-      // Protect ourselves somewhat for backward compatibility. This will
-      // prevent old templates from producing invalid HTML when no element type
-      // is selected.
-      if (empty($object->element_type)) {
-        $object->element_type = 'span';
+        $object->element_attributes = new Attribute($attributes);
       }
 
       $object->content = $field_output;
@@ -130,16 +119,14 @@ function template_preprocess_views_view_fields(&$variables) {
       $object->class = Html::cleanCssIdentifier($id);
 
       $previous_inline = $object->inline;
-      $object->inline_html = $object->handler->elementWrapperType(TRUE, TRUE);
-      if ($object->inline_html === '' && $variables['options']['default_field_elements']) {
-        $object->inline_html = $object->inline ? 'span' : 'div';
+      // Set up field wrapper element.
+      $object->wrapper_element = $object->handler->elementWrapperType(TRUE, TRUE);
+      if ($object->wrapper_element === '' && $variables['options']['default_field_elements']) {
+        $object->wrapper_element = $object->inline ? 'span' : 'div';
       }
 
-      // Set up the wrapper HTML.
-      $object->wrapper_prefix = '';
-      $object->wrapper_suffix = '';
-
-      if ($object->inline_html) {
+      // Set up field wrapper attributes if field wrapper was set.
+      if ($object->wrapper_element) {
         $attributes = array();
         if ($object->handler->options['element_default_classes']) {
           $attributes['class'][] = 'views-field';
@@ -149,26 +136,24 @@ function template_preprocess_views_view_fields(&$variables) {
         if ($classes = $object->handler->elementWrapperClasses($row->index)) {
           $attributes['class'][] = $classes;
         }
-        $attributes = new Attribute($attributes);
-
-        $object->wrapper_prefix = '<' . $object->inline_html;
-        $object->wrapper_prefix .= $attributes;
-        $object->wrapper_prefix .= '>';
-        $object->wrapper_suffix = '</' . $object->inline_html . '>';
+        $object->wrapper_attributes = new Attribute($attributes);
       }
 
-      // Set up the label for the value and the HTML to make it easier
-      // on the template.
-      $object->label = SafeMarkup::checkPlain($view->field[$id]->label());
-      $object->label_html = '';
+      // Set up field label
+      $object->label = $view->field[$id]->label();
+
+      // Set up field label wrapper and its attributes.
       if ($object->label) {
-        $object->label_html .= $object->label;
+        // Add a colon in a label suffix.
         if ($object->handler->options['element_label_colon']) {
-          $object->label_html .= ': ';
+          $object->label_suffix = ': ';
         }
 
-        $object->elementLabelType = $object->handler->elementLabelType(TRUE, !$variables['options']['default_field_elements']);
-        if ($object->elementLabelType) {
+        // Set up label HTML element.
+        $object->label_element = $object->handler->elementLabelType(TRUE, !$variables['options']['default_field_elements']);
+
+        // Set up label attributes.
+        if ($object->label_element) {
           $attributes = array();
           if ($object->handler->options['element_default_classes']) {
             $attributes['class'][] = 'views-label';
@@ -179,13 +164,7 @@ function template_preprocess_views_view_fields(&$variables) {
           if ($element_label_class) {
             $attributes['class'][] = $element_label_class;
           }
-          $attributes = new Attribute($attributes);
-
-          $pre = '<' . $object->elementLabelType;
-          $pre .= $attributes;
-          $pre .= '>';
-
-          $object->label_html = $pre . $object->label_html . '</' . $object->elementLabelType . '>';
+          $object->label_attributes = new Attribute($attributes);
         }
       }
 
@@ -219,12 +198,33 @@ function theme_views_view_fields($variables) {
     if (!empty($field->separator)) {
       $output .= $field->separator;
     }
-
-    $output .= $field->wrapper_prefix;
-    $output .= $field->label_html;
+    $wrapper_element = SafeMarkup::checkPlain($field->wrapper_element);
+    if ($wrapper_element) {
+      $output .= '<' . $wrapper_element . $field->wrapper_attributes . '>';
+      if (isset($field->label_element) && !empty($field->label_element)) {
+        $label_element = SafeMarkup::checkPlain($field->label_element);
+        $output .= '<' . $label_element . $field->label_attributes . '>';
+      }
+      $output .= SafeMarkup::checkPlain($field->label);
+      if (isset($field->label_suffix) && isset($field->label_suffix)) {
+        $output .= $field->label_suffix;
+      }
+      if ($label_element) {
+        $output .= '</' . $label_element . '>';
+      }
+    }
+    $element_type = SafeMarkup::checkPlain($field->element_type);
+    if ($element_type) {
+      $output .= '<' . $element_type . $field->element_attributes . '>';
+    }
+    // @todo this is not sanitized in render, cant use sanitizeValue from here
     $output .= $field->content;
-
-    $output .= $field->wrapper_suffix;
+    if ($element_type) {
+      $output .= '</' . $element_type . '>';
+    }
+    if ($wrapper_element) {
+      $output .= '</' . $wrapper_element . '>';
+    }
   }
 
   return $output;
