diff --git a/README.txt b/README.txt
index 770986a..b92f791 100644
--- a/README.txt
+++ b/README.txt
@@ -19,13 +19,15 @@ gets triggered on the accordion element.
 
 INSTALLATION:
 --------
-1. Install & Enable the module
-2. Open Administration > Configuration > Content authoring >
+1. Download external library from https://github.com/smillart/WAI-ARIA-Patterns-And-Widgets.
+2. Place the library in the root libraries folder (/libraries).
+3. Install & Enable the module
+4. Open Administration > Configuration > Content authoring >
    Text formats and editors (admin/config/content/formats)
-3. Edit a text format's settings (usually Basic HTML)
-4. Drag n Drop the Add Accordion -button to the toolbar to show it to the users
-5. Scroll down to the bottom to the input Allowed HTML tags
-6. Find and replace <dl> with <dl class>
+5. Edit a text format's settings (usually Basic HTML)
+6. Drag n Drop the Add Accordion -button to the toolbar to show it to the users
+7. Scroll down to the bottom to the input Allowed HTML tags
+8. Find and replace <dl> with <dl class>
    This ensures CKEditor doesn't remove the class name that the accordion uses.
-7. If you would like the Accordion tabs to be closed by default,
+9. If you would like the Accordion tabs to be closed by default,
 	 you can change this setting at: /admin/config/content/ckeditor-accordion
diff --git a/ckeditor_accordion.api.php b/ckeditor_accordion.api.php
new file mode 100644
index 0000000..1b30644
--- /dev/null
+++ b/ckeditor_accordion.api.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Hooks provided by the CKEditor Accordion module.
+ */
+
+
+/**
+ * @addtogroup hooks
+ * @{
+ */
+
+/**
+ * Alter the variant defintition.
+ *
+ * @param array &$definition
+ *   An array representing the HTML structure to be used to render accordions.
+ * @param array &$context
+ *   - 'variant_id': the ID of the variant being used
+ *
+ * @see \Drupal\ckeditor_accordion\Plugin\CkeditorAccordionVariantBase::renderLinks()
+ */
+function hook_ckeditor_accordion_variant_alter(array &$definition, array $context) {
+  if ($context['variant_id'] == 'ckeditor_accordion_variant_default') {
+    $definition['list']['attributes']['class'][] = 'my-custom-class';
+  }
+}
+
+/**
+ * @} End of "addtogroup hooks".
+ */
diff --git a/ckeditor_accordion.libraries.yml b/ckeditor_accordion.libraries.yml
index 5fdfea6..d5e05ab 100644
--- a/ckeditor_accordion.libraries.yml
+++ b/ckeditor_accordion.libraries.yml
@@ -9,3 +9,23 @@ accordion_style:
     - core/jquery
     - core/jquery.once
     - core/drupal
