diff --git a/css/paragraphs.widget.css b/css/paragraphs.widget.css
index b460cf7..a037ce6 100644
--- a/css/paragraphs.widget.css
+++ b/css/paragraphs.widget.css
@@ -111,3 +111,7 @@
     height: 40px;
   }
 }
+
+.is-horizontal .tabs__tab {
+  border-bottom: 0;
+}
diff --git a/css/paragraphs.widget.scss b/css/paragraphs.widget.scss
index 407df3a..79b26f0 100644
--- a/css/paragraphs.widget.scss
+++ b/css/paragraphs.widget.scss
@@ -121,3 +121,7 @@
     }
   }
 }
+
+.is-horizontal .tabs__tab {
+  border-bottom: 0;
+}
diff --git a/js/paragraphs.admin.js b/js/paragraphs.admin.js
new file mode 100644
index 0000000..49f6333
--- /dev/null
+++ b/js/paragraphs.admin.js
@@ -0,0 +1,38 @@
+(function ($, Drupal) {
+
+  'use strict';
+
+  /**
+   * For body tag, adds tabs for selecting how the content will be displayed.
+   *
+   * @type {Drupal~behavior}
+   */
+  Drupal.behaviors.bodyTabs = {
+    attach: function (context, settings) {
+      /** Set content fields to visible when tabs are created **/
+      $('.paragraphs-content').show();
+      $('.paragraphs-behavior').hide();
+      /** Create click event **/
+      $(context).find('.paragraphs-tabs').find('a').click(function(e) {
+        e.preventDefault();
+        /** Switching active class between tabs */
+        var el = jQuery(this);
+        $(context).find('.paragraphs-tabs').find('li').removeClass('is-active');
+        el.parent('li').addClass('is-active');
+        $(context).find('.paragraphs-tabs-wrapper').removeClass('is-active');
+        $(context).find(el.attr('href')).addClass('is-active');
+        /** Show/Hide fields based on current active class */
+        if($(context).find('.paragraphs-tabs-wrapper').find('#content').hasClass('is-active')) {
+          $('.paragraphs-content').show();
+          $('.paragraphs-behavior').hide();
+        }
+        if($(context).find('.paragraphs-tabs-wrapper').find('#behavior').hasClass('is-active')) {
+          $('.paragraphs-content').hide();
+          $('.paragraphs-behavior').show();
+        }
+      } );
+    }
+  };
+
+})(jQuery, Drupal);
+
diff --git a/paragraphs.libraries.yml b/paragraphs.libraries.yml
index bb2015d..2c2f4a0 100644
--- a/paragraphs.libraries.yml
+++ b/paragraphs.libraries.yml
@@ -1,5 +1,4 @@
 drupal.paragraphs.admin:
-  version: VERSION
   dependencies:
       - core/jquery
       - core/drupal
@@ -13,6 +12,16 @@ drupal.paragraphs.admin:
       css/paragraphs.admin.css: {}
 
 drupal.paragraphs.widget:
+  dependencies:
+    - core/jquery
+    - core/drupal
+    - core/drupalSettings
+    - core/jquery.once
+    - core/jquery.form
+    - core/drupal.ajax
+    - core/drupal.dropbutton
   css:
     theme:
       css/paragraphs.widget.css: {}
+  js:
+    js/paragraphs.admin.js: {}
diff --git a/src/ParagraphInterface.php b/src/ParagraphInterface.php
index 5cdbcc8..de534b0 100644
--- a/src/ParagraphInterface.php
+++ b/src/ParagraphInterface.php
@@ -9,8 +9,7 @@ use Drupal\Core\Entity\ContentEntityInterface;
  * Provides an interface defining a paragraphs entity.
  * @ingroup paragraphs
  */
