diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 7400017..4c3d0dc 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1350,7 +1350,7 @@ function template_preprocess_page(&$variables) {
   $variables['language']          = $language_interface;
   $variables['logo']              = theme_get_setting('logo.url');
   $variables['site_name']         = (theme_get_setting('features.name') ? SafeMarkup::checkPlain($site_config->get('name')) : '');
-  $variables['site_slogan']       = (theme_get_setting('features.slogan') ? Xss::filterAdmin($site_config->get('slogan')) : '');
+  $variables['site_slogan']       = (theme_get_setting('features.slogan') ? SafeMarkup::xssFilterAdmin($site_config->get('slogan')) : '');
 
   // An exception might be thrown.
   try {
diff --git a/core/lib/Drupal/Component/Utility/SafeMarkup.php b/core/lib/Drupal/Component/Utility/SafeMarkup.php
index d97dc2f..b11a65a 100644
--- a/core/lib/Drupal/Component/Utility/SafeMarkup.php
+++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php
@@ -141,6 +141,9 @@ public static function escape($string) {
   /**
    * Applies a very permissive XSS/HTML filter for admin-only use.
    *
+   * This method is preferred to \Drupal\Component\Utility\Xss::filterAdmin()
+   * when the result is being used directly in the rendering system.
+   *
    * @param string $string
    *   A string.
    *
@@ -150,8 +153,48 @@ public static function escape($string) {
    *
    * @see \Drupal\Component\Utility\Xss::filterAdmin()
    */
+  public static function xssFilterAdmin($string) {
+    if (!static::isSafe($string)) {
+      $string = Xss::filterAdmin($string);
+      static::set($string);
+    }
+    return $string;
+  }
+
+  /**
+   * Applies a very permissive XSS/HTML filter for admin-only use.
+   *
+   * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
+   *   \Drupal\Component\Utility\SafeMarkup::xssFilterAdmin() instead.
+   *
+   * @see \Drupal\Component\Utility\SafeMarkup::xssFilterAdmin()
+   */
   public static function checkAdminXss($string) {
-    return static::isSafe($string) ? $string : Xss::filterAdmin($string);
+    return static::xssFilterAdmin($string);
+  }
+
+  /**
+   * Filters HTML to prevent cross-site-scripting (XSS) vulnerabilities.
+   *
+   * This method is preferred to \Drupal\Component\Utility\Xss::filter() when
+   * the result is being used directly in the rendering system.
+   *
+   * @param $string
+   *   The string with raw HTML in it. It will be stripped of everything that
+   *   can cause an XSS attack. The string provided will always be escaped
+   *   regardless of whether the string is already marked as safe.
+   * @param array $html_tags
+   *   An array of HTML tags.
+   *
+   * @return string
+   *   An XSS safe version of $string, or an empty string if $string is not
+   *   valid UTF-8.
+   *
+   * @see \Drupal\Component\Utility\Xss::filter()
+   */
+  public static function xssFilter($string, $html_tags = array('a', 'em', 'strong', 'cite', 'blockquote', 'code', 'ul', 'ol', 'li', 'dl', 'dt', 'dd')) {
+    $string = Xss::filter($string, $html_tags);
+    return static::set($string);
   }
 
   /**
diff --git a/core/lib/Drupal/Component/Utility/Xss.php b/core/lib/Drupal/Component/Utility/Xss.php
index f967ca6..5fd7c8f 100644
--- a/core/lib/Drupal/Component/Utility/Xss.php
+++ b/core/lib/Drupal/Component/Utility/Xss.php
@@ -29,14 +29,17 @@ class Xss {
    * Based on kses by Ulf Harnhammar, see http://sourceforge.net/projects/kses.
    * For examples of various XSS attacks, see: http://ha.ckers.org/xss.html.
    *
-   * This code does five things:
+   * This method is preferred to
+   * \Drupal\Component\Utility\SafeMarkup::xssFilter() when the result is
+   * not being used directly in the rendering system. For example, when its
+   * result is being combined with other strings before rendering.
+   *
+   * This code does four things:
    * - Removes characters and constructs that can trick browsers.
    * - Makes sure all HTML entities are well-formed.
    * - Makes sure all HTML tags and attributes are well-formed.
    * - Makes sure no HTML tags contain URLs with a disallowed protocol (e.g.
    *   javascript:).
-   * - Marks the sanitized, XSS-safe version of $string as safe markup for
-   *   rendering.
    *
    * @param $string
    *   The string with raw HTML in it. It will be stripped of everything that
@@ -49,7 +52,7 @@ class Xss {
    *   valid UTF-8.
    *
    * @see \Drupal\Component\Utility\Unicode::validateUtf8()
-   * @see \Drupal\Component\Utility\SafeMarkup
+   * @see \Drupal\Component\Utility\SafeMarkup::xssFilter()
    *
    * @ingroup sanitization
    */
@@ -83,7 +86,7 @@ public static function filter($string, $html_tags = array('a', 'em', 'strong', '
     // for output. All other known XSS vectors have been filtered out by this
     // point and any HTML tags remaining will have been deliberately allowed, so
     // it is acceptable to call SafeMarkup::set() on the resultant string.
-    return SafeMarkup::set(preg_replace_callback('%
+    return preg_replace_callback('%
       (
       <(?=[^a-zA-Z!/])  # a lone <
       |                 # or
@@ -92,7 +95,7 @@ public static function filter($string, $html_tags = array('a', 'em', 'strong', '
       <[^>]*(>|$)       # a string that starts with a <, up until the > or the end of the string
       |                 # or
       >                 # just a >
-      )%x', $splitter, $string));
+      )%x', $splitter, $string);
   }
 
   /**
@@ -103,6 +106,11 @@ public static function filter($string, $html_tags = array('a', 'em', 'strong', '
    * is desired (so \Drupal\Component\Utility\SafeMarkup::checkPlain() is
    * not acceptable).
    *
+   * This method is preferred to
+   * \Drupal\Component\Utility\SafeMarkup::xssFilterAdmin() when the result is
+   * not being used directly in the rendering system. For example, when its
+   * result is being combined with other strings before rendering.
+   *
    * Allows all tags that can be used inside an HTML body, save
    * for scripts and styles.
    *
@@ -111,6 +119,8 @@ public static function filter($string, $html_tags = array('a', 'em', 'strong', '
    *
    * @return string
    *   The filtered string.
+   *
+   * @see \Drupal\Component\Utility\SafeMarkup::xssFilterAdmin()
    */
   public static function filterAdmin($string) {
     return static::filter($string, static::$adminTags);
diff --git a/core/lib/Drupal/Core/Render/Element/HtmlTag.php b/core/lib/Drupal/Core/Render/Element/HtmlTag.php
index 5dc3afe..c861cf5 100644
--- a/core/lib/Drupal/Core/Render/Element/HtmlTag.php
+++ b/core/lib/Drupal/Core/Render/Element/HtmlTag.php
@@ -161,7 +161,7 @@ public static function preRenderConditionalComments($element) {
     }
     else {
       // The IE expression might contain some user input data.
-      $expression = SafeMarkup::checkAdminXss($browsers['IE']);
+      $expression = SafeMarkup::xssFilterAdmin($browsers['IE']);
     }
 
     // If the #prefix and #suffix properties are used, wrap them with
@@ -173,8 +173,8 @@ public static function preRenderConditionalComments($element) {
 
     // Ensure what we are dealing with is safe.
     // This would be done later anyway in drupal_render().
-    $prefix = isset($elements['#prefix']) ? SafeMarkup::checkAdminXss($elements['#prefix']) : '';
-    $suffix = isset($elements['#suffix']) ? SafeMarkup::checkAdminXss($elements['#suffix']) : '';
+    $prefix = isset($elements['#prefix']) ? SafeMarkup::xssFilterAdmin($elements['#prefix']) : '';
+    $suffix = isset($elements['#suffix']) ? SafeMarkup::xssFilterAdmin($elements['#suffix']) : '';
 
     // Now calling SafeMarkup::set is safe, because we ensured the
     // data coming in was at least admin escaped.
diff --git a/core/lib/Drupal/Core/Render/Renderer.php b/core/lib/Drupal/Core/Render/Renderer.php
index 858501b..6e56d0a 100644
--- a/core/lib/Drupal/Core/Render/Renderer.php
+++ b/core/lib/Drupal/Core/Render/Renderer.php
@@ -368,7 +368,7 @@ protected function doRender(&$elements, $is_root_call = FALSE) {
     if (isset($elements['#markup'])) {
       // @todo Decide how to support non-HTML in the render API in
       //   https://www.drupal.org/node/2501313.
-      $elements['#markup'] = SafeMarkup::checkAdminXss($elements['#markup']);
+      $elements['#markup'] = SafeMarkup::xssFilterAdmin($elements['#markup']);
     }
 
     // Assume that if #theme is set it represents an implemented hook.
@@ -382,7 +382,7 @@ protected function doRender(&$elements, $is_root_call = FALSE) {
       );
       foreach ($markup_keys as $key) {
         if (!empty($elements[$key]) && is_scalar($elements[$key])) {
-          $elements[$key] = SafeMarkup::checkAdminXss($elements[$key]);
+          $elements[$key] = SafeMarkup::xssFilterAdmin($elements[$key]);
         }
       }
     }
@@ -468,8 +468,8 @@ protected function doRender(&$elements, $is_root_call = FALSE) {
     // with how render cached output gets stored. This ensures that placeholder
     // replacement logic gets the same data to work with, no matter if #cache is
     // disabled, #cache is enabled, there is a cache hit or miss.
-    $prefix = isset($elements['#prefix']) ? SafeMarkup::checkAdminXss($elements['#prefix']) : '';
-    $suffix = isset($elements['#suffix']) ? SafeMarkup::checkAdminXss($elements['#suffix']) : '';
+    $prefix = isset($elements['#prefix']) ? SafeMarkup::xssFilterAdmin($elements['#prefix']) : '';
+    $suffix = isset($elements['#suffix']) ? SafeMarkup::xssFilterAdmin($elements['#suffix']) : '';
 
     $elements['#markup'] = $prefix . $elements['#children'] . $suffix;
 
diff --git a/core/modules/dblog/src/Controller/DbLogController.php b/core/modules/dblog/src/Controller/DbLogController.php
index 2e2eccf..04be50a 100644
--- a/core/modules/dblog/src/Controller/DbLogController.php
+++ b/core/modules/dblog/src/Controller/DbLogController.php
@@ -285,7 +285,7 @@ public function eventDetails($event_id) {
         ),
         array(
           array('data' => $this->t('Operations'), 'header' => TRUE),
-          SafeMarkup::checkAdminXss($dblog->link),
+          SafeMarkup::xssFilterAdmin($dblog->link),
         ),
       );
       $build['dblog_table'] = array(
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 400d6cc..d28b841 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -430,7 +430,7 @@ function template_preprocess_filter_tips(&$variables) {
   foreach ($variables['tips'] as $name => $tiplist) {
     foreach ($tiplist as $tip_key => $tip) {
       $tiplist[$tip_key]['attributes'] = new Attribute();
-      $tiplist[$tip_key]['tip'] = Xss::filterAdmin($tiplist[$tip_key]['tip']);
+      $tiplist[$tip_key]['tip'] = SafeMarkup::xssFilterAdmin($tiplist[$tip_key]['tip']);
     }
 
     $variables['tips'][$name] = array(
diff --git a/core/modules/filter/src/Plugin/Filter/FilterCaption.php b/core/modules/filter/src/Plugin/Filter/FilterCaption.php
index 6f90565..ed241d8 100644
--- a/core/modules/filter/src/Plugin/Filter/FilterCaption.php
+++ b/core/modules/filter/src/Plugin/Filter/FilterCaption.php
@@ -45,7 +45,7 @@ public function process($text, $langcode) {
         // Sanitize caption: decode HTML encoding, limit allowed HTML tags; only
         // allow inline tags that are allowed by default, plus <br>.
         $caption = Html::decodeEntities($caption);
-        $caption = Xss::filter($caption, array('a', 'em', 'strong', 'cite', 'code', 'br'));
+        $caption = SafeMarkup::xssFilter($caption, array('a', 'em', 'strong', 'cite', 'code', 'br'));
 
         // The caption must be non-empty.
         if (Unicode::strlen($caption) === 0) {
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index f7374da..f3be5b6 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -9,6 +9,7 @@
  */
 
 use Drupal\Component\Utility\Html;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Cache\Cache;
@@ -508,7 +509,7 @@ function template_preprocess_node_add_list(&$variables) {
       $variables['types'][$type->id()] = array(
         'type' => $type->id(),
         'add_link' => \Drupal::l($type->label(), new Url('node.add', array('node_type' => $type->id()))),
-        'description' => Xss::filterAdmin($type->getDescription()),
+        'description' => SafeMarkup::xssFilterAdmin($type->getDescription()),
       );
     }
   }
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index b4c4126..25d52b5 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -8,7 +8,6 @@
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Unicode;
-use Drupal\Component\Utility\Xss;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
@@ -768,7 +767,7 @@ function search_excerpt($keys, $text, $langcode = NULL) {
   // Highlight keywords. Must be done at once to prevent conflicts ('strong'
   // and '<strong>').
   $text = trim(preg_replace('/' . $boundary . '(?:' . implode('|', $keys) . ')' . $boundary . '/iu', '<strong>\0</strong>', ' ' . $text . ' '));
-  return Xss::filter($text, ['strong']);
+  return SafeMarkup::xssFilter($text, ['strong']);
 }
 
 /**
diff --git a/core/modules/simpletest/src/Form/SimpletestResultsForm.php b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
index ea3447e..63dea75 100644
--- a/core/modules/simpletest/src/Form/SimpletestResultsForm.php
+++ b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
@@ -313,7 +313,7 @@ public static function addResultForm(array &$form, array $results) {
       $rows = array();
       foreach ($assertions as $assertion) {
         $row = array();
-        $row[] = SafeMarkup::checkAdminXss($assertion->message);
+        $row[] = SafeMarkup::xssFilterAdmin($assertion->message);
         $row[] = $assertion->message_group;
         $row[] = \Drupal::service('file_system')->basename(($assertion->file));
         $row[] = $assertion->line;
diff --git a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
index c5ebaa5..117ba2c 100644
--- a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
+++ b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Plugin\Block;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Block\BlockBase;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Config\ConfigFactoryInterface;
@@ -173,7 +174,7 @@ public function build() {
     );
 
     $build['site_slogan'] = array(
-      '#markup' => Xss::filterAdmin($site_config->get('slogan')),
+      '#markup' => SafeMarkup::xssFilterAdmin($site_config->get('slogan')),
       '#access' => $this->configuration['use_site_slogan'],
     );
 
diff --git a/core/modules/views/src/Plugin/views/field/Field.php b/core/modules/views/src/Plugin/views/field/Field.php
index 386456c..455f48e 100644
--- a/core/modules/views/src/Plugin/views/field/Field.php
+++ b/core/modules/views/src/Plugin/views/field/Field.php
@@ -671,7 +671,7 @@ public function renderItems($items) {
     if (!empty($items)) {
       $items = $this->prepareItemsByDelta($items);
       if ($this->options['multi_type'] == 'separator' || !$this->options['group_rows']) {
-        $separator = $this->options['multi_type'] == 'separator' ? SafeMarkup::checkAdminXss($this->options['separator']) : '';
+        $separator = $this->options['multi_type'] == 'separator' ? SafeMarkup::xssFilterAdmin($this->options['separator']) : '';
         $build = [
           '#type' => 'inline_template',
           '#template' => '{{ items | safe_join(separator) }}',