+accordion_accessible_style:
+  version: 1.x
+  css:
+    theme:
+      css/ckeditor-accessible-accordion.css: {}
+  dependencies:
+    - core/drupal
+    - ckeditor_accordion/libraries.smillart.wai-aria-patterns-and-widgets
+libraries.smillart.wai-aria-patterns-and-widgets:
+  remote: https://github.com/smillart/WAI-ARIA-Patterns-And-Widgets
+  version: 1.x
+  license:
+    name: MIT
+    url: https://github.com/smillart/WAI-ARIA-Patterns-And-Widgets/blob/master/LICENSE
+    gpl-compatible: true
+  css:
+    theme:
+      /libraries/wai-aria-patterns-and-widgets/dist/accordion/css/accordion.min.css: {}
+  js:
+    /libraries/wai-aria-patterns-and-widgets/dist/accordion/js/accordion.min.js: {}
diff --git a/ckeditor_accordion.module b/ckeditor_accordion.module
index 840b162..51771fc 100644
--- a/ckeditor_accordion.module
+++ b/ckeditor_accordion.module
@@ -10,8 +10,15 @@
 function ckeditor_accordion_page_attachments_alter(array &$page) {
   $config = \Drupal::config('ckeditor_accordion.settings');
 
-  // Attaches css assets globally.
-  $page['#attached']['library'][] = 'ckeditor_accordion/accordion_style';
+  // Attaches accordion accessible style library.
+  if (file_exists(DRUPAL_ROOT . '/libraries/wai-aria-patterns-and-widgets')) {
+    $page['#attached']['library'][] = 'ckeditor_accordion/accordion_accessible_style';
+  }
+  else {
+    // Attaches accordion library if accessible library
+    // does not exist in libraris folder.
+    $page['#attached']['library'][] = 'ckeditor_accordion/accordion_style';
+  }
 
   // Pass settings to JavaScript.
   $page['#attached']['drupalSettings']['ckeditorAccordion']['accordionStyle']['collapseAll'] = $config->get('collapse_all');
diff --git a/ckeditor_accordion.services.yml b/ckeditor_accordion.services.yml
new file mode 100644
index 0000000..58fd86e
--- /dev/null
+++ b/ckeditor_accordion.services.yml
@@ -0,0 +1,4 @@
+services:
+  plugin.manager.ckeditor_accordion_variant:
+    class: Drupal\ckeditor_accordion\Plugin\CkeditorAccordionVariantManager
+    parent: default_plugin_manager
diff --git a/config/install/ckeditor_accordion.settings.yml b/config/install/ckeditor_accordion.settings.yml
new file mode 100644
index 0000000..6b1304f
--- /dev/null
+++ b/config/install/ckeditor_accordion.settings.yml
@@ -0,0 +1,3 @@
+collapse_all: 0
+variant: 'ckeditor_accordion_variant_default'
+langcode: 'en'
diff --git a/css/ckeditor-accessible-accordion.css b/css/ckeditor-accessible-accordion.css
new file mode 100644
index 0000000..25c28e7
--- /dev/null
+++ b/css/ckeditor-accessible-accordion.css
@@ -0,0 +1,105 @@
+/*
+  Accessible Accordion style definition.
+*/
+
+.aria-accordion {
+  border: 1px solid #0065a3;
+}
+.aria-accordion .aria-accordion__heading {
+  margin: 0;
+  padding: 0;
+}
+.aria-accordion .aria-accordion__heading button {
+  display: block;
+  width: 100%;
+  color: #ffffff;
+  text-align: left;
+  margin: 0;
+  padding: 10px 15px 10px 35px;
+  cursor: pointer;
+  background: #007bb2;
+  border: 0;
+  border-bottom: 1px solid #0072a5;
+  border-radius: 0;
+  appearance: none;
+  box-shadow: 0 0 0 transparent;
+  transition: background-color 0.3s;
+  position: relative;
+  z-index: 1;
+  font-size: 1rem;
+}
+.aria-accordion .aria-accordion__heading:last-of-type button {
+  border-bottom: 0;
+}
+.aria-accordion .aria-accordion__heading button:before,
+.aria-accordion .aria-accordion__heading button:after {
+  content: '';
+  display: block;
+  width: 2px;
+  height: 10px;
+  margin: -5px 0 0 5px;
+  position: absolute;
+  top: 50%;
+  background: #ffffff;
+  transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
+}
+.aria-accordion .aria-accordion__heading button:before {
+  left: 7px;
+  transform: rotate(135deg);
+}
+.aria-accordion .aria-accordion__heading button:after {
+  left: 14px;
+  transform: rotate(-135deg);
+}
+.aria-accordion .aria-accordion__heading button:hover,
+.aria-accordion .aria-accordion__heading button:focus {
+  background-color: #0073a7;
+}
+.aria-accordion .aria-accordion__heading button[aria-expanded="true"] {
+  background-color: #004772;
+}
+.aria-accordion .aria-accordion__heading button[aria-expanded="true"]:before {
+  left: 7px;
+  transform: rotate(45deg);
+}
+.aria-accordion .aria-accordion__heading button[aria-expanded="true"]:after {
+  left: 14px;
+  transform: rotate(-45deg);
+}
+.aria-accordion .aria-accordion__panel {
+  margin: 0;
+  padding: 0 15px;
+}
+.aria-accordion .aria-accordion__panel--transition[hidden] {
+  display: block;
+  height: auto;
+  max-height: 0;
+  overflow: hidden;
+  -webkit-transition: max-height 800ms ease-out;
+  -moz-transition: max-height 800ms ease-out;
+  -ms-transition: max-height 800ms ease-out;
+  -o-transition: max-height 800ms ease-out;
+  transition: max-height 800ms ease-out;
+  visibility: visible;
+  /* persist visibility value from animation */
+  animation: 800ms delay-visibility;
+}
+.aria-accordion .aria-accordion__panel--transition {
+  display: block;
+  max-height: 1000px;
+  visibility: visible;
+  -webkit-transition: max-height 800ms ease-in;
+  -moz-transition: max-height 800ms ease-in;
+  -ms-transition: max-height 800ms ease-in;
+  -o-transition: max-height 800ms ease-in;
+  transition: max-height 800ms ease-in;
+  overflow: visible;
+  /* persist overflow value from animation */
+  animation: 800ms delay-overflow;
+}
+@keyframes delay-visibility {
+  from { visibility: visible; }
+}
+@keyframes delay-overflow {
+  from { overflow: hidden; }
+}
diff --git a/src/Annotation/CkeditorAccordionVariant.php b/src/Annotation/CkeditorAccordionVariant.php
new file mode 100644
index 0000000..0f35659
--- /dev/null
+++ b/src/Annotation/CkeditorAccordionVariant.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Drupal\ckeditor_accordion\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a CKEditor Accordion Variant item annotation object.
+ *
+ * @see \Drupal\ckeditor_accordion\Plugin\CkeditorAccordionVariantManager
+ * @see plugin_api
+ *
+ * @Annotation
+ */
+class CkeditorAccordionVariant extends Plugin {
+
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The label of the plugin.
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
+   */
+  public $label;
+
+  /**
+   * The description of the plugin.
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
+   */
+  public $description;
+
+}
diff --git a/src/Form/CkeditorAccordionSettingsForm.php b/src/Form/CkeditorAccordionSettingsForm.php
index 4ead5c5..4f187a7 100644
--- a/src/Form/CkeditorAccordionSettingsForm.php
+++ b/src/Form/CkeditorAccordionSettingsForm.php
@@ -4,6 +4,7 @@ namespace Drupal\ckeditor_accordion\Form;
 
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Component\Utility\Html;
 
 /**
  * Class CkeditorAccordionSettingsForm.
@@ -46,6 +47,19 @@ class CkeditorAccordionSettingsForm extends ConfigFormBase {
       '#default_value' => $config->get('keep_rows_open') ?: 0,
     ];
 
+    $variant_options = [];
+    foreach (\Drupal::service('plugin.manager.ckeditor_accordion_variant')->getDefinitions() as $variant_id => $values) {
+      $variant_options[$values['id']] = Html::escape($values['label']->render() . ': ' . $values['description']->render());
+    }
+
+    $form['variant'] = [
+      '#type' => 'radios',
+      '#title' => $this->t('Variant'),
+      '#description' => $this->t('Select the variant to be used.'),
+      '#options' => $variant_options,
+      '#default_value' => $config->get('variant'),
+    ];
+
     return parent::buildForm($form, $form_state);
   }
 
@@ -58,6 +72,7 @@ class CkeditorAccordionSettingsForm extends ConfigFormBase {
 
     $config->set('collapse_all', $values['collapse_all']);
     $config->set('keep_rows_open', $values['keep_rows_open']);
+    $config->set('variant', $values['variant']);
     $config->save();
 
     parent::submitForm($form, $form_state);
diff --git a/src/Plugin/CkeditorAccordionVariant/CkeditorAccordionVariantDefault.php b/src/Plugin/CkeditorAccordionVariant/CkeditorAccordionVariantDefault.php
new file mode 100644
index 0000000..33ec0d9
--- /dev/null
+++ b/src/Plugin/CkeditorAccordionVariant/CkeditorAccordionVariantDefault.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\ckeditor_accordion\Plugin\CkeditorAccordionVariant;
+
+use Drupal\ckeditor_accordion\Plugin\CkeditorAccordionVariantBase;
+
+
+/**
+ * @CkeditorAccordionVariant(
+ *  id = "ckeditor_accordion_variant_default",
+ *  label = @Translation("Default"),
+ *  description = @Translation("Default HTML structure which uses <div> <h2> <div> style tags."),
+ * )
+ */
+class CkeditorAccordionVariantDefault extends CkeditorAccordionVariantBase{
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $list_tag = [
+    'tag' => 'div',
+    'attributes' => [],
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $title_tag = [
+    'tag' => 'h2',
+    'attributes' => [],
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $description_tag = [
+    'tag' => 'div',
+    'attributes' => [],
+  ];
+  
+}
diff --git a/src/Plugin/CkeditorAccordionVariantBase.php b/src/Plugin/CkeditorAccordionVariantBase.php
new file mode 100644
index 0000000..5442a8c
--- /dev/null
+++ b/src/Plugin/CkeditorAccordionVariantBase.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Drupal\ckeditor_accordion\Plugin;
+
+use Drupal\Component\Plugin\PluginBase;
+
+/**
+ * Base class for CKEditor Accordion Variant plugins.
+ */
+abstract class CkeditorAccordionVariantBase extends PluginBase implements CkeditorAccordionVariantInterface {
+
+  /**
+   * The list tag to be used.
+   *
+   * @var array
+   */
+  protected $list_tag = [
+    'tag' => '',
+    'attributes' => [],
+  ];
+
+  /**
+   * The title tag to be used.
+   *
+   * @var array
+   */
+  protected $title_tag = [
+    'tag' => '',
+    'attributes' => [],
+  ];
+
+  /**
+   * The description tag to be used.
+   *
+   * @var array
+   */
+  protected $description_tag = [
+    'tag' => '',
+    'attributes' => [],
+  ];
+
+  /**
+   * Retrieves the CKEditor Accordion variant definition.
+   *
+   * @return array
+   *   An associative array containing tag and optional attributes for each type
+   *   of accordion's element (list, title, description):
+   *     - list
+   *       - tag
+   *       - attributes
+   *         - class
+   *           - class_name_1
+   *           - class_name_2
+   *           - ...
+   *         - ...
+   *     - title
+   *       - tag
+   *       - attributes
+   *     - description
+   *       - tag
+   *       - attributes
+   */
+  public function getVariantDefinition() {
+    $definition =  [
+      'list' => $this->list_tag,
+      'title' => $this->title_tag,
+      'description' => $this->description_tag,
+    ];
+
+    // Allow other modules to alter the variant definition.
+    $context = [
+      'variant_id' => $this->getBaseId(),
+    ];
+    \Drupal::moduleHandler()->alter('ckeditor_accordion_variant', $definition, $context);
+
+    return $definition;
+  }
+
+}
diff --git a/src/Plugin/CkeditorAccordionVariantInterface.php b/src/Plugin/CkeditorAccordionVariantInterface.php
new file mode 100644
index 0000000..7d76c89
--- /dev/null
+++ b/src/Plugin/CkeditorAccordionVariantInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Drupal\ckeditor_accordion\Plugin;
+
+use Drupal\Component\Plugin\PluginInspectionInterface;
+
+/**
+ * Defines an interface for CKEditor Accordion Variant plugins.
+ */
+interface CkeditorAccordionVariantInterface extends PluginInspectionInterface {
+
+
+  // Add get/set methods for your plugin type here.
+
+}
diff --git a/src/Plugin/CkeditorAccordionVariantManager.php b/src/Plugin/CkeditorAccordionVariantManager.php
new file mode 100644
index 0000000..4da23e8
--- /dev/null
+++ b/src/Plugin/CkeditorAccordionVariantManager.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\ckeditor_accordion\Plugin;
+
+use Drupal\Core\Plugin\DefaultPluginManager;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+
+/**
+ * Provides the CKEditor Accordion Variant plugin manager.
+ */
+class CkeditorAccordionVariantManager extends DefaultPluginManager {
+
+
+  /**
+   * Constructs a new CkeditorAccordionVariantManager object.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler to invoke the alter hook with.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+    parent::__construct('Plugin/CkeditorAccordionVariant', $namespaces, $module_handler, 'Drupal\ckeditor_accordion\Plugin\CkeditorAccordionVariantInterface', 'Drupal\ckeditor_accordion\Annotation\CkeditorAccordionVariant');
+
+    $this->alterInfo('ckeditor_accordion_ckeditor_accordion_variant_info');
+    $this->setCacheBackend($cache_backend, 'ckeditor_accordion_ckeditor_accordion_variant_plugins');
+  }
+
+}
diff --git a/src/Plugin/Filter/CKEditorAccordion.php b/src/Plugin/Filter/CKEditorAccordion.php
new file mode 100644
index 0000000..49d4965
--- /dev/null
+++ b/src/Plugin/Filter/CKEditorAccordion.php
@@ -0,0 +1,145 @@
+<?php
+
+namespace Drupal\ckeditor_accordion\Plugin\Filter;
+
+use Drupal\filter\FilterProcessResult;
+use Drupal\filter\Plugin\FilterBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * @Filter(
+ *   id = "filter_ckeditor_accordion",
+ *   title = @Translation("CKEditor Accordion"),
+ *   description = @Translation("Allows to modify the output of the CKEditor accordions."),
+ *   type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
+ * )
+ */
+class CKEditorAccordion extends FilterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function process($text, $langcode) {
+    // Get selected variant.
+    $config = \Drupal::config('ckeditor_accordion.settings');
+    $variant = \Drupal::service('plugin.manager.ckeditor_accordion_variant')->createInstance($config->get('variant'));
+    $defintion = $variant->getVariantDefinition();
+
+    $tags = [
+      'intial' => [
+        'list' => [
+          'tag' => 'dl',
+        ],
+        'title' => [
+          'tag' => 'dt',
+        ],
+        'description' => [
+          'tag' => 'dd',
+        ],
+      ],
+      'target' => $defintion,
+    ];
+
+    // Add the needed attributes for the accessible script.
+    $tags['target']['list']['attributes']['data-aria-accordion'] = 'data-aria-accordion';
+    $tags['target']['list']['attributes']['data-aria-accordion-allow-toggle'] = 'data-aria-accordion-allow-toggle';
+    $tags['target']['list']['attributes']['data-aria-accordion-panel-transition'] = 'data-aria-accordion-panel-transition';
+    $tags['target']['title']['attributes']['data-aria-accordion-heading'] = 'data-aria-accordion-heading';
+    $tags['target']['description']['attributes']['data-aria-accordion-panel'] = 'data-aria-accordion-panel';
+
+    if (!$config->get('collapse_all')) {
+      $tags['target']['list']['attributes']['data-aria-accordion-open-default'] = '';
+    }
+    if ($config->get('keep_rows_open')) {
+      $tags['target']['list']['attributes']['data-aria-accordion-allow-multiple'] = 'data-aria-accordion-allow-multiple';
+    }
+
+    $initial_class_name = 'ckeditor-accordion';
+
+    // Load the text into a dom object.
+    $dom = new \DOMDocument();
+    $dom->loadHTML(mb_convert_encoding($text, 'HTML-ENTITIES', 'UTF-8'));
+    $xpath = new \DOMXPath($dom);
+
+    // Find and replace title tags.
+    foreach ($xpath->query("//" . $tags['intial']['list']['tag'] . "[contains(@class, '$initial_class_name')]/" . $tags['intial']['title']['tag']) as $title) {
+      // Create the new title tag.
+      $this->replaceElementTag($dom, $title, $tags['target']['title']['tag'], $tags['target']['title']['attributes']);
+    }
+
+    // Find and replace description tags.
+    foreach ($xpath->query("//" . $tags['intial']['list']['tag'] . "[contains(@class, '$initial_class_name')]/" . $tags['intial']['description']['tag']) as $description) {
+      // Create the new description tag.
+      $this->replaceElementTag($dom, $description, $tags['target']['description']['tag'], $tags['target']['description']['attributes']);
+    }
+
+    // Find and replace list tags.
+    foreach ($xpath->query("//" . $tags['intial']['list']['tag'] . "[contains(@class, '$initial_class_name')]") as $accordion) {
+      // Remove the legacy class to avoid conflicts.
+      $classes = explode(' ', $accordion->getAttribute('class'));
+      if (($key = array_search($initial_class_name, $classes)) !== FALSE) {
+        unset($classes[$key]);
+      }
+      empty($classes) ? $accordion->removeAttribute('class') : $accordion->setAttribute('class', implode(' ', $classes));
+
+      // Create the new list tag.
+      $this->replaceElementTag($dom, $accordion, $tags['target']['list']['tag'], $tags['target']['list']['attributes']);
+    }
+
+    $new_text = $dom->saveXml($dom->documentElement);
+
+    return new FilterProcessResult($new_text);
+  }
+
+  /**
+   * Replaces an element's tag with a new one.
+   *
+   * @param \DOMDocument $dom
+   *   The DOMDocument the element is attached to.
+   *
+   * @param \DOMElement $element
+   *   The element for which the tag needs to be replaced.
+   *
+   * @param string $new_tag
+   *   The new tag to be used.
+   *
+   * @param array $new_attributes
+   *   The attributes to be added to the new tag as key => value.
+   *
+   * @param bool $preserve_attributes
+   *   Wether to keep attributes from the given element in the new one.
+   */
+  protected function replaceElementTag(\DOMDocument &$dom, \DOMElement $element, string $new_tag, array $new_attributes = [], $preserve_attributes = TRUE) {
+    $new_element = $dom->createElement($new_tag);
+
+    // Add new attributes to the new element.
+    foreach ($new_attributes as $attribute => $value) {
+      if (is_array($value)) {
+        $value = implode(' ', $value);
+      }
+      $new_element->setAttribute($attribute, $value);
+    }
+
+    if ($preserve_attributes) {
+      // Add all attributes from the intial element.
+      foreach ($element->attributes as $attribute) {
+        $value = $attribute->nodeValue;
+
+        // Make sure we keep the intial attribute value if one exists.
+        if (!empty($new_element->getAttribute($attribute->nodeName))) {
+          $value = implode(' ', [$new_element->getAttribute($attribute->nodeName), $attribute->nodeValue]);
+        }
+
+        $new_element->setAttribute($attribute->nodeName, $value);
+      }
+    }
+
+    // Move the children of the current node to the new one
+    while ($element->hasChildNodes()) {
+      $new_element->appendChild($element->firstChild);        
+    }
+
+    // Replace the current element with the new one.
+    $element->parentNode->replaceChild($new_element, $element);
+  }
+}