-interface ParagraphInterface extends ContentEntityInterface, EntityOwnerInterface
-{
+interface ParagraphInterface extends ContentEntityInterface, EntityOwnerInterface {
 
   /**
    * Gets the parent entity of the paragraph.
diff --git a/src/ParagraphsBehaviorBase.php b/src/ParagraphsBehaviorBase.php
index f523bc7..28abd11 100644
--- a/src/ParagraphsBehaviorBase.php
+++ b/src/ParagraphsBehaviorBase.php
@@ -118,7 +118,7 @@ abstract class ParagraphsBehaviorBase extends PluginBase implements ParagraphsBe
    * {@inheritdoc}
    */
   public function buildBehaviorForm(ParagraphInterface $paragraph, array &$form, FormStateInterface $form_state) {
-    return [];
+    return $form;
   }
 
   /**
diff --git a/src/ParagraphsTypeInterface.php b/src/ParagraphsTypeInterface.php
index 9465772..60f9742 100644
--- a/src/ParagraphsTypeInterface.php
+++ b/src/ParagraphsTypeInterface.php
@@ -31,7 +31,7 @@ interface ParagraphsTypeInterface extends ConfigEntityInterface {
   /**
    * Retrieves all the enabled plugins.
    *
-   * @return array
+   * @return \Drupal\paragraphs\ParagraphsBehaviorInterface[]
    *   Array of the enabled plugins as instances.
    */
   public function getEnabledBehaviorPlugins();
diff --git a/src/Plugin/Field/FieldWidget/ParagraphsWidget.php b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
index 097984a..1dbabb9 100644
--- a/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
+++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
@@ -223,6 +223,7 @@ class ParagraphsWidget extends WidgetBase {
     $parents = $element['#field_parents'];
     $info = [];
 
+    /** @var \Drupal\paragraphs\Entity\Paragraph $paragraphs_entity */
     $paragraphs_entity = NULL;
     $host = $items->getEntity();
     $widget_state = static::getWidgetState($parents, $field_name, $form_state);
@@ -619,13 +620,37 @@ class ParagraphsWidget extends WidgetBase {
 
       if ($item_mode == 'edit') {
         $display->buildForm($paragraphs_entity, $element['subform'], $form_state);
+        // Get the field definitions of the paragraphs_entity.
+        // We need them to filter out entity reference revisions fields that
+        // reference paragraphs, cause otherwise we have problems with showing
+        // and hiding the right fields in nested paragraphs.
+        $field_definitions = $paragraphs_entity->getFieldDefinitions();
+
         foreach (Element::children($element['subform']) as $field) {
+          // Do a check if we have to add a class to the form element. We need
+          // those classes (paragraphs-content and paragraphs-behavior) to show
+          // and hide elements, depending of the active perspective.
+          $omit_class = FALSE;
+          if (isset($field_definitions[$field])) {
+            $type = $field_definitions[$field]->getType();
+            if ($type == 'entity_reference_revisions') {
+              // Check if we are referencing paragraphs.
+              $target_entity_type = $field_definitions[$field]->get('entity_type');
+              if ($target_entity_type && $target_entity_type == 'paragraph') {
+                $omit_class = TRUE;
+              }
+            }
+          }
+
           if ($paragraphs_entity->hasField($field)) {
+            if (!$omit_class) {
+              $element['subform'][$field]['#attributes']['class'][] = 'paragraphs-content';
+            }
             $translatable = $paragraphs_entity->{$field}->getFieldDefinition()->isTranslatable();
             if ($translatable) {
               $element['subform'][$field]['widget']['#after_build'][] = [
                 static::class,
-                'removeTranslatabilityClue'
+                'removeTranslatabilityClue',
               ];
             }
           }
@@ -638,10 +663,16 @@ class ParagraphsWidget extends WidgetBase {
             '#weight' => -10,
           ];
           foreach ($paragraphs_type->getEnabledBehaviorPlugins() as $plugin_id => $plugin) {
-            $element['behavior_plugins'][$plugin_id] = [];
+            $element['behavior_plugins'][$plugin_id] = [
+              '#type' => 'container',
+              '#group' => implode('][', array_merge($element_parents, ['paragraph_behavior'])),
+            ];
             $subform_state = SubformState::createForSubform($element['behavior_plugins'][$plugin_id], $form, $form_state);
             if ($plugin_form = $plugin->buildBehaviorForm($paragraphs_entity, $element['behavior_plugins'][$plugin_id], $subform_state)) {
               $element['behavior_plugins'][$plugin_id] = $plugin_form;
+              // Add the paragraphs-behavior class, so that we are able to show
+              // and hide behavior fields, depending on the active perspective.
+              $element['behavior_plugins'][$plugin_id]['#attributes']['class'][] = 'paragraphs-behavior';
             }
           }
         }
@@ -785,9 +816,20 @@ class ParagraphsWidget extends WidgetBase {
     $description = FieldFilteredMarkup::create(\Drupal::token()->replace($this->fieldDefinition->getDescription()));
 
     $elements = array();
+    $tabs = '';
     $this->fieldIdPrefix = implode('-', array_merge($this->fieldParents, array($field_name)));
     $this->fieldWrapperId = Html::getUniqueId($this->fieldIdPrefix . '-add-more-wrapper');
-    $elements['#prefix'] = '<div id="' . $this->fieldWrapperId . '">';
+
+    // If the parent entity is paragraph add the nested class if not then add
+    // the perspective tabs.
+    $field_prefix = strtr($this->fieldIdPrefix, '_', '-');
+    if ($max > 0 && $items->getEntity()->getEntityTypeId() != 'paragraph') {
+      $tabs = '<ul class="paragraphs-tabs tabs primary clearfix"><li id="content" class="tabs__tab is-active"><a href="#' . $field_prefix . '-values">Content</a></li><li id="behavior" class="tabs__tab"><a href="#' . $field_prefix . '-values">Behavior</a></li></ul>';
+    }
+    else {
+      $form['#attributes']['class'][] = 'paragraphs-nested';
+    }
+    $elements['#prefix'] = '<div class="is-horizontal paragraphs-tabs-wrapper" id="' . $this->fieldWrapperId . '">' . $tabs;
     $elements['#suffix'] = '</div>';
 
     $field_state['ajax_wrapper_id'] = $this->fieldWrapperId;
@@ -1267,16 +1309,18 @@ class ParagraphsWidget extends WidgetBase {
             $paragraphs_entity->set($langcode_key, $form_state->get('langcode'));
           }
         }
-        if (isset($item['behavior_plugins'])) {
+        if (isset($item['subform'])) {
           // Submit all enabled behavior plugins.
           $paragraphs_type = $paragraphs_entity->getParagraphType();
           foreach ($paragraphs_type->getEnabledBehaviorPlugins() as $plugin_id => $plugin_values) {
-            if (!isset($item['behavior_plugins'][$plugin_id])) {
-              $item['behavior_plugins'][$plugin_id] = [];
+            if (!isset($item['subform'][$plugin_id])) {
+              $item['subform'][$plugin_id] = [];
             }
             if (isset($element[$delta]) && isset($element[$delta]['behavior_plugins'][$plugin_id]) && $form_state->getCompleteForm()) {
               $subform_state = SubformState::createForSubform($element[$delta]['behavior_plugins'][$plugin_id], $form_state->getCompleteForm(), $form_state);
-              $plugin_values->submitBehaviorForm($paragraphs_entity, $item['behavior_plugins'][$plugin_id], $subform_state);
+              if ($item['behavior_plugins'][$plugin_id]) {
+                $plugin_values->submitBehaviorForm($paragraphs_entity, $item['behavior_plugins'][$plugin_id], $subform_state);
+              }
             }
           }
         }
diff --git a/src/Tests/Experimental/ParagraphsExperimentalBehaviorsTest.php b/src/Tests/Experimental/ParagraphsExperimentalBehaviorsTest.php
index 639202a..9690407 100644
--- a/src/Tests/Experimental/ParagraphsExperimentalBehaviorsTest.php
+++ b/src/Tests/Experimental/ParagraphsExperimentalBehaviorsTest.php
@@ -75,13 +75,13 @@ class ParagraphsExperimentalBehaviorsTest extends ParagraphsExperimentalTestBase
 
     // Create a node with a Paragraph.
     $this->drupalGet('node/add/paragraphed_test');
-    $this->assertFieldByName('field_paragraphs[0][behavior_plugins][test_text_color][text_color]', 'green');
+    $this->assertFieldByName('field_paragraphs[0][subform][test_text_color][text_color]', 'green');
     // Setting a not allowed value in the text color plugin text field.
     $plugin_text = 'green';
     $edit = [
       'title[0][value]' => 'paragraphs_plugins_test',
       'field_paragraphs[0][subform][field_text][0][value]' => 'amazing_plugin_test',
-      'field_paragraphs[0][behavior_plugins][test_text_color][text_color]' => $plugin_text,
+      'field_paragraphs[0][subform][test_text_color][text_color]' => $plugin_text,
     ];
     $this->drupalPostForm(NULL, $edit, t('Save and publish'));
     // Asserting that the error message is shown.
@@ -89,7 +89,7 @@ class ParagraphsExperimentalBehaviorsTest extends ParagraphsExperimentalTestBase
     // Updating the text color to an allowed value.
     $plugin_text = 'red';
     $edit = [
-      'field_paragraphs[0][behavior_plugins][test_text_color][text_color]' => $plugin_text,
+      'field_paragraphs[0][subform][test_text_color][text_color]' => $plugin_text,
     ];
     $this->drupalPostForm(NULL, $edit, t('Save and publish'));
     // Assert that the class has been added to the element.
@@ -97,21 +97,21 @@ class ParagraphsExperimentalBehaviorsTest extends ParagraphsExperimentalTestBase
 
     $this->clickLink('Edit');
     // Assert the plugin fields populate the stored values.
-    $this->assertFieldByName('field_paragraphs[0][behavior_plugins][test_text_color][text_color]', $plugin_text);
+    $this->assertFieldByName('field_paragraphs[0][subform][test_text_color][text_color]', $plugin_text);
 
     // Update the value of both plugins.
     $updated_text = 'blue';
     $edit = [
-      'field_paragraphs[0][behavior_plugins][test_text_color][text_color]' => $updated_text,
-      'field_paragraphs[0][behavior_plugins][test_bold_text][bold_text]' => TRUE,
+      'field_paragraphs[0][subform][test_text_color][text_color]' => $updated_text,
+      'field_paragraphs[0][subform][test_bold_text][bold_text]' => TRUE,
     ];
     $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
     $this->assertNoRaw('class="red_plugin_text');
     $this->assertRaw('class="blue_plugin_text bold_plugin_text');
     $this->clickLink('Edit');
     // Assert the plugin fields populate the stored values.
-    $this->assertFieldByName('field_paragraphs[0][behavior_plugins][test_text_color][text_color]', $updated_text);
-    $this->assertFieldByName('field_paragraphs[0][behavior_plugins][test_bold_text][bold_text]', TRUE);
+    $this->assertFieldByName('field_paragraphs[0][subform][test_text_color][text_color]', $updated_text);
+    $this->assertFieldByName('field_paragraphs[0][subform][test_bold_text][bold_text]', TRUE);
 
     // Test plugin applicability. Add a paragraph type.
     $paragraph_type = 'text_paragraph_test';
diff --git a/tests/src/FunctionalJavascript/LoginAdminTrait.php b/tests/src/FunctionalJavascript/LoginAdminTrait.php
new file mode 100644
index 0000000..d5db660
--- /dev/null
+++ b/tests/src/FunctionalJavascript/LoginAdminTrait.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Drupal\Tests\paragraphs\FunctionalJavascript;
+
+/**
+ * Test trait for logging admin in JS tests.
+ */
+trait LoginAdminTrait {
+
+  /**
+   * Creates an user with admin permissions and log in.
+   *
+   * @param array $additional_permissions
+   *   Additional permissions that will be granted to admin user.
+   * @param bool $reset_permissions
+   *   Flag to determine if default admin permissions will be replaced by
+   *   $additional_permissions.
+   *
+   * @return object
+   *   Newly created and logged in user object.
+   */
+  public function loginAsAdmin($additional_permissions = [], $reset_permissions = FALSE) {
+
+    $permissions = [
+      'administer nodes',
+      'administer content types',
+      'administer node fields',
+      'administer paragraphs types',
+      'administer node form display',
+      'administer paragraph fields',
+      'administer paragraph form display',
+    ];
+
+    if ($reset_permissions) {
+      $permissions = $additional_permissions;
+    }
+    elseif (!empty($additional_permissions)) {
+      $permissions = array_merge($permissions, $additional_permissions);
+    }
+
+    $this->admin_user = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($this->admin_user);
+    return $this->admin_user;
+  }
+}
diff --git a/tests/src/FunctionalJavascript/ParagraphsExperimentalEditPerspectivesUiTest.php b/tests/src/FunctionalJavascript/ParagraphsExperimentalEditPerspectivesUiTest.php
new file mode 100644
index 0000000..2fc3a83
--- /dev/null
+++ b/tests/src/FunctionalJavascript/ParagraphsExperimentalEditPerspectivesUiTest.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\Tests\paragraphs\FunctionalJavascript;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+use Drupal\node\Entity\NodeType;
+use Drupal\Tests\paragraphs\FunctionalJavascript\LoginAdminTrait;
+
+/**
+ * Test paragraphs user interface.
+ *
+ * @group paragraphs
+ */
+class ParagraphsExperimentalEditPerspectivesUiTest extends JavascriptTestBase {
+
+  use LoginAdminTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'node',
+    'paragraphs_collection_test',
+    'paragraphs_test',
+    'field',
+    'field_ui',
+    'block',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+  }
+
+  /**
+   * Test paragraphs user interface.
+   */
+  public function testEditPerspectives() {
+
+    $this->loginAsAdmin();
+
+    $page = $this->getSession()->getPage();
+    $this->drupalGet('node/2/edit');;
+    $this->clickLink('Behavior');
+    $style_selector = $page->find('css', 'js-form-item-field-paragraphs-demo-0-behavior-plugins-style-style form-item-field-paragraphs-demo-0-behavior-plugins-style-style');
+    $this->assertTrue($style_selector->isVisible());
+    $this->clickLink('Content');
+    $this->assertFalse($style_selector->isVisible());
+  }
+}
