diff --git a/resources/assets/stylesheets/scss/courseware.scss b/resources/assets/stylesheets/scss/courseware.scss
index 11816754397d5e04185fff149ad8f4855721a462..3640c9ab2ccee02d007a881021b5046e1f1a1718 100644
--- a/resources/assets/stylesheets/scss/courseware.scss
+++ b/resources/assets/stylesheets/scss/courseware.scss
@@ -828,7 +828,12 @@ ribbon end
     .cw-container-header {
         background-color: $content-color-20;
         max-height: 30px;
-        padding: 4px 10px;
+        padding: 4px 10px 4px 22px;
+
+        .cw-container-header-toggle {
+            display: inline-block;
+            width: calc(100% - 40px);
+        }
 
         span {
             color: $base-color;
@@ -935,7 +940,6 @@ form.cw-container-dialog-edit-form {
 /* * *
  block
 * * */
-
 .cw-default-block {
     display: flex;
     flex-flow: row;
@@ -977,7 +981,12 @@ form.cw-container-dialog-edit-form {
 .cw-block-header {
     background-color: $content-color-20;
     max-height: 30px;
-    padding: 4px 10px;
+    padding: 4px 10px 4px 22px;
+
+    .cw-block-header-toggle {
+        display: inline-block;
+        width: calc(100% - 50px);
+    }
 
     span {
         color: $base-color;
@@ -1241,70 +1250,72 @@ label[for="cw-keypoint-color"] {
 /* * * * * * * *
  sortable handle
  * * * * * * * */
-.cw-container-list-sort-mode {
-    .block-ghost {
-        opacity: 0.6;
-    }
-    &.cw-container-list-sort-mode-empty {
-        min-height: 4em;
-        border: dashed thin $content-color-40;
+
+.cw-sortable-handle {
+    display: inline-block;
+    cursor: grab;
+    background-image: url("#{$image-path}/anfasser_24.png");
+    background-repeat: no-repeat;
+    width: 7px;
+    height: 24px;
+    padding-right: 4px;
+    vertical-align: middle;
+    &.cw-sortable-handle-dragging {
+        cursor: grabbing;
     }
 }
-.cw-structural-element-list-sort-mode {
-    list-style: none;
-    padding-left: 0;
 
-    .cw-container-item-sortable {
-        border: solid thin $content-color-40;
-        background-color: $content-color-20;
-        color: $base-color;
-        font-weight: 700;
-        margin-bottom: 0.5em;
-        padding: 0.5em;
+.cw-block-item-sortable {
+    .cw-sortable-handle {
+        position: relative;
+        left: 12px;
     }
-    .container-ghost {
-        opacity: 0.6;
+    .cw-block {
+        margin-top: -32px;
     }
 }
-.cw-structural-element-list-sort-mode,
-.cw-container-list-sort-mode {
+
+.cw-container-item-sortable {
     .cw-sortable-handle {
-        display: inline-block;
-        cursor: grab;
-        background-image: url("#{$image-path}/anfasser_24.png");
-        background-repeat: no-repeat;
-        width: 7px;
-        height: 24px;
-        padding-right: 4px;
-        vertical-align: middle;
+        position: relative;
+        left: 12px;
     }
-    .cw-content-wrapper-active:hover {
-        border: solid thin $base-color;
+    .cw-container {
+        margin-top: -32px;
     }
 }
 
-.cw-container-item-sortable.sortable-chosen {
-        .cw-sortable-handle {
-            cursor: grabbing;
-        }
+.cw-collapsible-open {
+    .cw-container-list-sort-mode {
+        margin-top: 8px;
+    }
 }
 
-.cw-container-sort-buttons {
-    display: block;
+.container-ghost,
+.block-ghost {
+    opacity: 0.6;
 }
 
-.cw-tree-item-wrapper {
-    .cw-sortable-handle {
-        display: inline-block;
-        cursor: grab;
-        background-image: url("#{$image-path}/anfasser_24.png");
-        background-repeat: no-repeat;
-        width: 7px;
-        height: 24px;
-        padding-right: 4px;
-        vertical-align: middle;
+
+.cw-container-wrapper-edit {
+    .cw-structural-element-list {
+        width: 100%;
+        padding: 0;
+        list-style: none;
     }
 }
+
+.cw-block-item-selected {
+    .cw-block-header {
+        font-style: italic;
+    }
+}
+.cw-container-item-selected {
+    .cw-container-header {
+        font-style: italic;
+    }
+}
+
 /* * * * * * * * * * *
  sortable handle end
  * * * * * * * * * * */
diff --git a/resources/vue/components/courseware/CoursewareAccordionContainer.vue b/resources/vue/components/courseware/CoursewareAccordionContainer.vue
index 8e4d0984d1aab3ccb4ff8ec19a30fd83c6bc7b90..02b789131e1285cf97aa1c7d2233dcf37f2ab3ee 100644
--- a/resources/vue/components/courseware/CoursewareAccordionContainer.vue
+++ b/resources/vue/components/courseware/CoursewareAccordionContainer.vue
@@ -7,17 +7,22 @@
         @showEdit="setShowEdit"
         @storeContainer="storeContainer"
         @closeEdit="initCurrentData"
-        @sortBlocks="enableSort"
     >
         <template v-slot:containerContent>
+            <template v-if="showEditMode && canEdit">
+                <span aria-live="assertive" class="assistive-text">{{ assistiveLive }}</span>
+                <span id="operation" class="assistive-text">
+                    {{$gettext('Drücken Sie die Leertaste, um neu anzuordnen')}}
+                </span>
+            </template>
             <courseware-collapsible-box
                 v-for="(section, index) in currentSections"
                 :key="index"
                 :title="section.name"
                 :icon="section.icon"
-                :open="index === 0"
+                :open="index === 0 || sortInSlots.includes(index)"
             >
-                <ul v-if="!sortMode" class="cw-container-accordion-block-list">
+                <ul v-if="!showEditMode" class="cw-container-accordion-block-list">
                     <li v-for="block in section.blocks" :key="block.id" class="cw-block-item">
                         <component
                             :is="component(block)"
@@ -26,33 +31,49 @@
                             :isTeacher="isTeacher"
                         />
                     </li>
-                    <li v-if="showEditMode && canAddElements">
-                        <courseware-block-adder-area :container="container" :section="index" @updateContainerContent="updateContent"/>
-                    </li>
                 </ul>
                 <draggable
-                    v-if="sortMode && canEdit"
+                    v-if="showEditMode && canEdit && !processing"
                     class="cw-container-list-block-list cw-container-list-sort-mode"
                     :class="[section.blocks.length === 0 ? 'cw-container-list-sort-mode-empty' : '']"
-                    tag="ul"
+                    tag="ol"
+                    role="listbox"
                     v-model="section.blocks"
                     v-bind="dragOptions"
                     handle=".cw-sortable-handle"
+                    group="blocks"
                     @start="isDragging = true"
-                    @end="isDragging = false"
+                    @end="dropBlock"
+                    :containerId="container.id"
+                    :sectionId="index"
                 >
-                    <transition-group type="transition" name="flip-blocks" tag="div">
-                        <li v-for="block in section.blocks" :key="block.id" class="cw-block-item cw-block-item-sortable">
-                            <component :is="component(block)" :block="block" :canEdit="canEdit" :isTeacher="isTeacher" />
-                        </li>
-                    </transition-group>
-
+                    <li v-for="block in section.blocks" :key="block.id" class="cw-block-item cw-block-item-sortable">
+                        <span
+                            :class="{ 'cw-sortable-handle-dragging': isDragging }"
+                            class="cw-sortable-handle"
+                            tabindex="0"
+                            role="option"
+                            aria-describedby="operation"
+                            :ref="'sortableHandle' + block.id"
+                            @keydown="keyHandler($event, block.id, index)"
+                        ></span>
+                        <component
+                            :is="component(block)"
+                            :block="block"
+                            :canEdit="canEdit"
+                            :isTeacher="isTeacher"
+                            :class="{ 'cw-block-item-selected': keyboardSelected === block.id}"
+                            :blockId="block.id"
+                        />
+                    </li>
                 </draggable>
+                <template v-if="showEditMode && canAddElements && !processing">
+                    <courseware-block-adder-area :container="container" :section="index" @updateContainerContent="updateContent"/>
+                </template>
+                <div v-if="showEditMode && processing" class="progress-wrapper">
+                    <studip-progress-indicator :description="$gettext('Vorgang wird bearbeitet...')" />
+                </div>
             </courseware-collapsible-box>
-            <div v-if="sortMode && canEdit">
-                <button class="button accept" @click="storeSort"><translate>Sortierung speichern</translate></button>
-                <button class="button cancel"  @click="resetSort"><translate>Sortieren abbrechen</translate></button>
-            </div>
         </template>
         <template v-slot:containerEditDialog>
             <form class="default cw-container-dialog-edit-form" @submit.prevent="">
@@ -127,12 +148,20 @@ export default {
                 disabled: false,
                 ghostClass: "block-ghost"
             },
+            processing: false,
+            keyboardSelected: null,
+            sortInSlots: [],
+            assistiveLive: ''
         };
     },
     computed: {
         ...mapGetters({
             blockById: 'courseware-blocks/byId',
+            viewMode: 'viewMode'
         }),
+        showEditMode() {
+            return this.viewMode === 'edit';
+        },
         blocks() {
             if (!this.container) {
                 return [];
@@ -140,9 +169,6 @@ export default {
 
             return this.container.relationships.blocks.data.map(({ id }) => this.blockById({ id })).filter((a) => a);
         },
-        showEditMode() {
-            return this.$store.getters.viewMode === 'edit';
-        },
         icons() {
             return contentIcons;
         },
@@ -153,6 +179,7 @@ export default {
     methods: {
         ...mapActions({
             updateContainer: 'updateContainer',
+            loadContainer: 'courseware-containers/loadById',
             lockObject: 'lockObject',
             unlockObject: 'unlockObject',
         }),
@@ -181,6 +208,7 @@ export default {
             }
 
             this.currentSections = sections;
+            this.sortInSlots = [];
         },
         setShowEdit(state) {
             this.showEdit = state;
@@ -210,6 +238,7 @@ export default {
             this.currentContainer.attributes.payload.sections.splice(index, 1);
         },
         async storeContainer() {
+            const timeout = setTimeout(() => this.processing = true, 800);
             this.currentContainer.attributes.payload.sections = this.currentContainer.attributes.payload.sections.filter(section => !section.locked);
             this.currentContainer.attributes.payload.sections.forEach(section => {
                 section.blocks = section.blocks.map((block) => {return block.id;});
@@ -220,20 +249,22 @@ export default {
                 structuralElementId: this.currentContainer.relationships['structural-element'].data.id,
             });
             await this.unlockObject({ id: this.currentContainer.id, type: 'courseware-containers' });
+            await this.loadContainer({id : this.container.id });
             this.initCurrentData();
-        },
-        enableSort() {
-            this.sortMode = true;
+            clearTimeout(timeout);
+            this.processing = false;
         },
         async storeSort() {
-            this.sortMode = false;
-            this.storeContainer();
-        },
-        async resetSort() {
-            await this.unlockObject({ id: this.currentContainer.id, type: 'courseware-containers' });
-            this.sortMode = false;
-            this.initCurrentData();
+            if (this.blockedByAnotherUser) {
+                this.companionInfo({ info: this.$gettext('Dieser Abschnitt wird bereits bearbeitet.') });
+                this.loadContainer({id : this.container.id });
+                return false;
+            }
+            await this.lockObject({ id: this.container.id, type: 'courseware-containers' });
+            await this.storeContainer();
+            this.assistiveLive = '';
         },
+
         component(block) {
             if (block.attributes) {
                 return 'courseware-' + block.attributes["block-type"] + '-block';
@@ -244,6 +275,102 @@ export default {
             if (blockAdder.container !== undefined && blockAdder.container.id === this.container.id) {
                 this.initCurrentData();
             }
+        },
+        keyHandler(e, blockId, sectionIndex) {
+            switch (e.keyCode) {
+                case 27: // esc
+                    this.abortKeyboardSorting(blockId, sectionIndex);
+                    break;
+                case 32: // space
+                    e.preventDefault();
+                    if (this.keyboardSelected) {
+                        this.storeKeyboardSorting(blockId, sectionIndex);
+                    } else {
+                        this.keyboardSelected = blockId;
+                        const block = this.blockById({id: blockId});
+                        const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId);
+                        this.assistiveLive = 
+                            this.$gettextInterpolate(
+                                this.$gettext('%{blockTitle} Block ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.')
+                                , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.currentSections[sectionIndex].blocks.length}
+                            );
+                    }
+                    break;
+            }
+            if (this.keyboardSelected) {
+                switch (e.keyCode) {
+                    case 9: //tab
+                        this.abortKeyboardSorting(blockId, sectionIndex);
+                        break;
+                    case 38: // up
+                        e.preventDefault();
+                        this.moveItemUp(blockId, sectionIndex);
+                        break;
+                    case 40: // down
+                        e.preventDefault();
+                        this.moveItemDown(blockId, sectionIndex);
+                        break;
+                }
+            }
+        },
+        moveItemUp(blockId, sectionIndex) {
+            const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId);
+            const block = this.blockById({id: blockId});
+            if (currentIndex !== 0) {
+                const newPos = currentIndex - 1;
+                this.currentSections[sectionIndex].blocks.splice(newPos, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]);
+                this.assistiveLive = 
+                    this.$gettextInterpolate(
+                        this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.')
+                        , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.currentSections[sectionIndex].blocks.length}
+                    );
+            } else if (sectionIndex !== 0) {
+                const newSectionIndex = sectionIndex - 1;
+                if (!this.sortInSlots.includes(newSectionIndex)) {
+                    this.sortInSlots.push(newSectionIndex);
+                }
+                this.currentSections[newSectionIndex].blocks.push(this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]);
+            }
+        },
+        moveItemDown(blockId, sectionIndex) {
+            const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId);
+            const block = this.blockById({id: blockId});
+            if (this.currentSections[sectionIndex].blocks.length - 1 > currentIndex) {
+                const newPos = currentIndex + 1;
+                this.currentSections[sectionIndex].blocks.splice(newPos, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]);
+                this.assistiveLive = 
+                    this.$gettextInterpolate(
+                        this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.')
+                        , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.currentSections[sectionIndex].blocks.length}
+                    );
+            } else if (this.currentSections.length - 1 > sectionIndex) {
+                const newSectionIndex = sectionIndex + 1;
+                if (!this.sortInSlots.includes(newSectionIndex)) {
+                    this.sortInSlots.push(newSectionIndex);
+                }
+                this.currentSections[newSectionIndex].blocks.splice(0, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]);
+            }
+        },
+        abortKeyboardSorting(blockId, sectionIndex) {
+            const block = this.blockById({id: blockId});
+            this.keyboardSelected = null;
+            this.assistiveLive = 
+                this.$gettextInterpolate(
+                    this.$gettext('%{blockTitle} Block, Neuordnung abgebrochen')
+                    , {blockTitle: block.attributes.title}
+                );
+            this.initCurrentData();
+        },
+        storeKeyboardSorting(blockId, sectionIndex) {
+            const block = this.blockById({id: blockId});
+            const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId);
+            this.keyboardSelected = null;
+            this.assistiveLive = 
+                this.$gettextInterpolate(
+                    this.$gettext('%{blockTitle} Block, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.')
+                    , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.currentSections[sectionIndex].blocks.length}
+                );
+            this.storeSort();
         }
     },
     watch: {
@@ -251,6 +378,16 @@ export default {
             if (!this.showEdit) {
                 this.initCurrentData();
             }
+        },
+        currentSections: {
+            handler() {
+                if (this.keyboardSelected) {
+                this.$nextTick(() => {
+                    this.$refs['sortableHandle' + this.keyboardSelected][0].focus();
+                });
+                }   
+            },
+            deep: true
         }
     }
 };
diff --git a/resources/vue/components/courseware/CoursewareActionWidget.vue b/resources/vue/components/courseware/CoursewareActionWidget.vue
index f4d690683aa4b0c1ea723a4af2dbc9f20a250306..c6be07da16c307704f87a68f65c9e57b960e4679 100644
--- a/resources/vue/components/courseware/CoursewareActionWidget.vue
+++ b/resources/vue/components/courseware/CoursewareActionWidget.vue
@@ -22,11 +22,6 @@
                         {{ $gettext('Sperre aufheben') }}
                     </button>
                 </li>
-                <li v-if="canEdit && !blockedByAnotherUser" class="cw-action-widget-sort">
-                    <button @click="sortContainers">
-                        {{ $gettext('Abschnitte sortieren') }}
-                    </button>
-                </li>
                 <li v-if="canEdit" class="cw-action-widget-add">
                     <button @click="addElement">
                         {{ $gettext('Seite hinzufügen') }}
@@ -122,7 +117,6 @@ export default {
             showElementLinkDialog: 'showElementLinkDialog',
             showElementRemoveLockDialog: 'showElementRemoveLockDialog',
             updateShowSuggestOerDialog: 'updateShowSuggestOerDialog',
-            setStructuralElementSortMode: 'setStructuralElementSortMode',
             companionInfo: 'companionInfo',
             addBookmark: 'addBookmark',
             lockObject: 'lockObject',
@@ -155,26 +149,6 @@ export default {
         async removeElementLock() {
             this.showElementRemoveLockDialog(true);
         },
-        async sortContainers() {
-            await this.loadStructuralElement(this.currentId);
-            if (this.blockedByAnotherUser) {
-                this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
-
-                return false;
-            }
-            try {
-                await this.lockObject({ id: this.currentId, type: 'courseware-structural-elements' });
-            } catch (error) {
-                if (error.status === 409) {
-                    this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
-                } else {
-                    console.log(error);
-                }
-
-                return false;
-            }
-            this.setStructuralElementSortMode(true);
-        },
         async deleteElement() {
             await this.loadStructuralElement(this.currentId);
             if (this.blockedByAnotherUser) {
diff --git a/resources/vue/components/courseware/CoursewareBlockadderItem.vue b/resources/vue/components/courseware/CoursewareBlockadderItem.vue
index 6339e0dbae76f18ad4a98a0a1da9d737bcd36b43..c882cd2569682c9e71c2234b5ba83794dbd348a1 100644
--- a/resources/vue/components/courseware/CoursewareBlockadderItem.vue
+++ b/resources/vue/components/courseware/CoursewareBlockadderItem.vue
@@ -30,6 +30,7 @@ export default {
     computed: {
         ...mapGetters({
             blockAdder: 'blockAdder',
+            blockById: 'courseware-blocks/byId'
         }),
     },
     methods: {
@@ -41,6 +42,7 @@ export default {
             updateContainer: 'updateContainer',
             lockObject: 'lockObject',
             unlockObject: 'unlockObject',
+            loadBlock: 'courseware-blocks/loadById',
         }),
         async addBlock() {
             if (Object.keys(this.blockAdder).length !== 0) {
diff --git a/resources/vue/components/courseware/CoursewareContainerActions.vue b/resources/vue/components/courseware/CoursewareContainerActions.vue
index fdea003c0100850385b78c9883f0561bc05cdbb6..4795984797de6435cd486085d5a01cf586979381 100644
--- a/resources/vue/components/courseware/CoursewareContainerActions.vue
+++ b/resources/vue/components/courseware/CoursewareContainerActions.vue
@@ -5,7 +5,6 @@
             :context="container.attributes.title"
             @editContainer="editContainer"
             @deleteContainer="deleteContainer"
-            @sortBlocks="sortBlocks"
             @removeLock="removeLock"
         />
     </div>
@@ -42,8 +41,7 @@ export default {
                 if (this.container.attributes["container-type"] !== 'list') {
                     menuItems.push({ id: 1, label: this.$gettext('Abschnitt bearbeiten'), icon: 'edit', emit: 'editContainer' });
                 }
-                menuItems.push({ id: 2, label: this.$gettext('Blöcke sortieren'), icon: 'arr_1sort', emit: 'sortBlocks' });
-                menuItems.push({ id: 3, label: this.$gettext('Abschnitt löschen'), icon: 'trash', emit: 'deleteContainer' });
+                menuItems.push({ id: 2, label: this.$gettext('Abschnitt löschen'), icon: 'trash', emit: 'deleteContainer' });
             }
 
             if (this.blocked && this.blockedByAnotherUser && this.userIsTeacher) {
@@ -72,9 +70,6 @@ export default {
         deleteContainer() {
             this.$emit('deleteContainer');
         },
-        sortBlocks() {
-            this.$emit('sortBlocks');
-        },
         removeLock() {
             this.$emit('removeLock');
         }
diff --git a/resources/vue/components/courseware/CoursewareDefaultBlock.vue b/resources/vue/components/courseware/CoursewareDefaultBlock.vue
index 14ab304ec61394975a38038b5cceb7db59b517ba..6c85484c036685b693248595f56de7881de3515b 100644
--- a/resources/vue/components/courseware/CoursewareDefaultBlock.vue
+++ b/resources/vue/components/courseware/CoursewareDefaultBlock.vue
@@ -2,17 +2,18 @@
     <div v-if="block.attributes.visible || canEdit" class="cw-default-block">
         <div class="cw-content-wrapper" :class="[showEditMode ? 'cw-content-wrapper-active' : '']">
             <header v-if="showEditMode" class="cw-block-header">
-                <span class="cw-sortable-handle"></span>
-                <studip-icon v-if="!block.attributes.visible" shape="visibility-invisible" />
-                <studip-icon v-if="blockedByAnotherUser" shape="lock-locked" />
-                <span>{{ blockTitle }}</span>
-                <span v-if="blockedByAnotherUser" class="cw-default-block-blocker-warning">
-                    | {{ $gettextInterpolate($gettext('wird im Moment von %{ userName } bearbeitet'), { userName: this.blockingUserName }) }}
-                </span>
-
-                <span v-if="!block.attributes.visible" class="cw-default-block-invisible-info">
-                    | {{ $gettext('unsichtbar für Nutzende ohne Schreibrecht') }}
-                </span>
+                <a href="#" class="cw-block-header-toggle" :aria-expanded="isOpen" @click.prevent="isOpen = !isOpen">
+                    <studip-icon :shape="isOpen ? 'arr_1down' : 'arr_1right'" />
+                    <span>{{ blockTitle }}</span>
+                    <studip-icon v-if="blockedByAnotherUser" shape="lock-locked" />
+                    <span v-if="blockedByAnotherUser" class="cw-default-block-blocker-warning">
+                        {{ $gettextInterpolate($gettext('wird im Moment von %{ userName } bearbeitet'), { userName: this.blockingUserName }) }}
+                    </span>
+                    <studip-icon v-if="!block.attributes.visible" shape="visibility-invisible" />
+                    <span v-if="!block.attributes.visible" class="cw-default-block-invisible-info">
+                        {{ $gettext('unsichtbar für Nutzende ohne Schreibrecht') }}
+                    </span>
+                </a>
                 <courseware-block-actions
                     :block="block"
                     :canEdit="canEdit"
@@ -24,30 +25,32 @@
                     @removeLock="displayRemoveLockDialog()"
                 />
             </header>
-            <div v-if="showContent" class="cw-block-content">
-                <slot name="content" />
-            </div>
-            <div v-if="showFeatures" class="cw-block-features cw-block-features-default">
-                <courseware-block-export-options
-                    v-if="canEdit && showExportOptions"
-                    :block="block"
-                    @close="displayFeature(false)"
-                />
-                <courseware-block-edit
-                    v-if="canEdit && showEdit"
-                    :block="block"
-                    @store="prepareStoreEdit"
-                    @close="closeEdit"
-                >
-                    <template #edit>
-                        <slot name="edit" />
-                    </template>
-                </courseware-block-edit>
-                <courseware-block-info v-if="showInfo" :block="block" @close="displayFeature(false)">
-                    <template #info>
-                        <slot name="info" />
-                    </template>
-                </courseware-block-info>
+            <div v-show="isOpen">
+                <div v-if="showContent" class="cw-block-content">
+                    <slot name="content" />
+                </div>
+                <div v-if="showFeatures" class="cw-block-features cw-block-features-default">
+                    <courseware-block-export-options
+                        v-if="canEdit && showExportOptions"
+                        :block="block"
+                        @close="displayFeature(false)"
+                    />
+                    <courseware-block-edit
+                        v-if="canEdit && showEdit"
+                        :block="block"
+                        @store="prepareStoreEdit"
+                        @close="closeEdit"
+                    >
+                        <template #edit>
+                            <slot name="edit" />
+                        </template>
+                    </courseware-block-edit>
+                    <courseware-block-info v-if="showInfo" :block="block" @close="displayFeature(false)">
+                        <template #info>
+                            <slot name="info" />
+                        </template>
+                    </courseware-block-info>
+                </div>
             </div>
         </div>
         <div v-if="discussView" class="cw-discuss-wrapper">
@@ -130,6 +133,7 @@ export default {
             textDeleteAlert: this.$gettext('Möchten Sie diesen Block wirklich löschen?'),
             textRemoveLockTitle: this.$gettext('Sperre aufheben'),
             textRemoveLockAlert: this.$gettext('Möchten Sie die Sperre dieses Blocks wirklich aufheben?'),
+            isOpen: true,
         };
     },
     computed: {
@@ -302,6 +306,9 @@ export default {
             this.showDeleteDialog = false;
         },
         async executeDelete() {
+            this.showDeleteDialog = false;
+            this.displayFeature(false);
+            this.$emit('closeEdit');
             await this.loadBlock({ id: this.block.id, options: { include: 'edit-blocker' } });
             if (this.blockedByAnotherUser) {
                 this.companionInfo({
diff --git a/resources/vue/components/courseware/CoursewareDefaultContainer.vue b/resources/vue/components/courseware/CoursewareDefaultContainer.vue
index 70a6da708f0f66215174ea40408d847e2b221fe6..aa1923bfabc90a13c0991606232d92fd880bc5ff 100644
--- a/resources/vue/components/courseware/CoursewareDefaultContainer.vue
+++ b/resources/vue/components/courseware/CoursewareDefaultContainer.vue
@@ -4,22 +4,29 @@
         :class="['cw-container-colspan-' + colSpan, showEditMode && canEdit ? 'cw-container-active' : '']"
     >
         <div class="cw-container-content">
-            <header v-if="showEditMode && canEdit" class="cw-container-header">
-                <studip-icon v-if="blockedByAnotherUser" shape="lock-locked" />
-                <span>{{ container.attributes.title }} ({{container.attributes.width}})</span>
-                <span v-if="blockedByAnotherUser" class="cw-default-container-blocker-warning">
-                    | {{ $gettextInterpolate($gettext('wird im Moment von %{ userName } bearbeitet'), { userName: this.blockingUserName }) }}
-                </span>
+            <header v-if="showEditMode && canEdit" class="cw-container-header" :class="{ 'cw-container-header-open': isOpen }">
+                <a href="#" class="cw-container-header-toggle" :aria-expanded="isOpen" @click.prevent="isOpen = !isOpen">
+                    <studip-icon :shape="isOpen ? 'arr_1down' : 'arr_1right'" />
+                    <span>{{ container.attributes.title }} ({{container.attributes.width}})</span>
+                    <studip-icon v-if="blockedByAnotherUser" shape="lock-locked" />
+                    <span v-if="blockedByAnotherUser" class="cw-default-container-blocker-warning">
+                        {{ $gettextInterpolate($gettext('wird im Moment von %{ userName } bearbeitet'), { userName: this.blockingUserName }) }}
+                    </span>
+                </a>
                 <courseware-container-actions
                     :canEdit="canEdit"
                     :container="container"
                     @editContainer="displayEditDialog"
                     @deleteContainer="displayDeleteDialog"
-                    @sortBlocks="sortBlocks"
                     @removeLock="displayRemoveLockDialog"
                 />
             </header>
-            <div class="cw-block-wrapper" :class="{ 'cw-block-wrapper-active': showEditMode }">
+            <div v-show="isOpen"
+                class="cw-block-wrapper"
+                :class="{
+                    'cw-block-wrapper-active': showEditMode,
+                }"
+            >
                 <slot name="containerContent"></slot>
             </div>
 
@@ -93,15 +100,17 @@ export default {
             textDeleteAlert: this.$gettext('Möchten Sie diesen Abschnitt wirklich löschen?'),
             textRemoveLockTitle: this.$gettext('Sperre aufheben'),
             textRemoveLockAlert: this.$gettext('Möchten Sie die Sperre dieses Abschnitts wirklich aufheben?'),
+            isOpen: true,
         };
     },
     computed: {
         ...mapGetters({
             userId: 'userId',
             userById: 'users/byId',
+            viewMode: 'viewMode'
         }),
         showEditMode() {
-            return this.$store.getters.viewMode === 'edit';
+            return this.viewMode === 'edit';
         },
         colSpan() {
             return this.container.attributes.payload.colspan ? this.container.attributes.payload.colspan : 'full';
@@ -223,16 +232,6 @@ export default {
             }
             this.showDeleteDialog = false;
         },
-        async sortBlocks() {
-            await this.loadContainer({ id: this.container.id, options: { include: 'edit-blocker' } });
-            if (this.blockedByAnotherUser) {
-                this.companionInfo({ info: this.$gettext('Dieser Abschnitt wird bereits bearbeitet.') });
-
-                return false;
-            }
-            await this.lockObject({ id: this.container.id, type: 'courseware-containers' });
-            this.$emit('sortBlocks');
-        },
         displayRemoveLockDialog() {
             this.showRemoveLockDialog = true;
         },
diff --git a/resources/vue/components/courseware/CoursewareListContainer.vue b/resources/vue/components/courseware/CoursewareListContainer.vue
index 8e889f86c8692712f21cc36d10049cc717517978..fea688c7b61f091c3e16d1189c4f7854b3b1182a 100644
--- a/resources/vue/components/courseware/CoursewareListContainer.vue
+++ b/resources/vue/components/courseware/CoursewareListContainer.vue
@@ -5,37 +5,62 @@
         :canEdit="canEdit"
         :isTeacher="isTeacher"
         @storeContainer="storeContainer"
-        @sortBlocks="enableSort"
     >
         <template v-slot:containerContent>
-            <ul v-if="!sortMode"  class="cw-container-list-block-list">
+            <ul v-if="!showEditMode"  class="cw-container-list-block-list">
                 <li v-for="block in blocks" :key="block.id" class="cw-block-item">
                     <component :is="component(block)" :block="block" :canEdit="canEdit" :isTeacher="isTeacher" />
                 </li>
-                <li v-if="showEditMode && canEdit && canAddElements"><courseware-block-adder-area :container="container" :section="0" /></li>
             </ul>
-            <draggable
-                v-if="sortMode && canEdit"
-                class="cw-container-list-block-list cw-container-list-sort-mode"
-                tag="ul"
-                v-model="blockList"
-                v-bind="dragOptions"
-                handle=".cw-sortable-handle"
-                @start="isDragging = true"
-                @end="isDragging = false"
-            >
-                <transition-group type="transition" name="flip-blocks">
-                    <li v-for="block in blockList" :key="block.id" class="cw-block-item cw-block-item-sortable">
-                        <component :is="component(block)" :block="block" :canEdit="canEdit" :isTeacher="isTeacher" />
+            <template v-if="showEditMode && !processing">
+                <span aria-live="assertive" class="assistive-text">{{ assistiveLive }}</span>
+                <span id="operation" class="assistive-text">
+                    {{$gettext('Drücken Sie die Leertaste, um neu anzuordnen')}}
+                </span>
+                <draggable
+                    v-if="showEditMode && canEdit"
+                    class="cw-container-list-block-list cw-container-list-sort-mode"
+                    tag="ol"
+                    role="listbox"
+                    v-model="blockList"
+                    v-bind="dragOptions"
+                    handle=".cw-sortable-handle"
+                    group="blocks"
+                    @start="isDragging = true"
+                    @end="dropBlock"
+                    ref="sortables"
+                    :containerId="container.id"
+                    sectionId="0"
+                >
+                    <li
+                        v-for="block in blockList"
+                        :key="block.id"
+                        class="cw-block-item cw-block-item-sortable"
+                    >
+                        <span
+                            :class="{ 'cw-sortable-handle-dragging': isDragging }"
+                            class="cw-sortable-handle"
+                            tabindex="0"
+                            role="option"
+                            aria-describedby="operation"
+                            :ref="'sortableHandle' + block.id"
+                            @keydown="keyHandler($event, block.id)"
+                        ></span>
+                        <component
+                            :is="component(block)"
+                            :block="block"
+                            :canEdit="canEdit"
+                            :isTeacher="isTeacher"
+                            :class="{ 'cw-block-item-selected': keyboardSelected === block.id}"
+                            :blockId="block.id"
+                        />
                     </li>
-                </transition-group>
-
-            </draggable>
-            <div v-if="sortMode && canEdit">
-                <button class="button accept" @click="storeSort"><translate>Sortierung speichern</translate></button>
-                <button class="button cancel"  @click="resetSort"><translate>Sortieren abbrechen</translate></button>
+                </draggable>
+                <courseware-block-adder-area :container="container" :section="0" />
+            </template>
+            <div v-if="showEditMode && processing" class="progress-wrapper" :style="{ height: contentHeight + 'px' }">
+                <studip-progress-indicator :description="$gettext('Vorgang wird bearbeitet...')" />
             </div>
-
         </template>
     </courseware-default-container>
 </template>
@@ -43,6 +68,7 @@
 <script>
 import ContainerComponents from './container-components.js';
 import containerMixin from '../../mixins/courseware/container.js';
+import StudipProgressIndicator from '../StudipProgressIndicator.vue';
 import draggable from 'vuedraggable';
 import { mapActions, mapGetters } from 'vuex';
 
@@ -50,7 +76,8 @@ export default {
     name: 'courseware-list-container',
     mixins: [containerMixin],
     components: Object.assign(ContainerComponents, {
-        draggable
+        draggable,
+        StudipProgressIndicator
     }),
     props: {
         container: Object,
@@ -60,7 +87,6 @@ export default {
     },
     data() {
         return {
-            sortMode: false,
             isDragging: false,
             dragOptions: {
                 animation: 0,
@@ -69,12 +95,33 @@ export default {
                 ghostClass: "block-ghost"
             },
             blockList: [],
+            processing: false,
+            contentHeight: 0,
+            keyboardSelected: null,
+            assistiveLive: ''
         };
     },
     computed: {
         ...mapGetters({
             blockById: 'courseware-blocks/byId',
+            containerById: 'courseware-containers/byId',
+            viewMode: 'viewMode'
         }),
+        blocked() {
+            return this.container?.relationships?.['edit-blocker']?.data !== null;
+        },
+        blockerId() {
+            return this.blocked ? this.container?.relationships?.['edit-blocker']?.data?.id : null;
+        },
+        blockedByThisUser() {
+            return this.blocked && this.userId === this.blockerId;
+        },
+        blockedByAnotherUser() {
+            return this.blocked && this.userId !== this.blockerId;
+        },
+        showEditMode() {
+            return this.viewMode === 'edit';
+        },
         blocks() {
             if (!this.container) {
                 return [];
@@ -87,28 +134,31 @@ export default {
 
             return sortedBlocks.concat(unallocatedBlocks);
         },
-        showEditMode() {
-            return this.$store.getters.viewMode === 'edit';
-        },
     },
     methods: {
         ...mapActions({
             updateContainer: 'updateContainer',
+            loadContainer: 'courseware-containers/loadById',
             lockObject: 'lockObject',
             unlockObject: 'unlockObject',
+            companionInfo: 'companionInfo'
         }),
         storeContainer(data) {
         },
         initCurrentData() {
             this.blockList = this.blocks;
         },
-        enableSort() {
-            this.initCurrentData();
-            this.sortMode = true;
-        },
         async storeSort() {
-            this.sortMode = false;
-
+            this.contentHeight = this.$refs.sortables.$el.offsetHeight;
+            const timeout = setTimeout(() => this.processing = true, 800);
+            if (this.blockedByAnotherUser) {
+                this.companionInfo({ info: this.$gettext('Dieser Abschnitt wird bereits bearbeitet.') });
+                clearTimeout(timeout);
+                this.processing = false;
+                this.loadContainer({id : this.container.id });
+                return false;
+            }
+            await this.lockObject({ id: this.container.id, type: 'courseware-containers' });
             let currentContainer = this.container;
             currentContainer.attributes.payload.sections[0].blocks = this.blockList.map(block => {return block.id});
             await this.updateContainer({
@@ -116,12 +166,11 @@ export default {
                 structuralElementId: currentContainer.relationships['structural-element'].data.id,
             });
             await this.unlockObject({ id: this.container.id, type: 'courseware-containers' });
+            await this.loadContainer({id : this.container.id });
             this.initCurrentData();
-        },
-        async resetSort() {
-            await this.unlockObject({ id: this.container.id, type: 'courseware-containers' });
-            this.sortMode = false;
-            this.blockList = this.blocks;
+            clearTimeout(timeout);
+            this.processing = false;
+            this.assistiveLive = '';
         },
         component(block) {
             if (block.attributes["block-type"] !== undefined) {
@@ -129,9 +178,107 @@ export default {
             }
             return null;
         },
+        keyHandler(e, blockId) {
+            switch (e.keyCode) {
+                case 27: // esc
+                    this.abortKeyboardSorting(blockId);
+                    break;
+                case 32: // space
+                    e.preventDefault();
+                    if (this.keyboardSelected) {
+                        this.storeKeyboardSorting(blockId);
+                    } else {
+                        this.keyboardSelected = blockId;
+                        const block = this.blockById({id: blockId});
+                        const index = this.blockList.findIndex(b => b.id === block.id);
+                        this.assistiveLive = 
+                            this.$gettextInterpolate(
+                                this.$gettext('%{blockTitle} Block ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.')
+                                , {blockTitle: block.attributes.title, pos: index + 1, listLength: this.blockList.length}
+                            );
+                    }
+                    break;
+            }
+            if (this.keyboardSelected) {
+                switch (e.keyCode) {
+                    case 9: //tab
+                        this.abortKeyboardSorting(blockId);
+                        break;
+                    case 38: // up
+                        e.preventDefault();
+                        this.moveItemUp(blockId);
+                        break;
+                    case 40: // down
+                        e.preventDefault();
+                        this.moveItemDown(blockId);
+                        break;
+                }
+            }
+        },
+        moveItemUp(blockId) {
+            const currentIndex = this.blockList.findIndex(block => block.id === blockId);
+            if (currentIndex !== 0) {
+                const block = this.blockById({id: blockId});
+                const newPos = currentIndex - 1;
+                this.blockList.splice(newPos, 0, this.blockList.splice(currentIndex, 1)[0]);
+                this.assistiveLive = 
+                    this.$gettextInterpolate(
+                        this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.')
+                        , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.blockList.length}
+                    );
+            }
+        },
+        moveItemDown(blockId) {
+            const currentIndex = this.blockList.findIndex(block => block.id === blockId);
+            if (this.blockList.length - 1 > currentIndex) {
+                const block = this.blockById({id: blockId});
+                const newPos = currentIndex + 1;
+                this.blockList.splice(newPos, 0, this.blockList.splice(currentIndex, 1)[0]);
+                this.assistiveLive = 
+                    this.$gettextInterpolate(
+                        this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.')
+                        , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.blockList.length}
+                    );
+            }
+        },
+        abortKeyboardSorting(blockId) {
+            const block = this.blockById({id: blockId});
+            this.keyboardSelected = null;
+            this.assistiveLive = 
+                this.$gettextInterpolate(
+                    this.$gettext('%{blockTitle} Block, Neuordnung abgebrochen')
+                    , {blockTitle: block.attributes.title}
+                );
+            this.initCurrentData();
+        },
+        storeKeyboardSorting(blockId) {
+            const block = this.blockById({id: blockId});
+            const currentIndex = this.blockList.findIndex(block => block.id === blockId);
+            this.keyboardSelected = null;
+            this.assistiveLive = 
+                this.$gettextInterpolate(
+                    this.$gettext('%{blockTitle} Block, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.')
+                    , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.blockList.length}
+                );
+            this.storeSort();
+        }
     },
     mounted() {
         this.initCurrentData();
     },
+    watch: {
+        blocks() {
+            this.initCurrentData();
+        },
+        blockList() {
+            if (this.keyboardSelected) {
+                this.$nextTick(() => {
+                    const selected = this.$refs['sortableHandle' + this.keyboardSelected][0];
+                    selected.focus();
+                    selected.scrollIntoView({behavior: "smooth", block: "center"});
+                });
+            }
+        }
+    }
 };
 </script>
diff --git a/resources/vue/components/courseware/CoursewareRibbon.vue b/resources/vue/components/courseware/CoursewareRibbon.vue
index 119448c7f061fdba4392c6c7745425fdbe299c13..066a56fc69f2b2d0d3d91c47482132ed262251c5 100644
--- a/resources/vue/components/courseware/CoursewareRibbon.vue
+++ b/resources/vue/components/courseware/CoursewareRibbon.vue
@@ -41,6 +41,7 @@
                 :style="{ maxHeight: maxHeight + 'px' }"
                 :canEdit="canEdit"
                 @deactivate="deactivateToolbar"
+                @blockAdded="$emit('blockAdded')"
             />
         </header>
         <div v-if="stickyRibbon" class="cw-ribbon-sticky-bottom"></div>
diff --git a/resources/vue/components/courseware/CoursewareRibbonToolbar.vue b/resources/vue/components/courseware/CoursewareRibbonToolbar.vue
index 7d6a779dadadafcb3246d6aa873f3a808dd86aec..d90616c78f1e2aa9ba298d31be8f88af05b06d9a 100644
--- a/resources/vue/components/courseware/CoursewareRibbonToolbar.vue
+++ b/resources/vue/components/courseware/CoursewareRibbonToolbar.vue
@@ -33,6 +33,7 @@
                             <courseware-tools-blockadder
                                 id="cw-ribbon-tool-blockadder"
                                 :stickyRibbon="stickyRibbon"
+                                @blockAdded="$emit('blockAdded')"
                             />
                         </courseware-tab>
                         <courseware-tab
diff --git a/resources/vue/components/courseware/CoursewareStructuralElement.vue b/resources/vue/components/courseware/CoursewareStructuralElement.vue
index 76a949d04ee9f904eb35aba4f4d528f24bb394ee..c45e8532b922a34da81c90f4e693347672792f13 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElement.vue
+++ b/resources/vue/components/courseware/CoursewareStructuralElement.vue
@@ -7,7 +7,7 @@
                 v-if="validContext"
             >
                 <div class="cw-structural-element-content" v-if="structuralElement">
-                    <courseware-ribbon :canEdit="canEdit && canAddElements" :isContentBar="true">
+                    <courseware-ribbon :canEdit="canEdit && canAddElements" :isContentBar="true" @blockAdded="updateContainerList">
                         <template #buttons>
                             <router-link v-if="prevElement" :to="'/structural_element/' + prevElement.id">
                                 <div class="cw-ribbon-button cw-ribbon-button-prev" :title="textRibbon.perv" />
@@ -68,7 +68,7 @@
                     </courseware-ribbon>
 
                     <div
-                        v-if="canVisit && !sortMode && !isLink"
+                        v-if="canVisit && !editView && !isLink"
                         class="cw-container-wrapper"
                         :class="{
                             'cw-container-wrapper-consume': consumeMode,
@@ -139,35 +139,50 @@
                             class="cw-container-item"
                         />
                     </div>
-                    <div v-if="canVisit && canEdit && sortMode" class="cw-container-wrapper-sort-mode">
-                        <draggable
-                            class="cw-structural-element-list-sort-mode"
-                            tag="ul"
-                            v-model="containerList"
-                            v-bind="dragOptions"
-                            handle=".cw-sortable-handle"
-                            @start="isDragging = true"
-                            @end="isDragging = false"
-                        >
-                            <transition-group type="transition" name="flip-containers">
+                    <div v-if="canVisit && canEdit && editView" class="cw-container-wrapper cw-container-wrapper-edit">
+                        <template v-if="!processing">
+                            <span aria-live="assertive" class="assistive-text">{{ assistiveLive }}</span>
+                            <span id="operation" class="assistive-text">
+                                {{$gettext('Drücken Sie die Leertaste, um neu anzuordnen')}}
+                            </span>
+                            <draggable
+                                class="cw-structural-element-list"
+                                tag="ol"
+                                role="listbox"
+                                v-model="containerList"
+                                v-bind="dragOptions"
+                                handle=".cw-sortable-handle"
+                                @start="isDragging = true"
+                                @end="dropContainer"
+                            >
                                 <li
                                     v-for="container in containerList"
                                     :key="container.id"
                                     class="cw-container-item-sortable"
                                 >
-                                    <span class="cw-sortable-handle"></span>
-                                    <span>{{ container.attributes.title }} ({{ container.attributes.width }})</span>
+                                    <span
+                                        :class="{ 'cw-sortable-handle-dragging': isDragging }"
+                                        class="cw-sortable-handle"
+                                        tabindex="0"
+                                        role="option"
+                                        aria-describedby="operation"
+                                        :ref="'sortableHandle' + container.id"
+                                        @keydown="keyHandler($event, container.id)"
+                                    ></span>
+                                    <component
+                                        :is="containerComponent(container)"
+                                        :container="container"
+                                        :canEdit="canEdit"
+                                        :canAddElements="canAddElements"
+                                        :isTeacher="userIsTeacher"
+                                        class="cw-container-item"
+                                        ref="containers"
+                                        :class="{ 'cw-container-item-selected': keyboardSelected === container.id}"
+                                    />
                                 </li>
-                            </transition-group>
-                        </draggable>
-                        <div class="cw-container-sort-buttons">
-                            <button class="button accept" @click="storeSort">
-                                <translate>Sortierung speichern</translate>
-                            </button>
-                            <button class="button cancel" @click="resetSort">
-                                <translate>Sortieren abbrechen</translate>
-                            </button>
-                        </div>
+                            </draggable>
+                        </template>
+                        <studip-progress-indicator v-if="processing" :description="$gettext('Vorgang wird bearbeitet...')" />
                     </div>
                     <div
                         v-if="!canVisit"
@@ -732,6 +747,9 @@ export default {
                 'expire-date': ''
             },
             deletingPreviewImage: false,
+            processing: false,
+            keyboardSelected: null,
+            assistiveLive: ''
         };
     },
 
@@ -763,7 +781,6 @@ export default {
             exportState: 'exportState',
             exportProgress: 'exportProgress',
             userId: 'userId',
-            sortMode: 'structuralElementSortMode',
             viewMode: 'viewMode',
             taskById: 'courseware-tasks/byId',
             userById: 'users/byId',
@@ -988,12 +1005,6 @@ export default {
                         icon: 'edit',
                         emit: 'editCurrentElement',
                     });
-                    menu.push({
-                        id: 2,
-                        label: this.$gettext('Abschnitte sortieren'),
-                        icon: 'arr_1sort',
-                        emit: 'sortContainers',
-                    });
                 }
                 if (this.blockedByAnotherUser && this.userIsTeacher) {
                     menu.push({
@@ -1335,7 +1346,6 @@ export default {
             showElementRemoveLockDialog: 'showElementRemoveLockDialog',
             updateShowSuggestOerDialog: 'updateShowSuggestOerDialog',
             updateContainer: 'updateContainer',
-            setStructuralElementSortMode: 'setStructuralElementSortMode',
             sortContainersInStructualElements: 'sortContainersInStructualElements',
             loadTask: 'loadTask',
             loadStructuralElement: 'loadStructuralElement',
@@ -1410,26 +1420,6 @@ export default {
                 case 'setBookmark':
                     this.setBookmark();
                     break;
-                case 'sortContainers':
-                    await this.loadStructuralElement(this.currentId);
-                    if (this.blockedByAnotherUser) {
-                        this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
-
-                        return false;
-                    }
-                    try {
-                        await this.lockObject({ id: this.currentId, type: 'courseware-structural-elements' });
-                    } catch (error) {
-                        if (error.status === 409) {
-                            this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
-                        } else {
-                            console.log(error);
-                        }
-
-                        return false;
-                    }
-                    this.enableSortContainers();
-                    break;
                 case 'linkElement':
                     this.showElementLinkDialog(true);
                     break;
@@ -1516,23 +1506,41 @@ export default {
             this.initCurrent();
         },
 
-        enableSortContainers() {
-            this.setStructuralElementSortMode(true);
+        dropContainer() {
+            this.isDragging = false;
+            this.storeSort();
         },
 
-        storeSort() {
-            this.setStructuralElementSortMode(false);
+        async storeSort() {
+            const timeout = setTimeout(() => this.processing = true, 800);
+            if (this.blockedByAnotherUser) {
+                this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
+                clearTimeout(timeout);
+                this.processing = false;
+                return false;
+            }
+            try {
+                await this.lockObject({ id: this.currentId, type: 'courseware-structural-elements' });
+            } catch (error) {
+                if (error.status === 409) {
+                    this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
+                } else {
+                    console.log(error);
+                }
 
-            this.sortContainersInStructualElements({
+                clearTimeout(timeout);
+                this.processing = false;
+                return false;
+            }
+
+            await this.sortContainersInStructualElements({
                 structuralElement: this.structuralElement,
                 containers: this.containerList,
             });
             this.$emit('select', this.currentId);
-        },
 
-        resetSort() {
-            this.setStructuralElementSortMode(false);
-            this.containerList = this.containers;
+            clearTimeout(timeout);
+            this.processing = false;
         },
 
         async exportCurrentElement(data) {
@@ -1711,6 +1719,97 @@ export default {
             await this.unlockObject({ id: this.currentId, type: 'courseware-structural-elements' });
             await this.loadStructuralElement(this.currentElement.id);
             this.showElementRemoveLockDialog(false);
+        },
+        updateContainerList() {
+            this.containerList = this.containers;
+            const containerRefs = this.$refs.containers;
+            for (let ref of containerRefs) {
+                ref.initCurrentData();
+            }
+        },
+        keyHandler(e, containerId) {
+            switch (e.keyCode) {
+                case 27: // esc
+                    this.abortKeyboardSorting(containerId);
+                    break;
+                case 32: // space
+                    e.preventDefault();
+                    if (this.keyboardSelected) {
+                        this.storeKeyboardSorting(containerId);
+                    } else {
+                        this.keyboardSelected = containerId;
+                        const container = this.containerById({id: containerId});
+                        const index = this.containerList.findIndex(c => c.id === container.id);
+                        this.assistiveLive = 
+                            this.$gettextInterpolate(
+                                this.$gettext('%{containerTitle} Abschnitt ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.')
+                                , {containerTitle: container.attributes.title, pos: index + 1, listLength: this.containerList.length}
+                            );
+                    }
+                    break;
+            }
+            if (this.keyboardSelected) {
+                switch (e.keyCode) {
+                    case 9: //tab
+                        this.abortKeyboardSorting(containerId);
+                        break;
+                    case 38: // up
+                        e.preventDefault();
+                        this.moveItemUp(containerId);
+                        break;
+                    case 40: // down
+                        e.preventDefault();
+                        this.moveItemDown(containerId);
+                        break;
+                }
+            }
+        },
+        moveItemUp(containerId) {
+            const currentIndex = this.containerList.findIndex(container => container.id === containerId);
+            if (currentIndex !== 0) {
+                const container = this.containerById({id: containerId});
+                const newPos = currentIndex - 1;
+                this.containerList.splice(newPos, 0, this.containerList.splice(currentIndex, 1)[0]);
+                this.assistiveLive = 
+                    this.$gettextInterpolate(
+                        this.$gettext('%{containerTitle} Abschnitt. Aktuelle Position in der Liste: %{pos} von %{listLength}.')
+                        , {containerTitle: container.attributes.title, pos: newPos + 1, listLength: this.containerList.length}
+                    );
+            }
+        },
+        moveItemDown(containerId) {
+            const currentIndex = this.containerList.findIndex(container => container.id === containerId);
+            if (this.containerList.length - 1 > currentIndex) {
+                const container = this.containerById({id: containerId});
+                const newPos = currentIndex + 1;
+                this.containerList.splice(newPos, 0, this.containerList.splice(currentIndex, 1)[0]);
+                this.assistiveLive = 
+                    this.$gettextInterpolate(
+                        this.$gettext('%{containerTitle} Abschnitt. Aktuelle Position in der Liste: %{pos} von %{listLength}.')
+                        , {containerTitle: container.attributes.title, pos: newPos + 1, listLength: this.containerList.length}
+                    );
+            }
+        },
+        abortKeyboardSorting(containerId) {
+            const container = this.containerById({id: containerId});
+            this.keyboardSelected = null;
+            this.assistiveLive = 
+                this.$gettextInterpolate(
+                    this.$gettext('%{containerTitle} Abschnitt, Neuordnung abgebrochen')
+                    , {containerTitle: container.attributes.title}
+                );
+            this.$emit('select', this.currentId);
+        },
+        storeKeyboardSorting(containerId) {
+            const container = this.containerById({id: containerId});
+            const currentIndex = this.containerList.findIndex(container => container.id === containerId);
+            this.keyboardSelected = null;
+            this.assistiveLive = 
+                this.$gettextInterpolate(
+                    this.$gettext('%{containerTitle} Abschnitt, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.')
+                    , {containerTitle: container.attributes.title, pos: currentIndex + 1, listLength: this.containerList.length}
+                );
+            this.storeSort();
         }
     },
     created() {
@@ -1734,6 +1833,15 @@ export default {
         containers() {
             this.containerList = this.containers;
         },
+        containerList() {
+            if (this.keyboardSelected) {
+                this.$nextTick(() => {
+                    const selected = this.$refs['sortableHandle' + this.keyboardSelected][0];
+                    selected.focus();
+                    selected.scrollIntoView({behavior: "smooth", block: "center"});
+                });
+            }
+        },
         consumeMode(newState) {
             this.consumModeTrap = newState;
         },
diff --git a/resources/vue/components/courseware/CoursewareTabs.vue b/resources/vue/components/courseware/CoursewareTabs.vue
index b5cc5a60f76a18a79f1c2aeb7fc38c90e05819a0..b6e2bc63b778c82708bdea8957109dd9b28d94b5 100644
--- a/resources/vue/components/courseware/CoursewareTabs.vue
+++ b/resources/vue/components/courseware/CoursewareTabs.vue
@@ -127,7 +127,7 @@ export default {
                 return this.$refs[selectorId][0];
             }
             return null;
-        }
+        },
     },
     watch: {
         setSelected(tab) {
diff --git a/resources/vue/components/courseware/CoursewareTabsContainer.vue b/resources/vue/components/courseware/CoursewareTabsContainer.vue
index b07d2a6b35b40bd8854820207def326c54916715..8de73a661650e57dd2faa37fadecafe6e4b9dac4 100644
--- a/resources/vue/components/courseware/CoursewareTabsContainer.vue
+++ b/resources/vue/components/courseware/CoursewareTabsContainer.vue
@@ -7,19 +7,24 @@
         @showEdit="setShowEdit"
         @storeContainer="storeContainer"
         @closeEdit="initCurrentData"
-        @sortBlocks="enableSort"
     >
         <template v-slot:containerContent>
-            <courseware-tabs v-if="!sortMode">
+            <template v-if="showEditMode && canEdit">
+                <span aria-live="assertive" class="assistive-text">{{ assistiveLive }}</span>
+                <span id="operation" class="assistive-text">
+                    {{$gettext('Drücken Sie die Leertaste, um neu anzuordnen')}}
+                </span>
+            </template>
+            <courseware-tabs>
                 <courseware-tab
                     v-for="(section, index) in currentSections"
                     :key="index"
                     :index="index"
                     :name="section.name"
                     :icon="section.icon"
-                    :selected="index === 0"
+                    :selected="sortInTab === index"
                 >
-                    <ul class="cw-container-tabs-block-list">
+                    <ul v-if="!showEditMode" class="cw-container-tabs-block-list">
                         <li v-for="block in section.blocks" :key="block.id" class="cw-block-item">
                             <component
                                 :is="component(block)"
@@ -28,42 +33,48 @@
                                 :isTeacher="isTeacher"
                             />
                         </li>
-                        <li v-if="showEditMode && canAddElements">
-                            <courseware-block-adder-area :container="container" :section="index" @updateContainerContent="updateContent"/>
-                        </li>
                     </ul>
-                </courseware-tab>
-            </courseware-tabs>
-            <div v-if="sortMode && canEdit" class="cw-container-tabs-sort">
-                <courseware-collapsible-box
-                    v-for="(section, index) in currentSections"
-                    :key="index"
-                    :title="section.name"
-                    :icon="section.icon"
-                    :open="index === 0"
-                >
-                    <draggable
-                        class="cw-container-list-block-list cw-container-list-sort-mode"
-                        :class="[section.blocks.length === 0 ? 'cw-container-list-sort-mode-empty' : '']"
-                        tag="ul"
-                        v-model="section.blocks"
-                        v-bind="dragOptions"
-                        handle=".cw-sortable-handle"
-                        @start="isDragging = true"
-                        @end="isDragging = false"
-                    >
-                        <transition-group type="transition" name="flip-blocks" tag="div">
+                    <template v-if="showEditMode && canEdit">
+                        <draggable
+                            class="cw-container-list-block-list cw-container-list-sort-mode"
+                            :class="[section.blocks.length === 0 ? 'cw-container-list-sort-mode-empty' : '']"
+                            tag="ol"
+                            role="listbox"
+                            v-model="section.blocks"
+                            v-bind="dragOptions"
+                            handle=".cw-sortable-handle"
+                            group="blocks"
+                            @start="isDragging = true"
+                            @end="dropBlock"
+                            :containerId="container.id"
+                            :sectionId="index"
+                        >
                             <li v-for="block in section.blocks" :key="block.id" class="cw-block-item cw-block-item-sortable">
-                                <component :is="component(block)" :block="block" :canEdit="canEdit" :isTeacher="isTeacher" />
+                                 <span
+                                    :class="{ 'cw-sortable-handle-dragging': isDragging }"
+                                    class="cw-sortable-handle"
+                                    tabindex="0"
+                                    role="option"
+                                    aria-describedby="operation"
+                                    :ref="'sortableHandle' + block.id"
+                                    @keydown="keyHandler($event, block.id, index)"
+                                ></span>
+                                <component
+                                    :is="component(block)"
+                                    :block="block"
+                                    :canEdit="canEdit"
+                                    :isTeacher="isTeacher"
+                                    :class="{ 'cw-block-item-selected': keyboardSelected === block.id}"
+                                    :blockId="block.id"
+                                />
                             </li>
-                        </transition-group>
-                    </draggable>
-                </courseware-collapsible-box>
-                <div>
-                    <button class="button accept" @click="storeSort"><translate>Sortierung speichern</translate></button>
-                    <button class="button cancel"  @click="resetSort"><translate>Sortieren abbrechen</translate></button>
-                </div>
-            </div>
+                        </draggable>
+                        <template v-if="canAddElements">
+                            <courseware-block-adder-area :container="container" :section="index" @updateContainerContent="updateContent"/>
+                        </template>
+                    </template>
+                </courseware-tab>
+            </courseware-tabs>
         </template>
         <template v-slot:containerEditDialog>
             <form class="default cw-container-dialog-edit-form" @submit.prevent="">
@@ -144,12 +155,20 @@ export default {
                 disabled: false,
                 ghostClass: "block-ghost"
             },
+            processing: false,
+            keyboardSelected: null,
+            sortInTab: 0,
+            assistiveLive: ''
         };
     },
     computed: {
         ...mapGetters({
             blockById: 'courseware-blocks/byId',
+            viewMode: 'viewMode'
         }),
+        showEditMode() {
+            return this.viewMode === 'edit';
+        },
         blocks() {
             if (!this.container) {
                 return [];
@@ -157,9 +176,6 @@ export default {
 
             return this.container.relationships.blocks.data.map(({ id }) => this.blockById({ id })).filter((a) => a);
         },
-        showEditMode() {
-            return this.$store.getters.viewMode === 'edit';
-        },
         icons() {
             return contentIcons;
         },
@@ -170,6 +186,7 @@ export default {
     methods: {
         ...mapActions({
             updateContainer: 'updateContainer',
+            loadContainer: 'courseware-containers/loadById',
             lockObject: 'lockObject',
             unlockObject: 'unlockObject',
         }),
@@ -227,31 +244,31 @@ export default {
             this.currentContainer.attributes.payload.sections.splice(index, 1);
         },
         async storeContainer() {
+            const timeout = setTimeout(() => this.processing = true, 800);
             this.currentContainer.attributes.payload.sections = this.currentContainer.attributes.payload.sections.filter(section => !section.locked);
             this.currentContainer.attributes.payload.sections.forEach(section => {
                 section.blocks = section.blocks.map((block) => {return block.id;});
                 delete section.locked;
             });
-
             await this.updateContainer({
                 container: this.currentContainer,
                 structuralElementId: this.currentContainer.relationships['structural-element'].data.id,
             });
             await this.unlockObject({ id: this.container.id, type: 'courseware-containers' });
+            await this.loadContainer({id : this.container.id });
             this.initCurrentData();
-        },
-        enableSort() {
-            this.sortMode = true;
+            clearTimeout(timeout);
+            this.processing = false;
         },
         async storeSort() {
-            this.sortMode = false;
+            if (this.blockedByAnotherUser) {
+                this.companionInfo({ info: this.$gettext('Dieser Abschnitt wird bereits bearbeitet.') });
+                this.loadContainer({id : this.container.id });
+                return false;
+            }
+            await this.lockObject({ id: this.container.id, type: 'courseware-containers' });
             this.storeContainer();
         },
-        async resetSort() {
-            await this.unlockObject({ id: this.currentContainer.id, type: 'courseware-containers' });
-            this.sortMode = false;
-            this.initCurrentData();
-        },
         component(block) {
             if (block.attributes) {
                 return 'courseware-' + block.attributes["block-type"] + '-block';
@@ -262,6 +279,98 @@ export default {
             if(blockAdder.container !== undefined && blockAdder.container.id === this.container.id) {
                 this.initCurrentData();
             }
+        },
+        keyHandler(e, blockId, sectionIndex) {
+            switch (e.keyCode) {
+                case 27: // esc
+                    this.abortKeyboardSorting(blockId, sectionIndex);
+                    break;
+                case 32: // space
+                    e.preventDefault();
+                    if (this.keyboardSelected) {
+                        this.storeKeyboardSorting(blockId, sectionIndex);
+                    } else {
+                        this.keyboardSelected = blockId;
+                        const block = this.blockById({id: blockId});
+                        const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId);
+                        this.assistiveLive = 
+                            this.$gettextInterpolate(
+                                this.$gettext('%{blockTitle} Block ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.')
+                                , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.currentSections[sectionIndex].blocks.length}
+                            );
+                    }
+                    break;
+            }
+            if (this.keyboardSelected) {
+                switch (e.keyCode) {
+                    case 9: //tab
+                        this.abortKeyboardSorting(blockId, sectionIndex);
+                        break;
+                    case 38: // up
+                        e.preventDefault();
+                        this.moveItemUp(blockId, sectionIndex);
+                        break;
+                    case 40: // down
+                        e.preventDefault();
+                        this.moveItemDown(blockId, sectionIndex);
+                        break;
+                }
+            }
+        },
+        moveItemUp(blockId, sectionIndex) {
+            const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId);
+            const block = this.blockById({id: blockId});
+            if (currentIndex !== 0) {
+                const newPos = currentIndex - 1;
+                this.currentSections[sectionIndex].blocks.splice(newPos, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]);
+                this.assistiveLive = 
+                    this.$gettextInterpolate(
+                        this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.')
+                        , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.currentSections[sectionIndex].blocks.length}
+                    );
+            } else if (sectionIndex !== 0) {
+                const newSectionIndex = sectionIndex - 1;
+                this.sortInTab = newSectionIndex;
+                this.currentSections[newSectionIndex].blocks.push(this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]);
+            }
+        },
+        moveItemDown(blockId, sectionIndex) {
+            const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId);
+            const block = this.blockById({id: blockId});
+            if (this.currentSections[sectionIndex].blocks.length - 1 > currentIndex) {
+                const newPos = currentIndex + 1;
+                this.currentSections[sectionIndex].blocks.splice(newPos, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]);
+                this.assistiveLive = 
+                    this.$gettextInterpolate(
+                        this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.')
+                        , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.currentSections[sectionIndex].blocks.length}
+                    );
+            } else if (this.currentSections.length - 1 > sectionIndex) {
+                const newSectionIndex = sectionIndex + 1;
+                this.sortInTab = newSectionIndex;
+                this.currentSections[newSectionIndex].blocks.splice(0, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]);
+            }
+        },
+        abortKeyboardSorting(blockId, sectionIndex) {
+            const block = this.blockById({id: blockId});
+            this.keyboardSelected = null;
+            this.assistiveLive = 
+                this.$gettextInterpolate(
+                    this.$gettext('%{blockTitle} Block, Neuordnung abgebrochen')
+                    , {blockTitle: block.attributes.title}
+                );
+            this.initCurrentData();
+        },
+        storeKeyboardSorting(blockId, sectionIndex) {
+            const block = this.blockById({id: blockId});
+            const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId);
+            this.keyboardSelected = null;
+            this.assistiveLive = 
+                this.$gettextInterpolate(
+                    this.$gettext('%{blockTitle} Block, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.')
+                    , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.currentSections[sectionIndex].blocks.length}
+                );
+            this.storeSort();
         }
     },
     watch: {
@@ -269,6 +378,16 @@ export default {
             if (!this.showEdit) {
                 this.initCurrentData();
             }
+        },
+        currentSections: {
+            handler() {
+                if (this.keyboardSelected) {
+                    this.$nextTick(() => {
+                        this.$refs['sortableHandle' + this.keyboardSelected][0].focus();
+                    });
+                }   
+            },
+            deep: true
         }
     }
 };
diff --git a/resources/vue/components/courseware/CoursewareToolsBlockadder.vue b/resources/vue/components/courseware/CoursewareToolsBlockadder.vue
index dde956fa20fdbe57c9e2bebd6f390b6f047b39b8..2485eb3ec8948062a21971c190680b0eecd7afe2 100644
--- a/resources/vue/components/courseware/CoursewareToolsBlockadder.vue
+++ b/resources/vue/components/courseware/CoursewareToolsBlockadder.vue
@@ -19,6 +19,7 @@
                             :icon="block.icon"
                             :type="block.type"
                             :description="block.description"
+                            @blockAdded="$emit('blockAdded')"
                         />
                     </div>
                     <div class="cw-element-adder-favs-wrapper" v-if="showEditFavs">
@@ -29,6 +30,7 @@
                                 :title="block.title"
                                 :type="block.type"
                                 :description="block.description"
+                                @blockAdded="$emit('blockAdded')"
                             />
                         </div>
                         <div class="cw-element-adder-favs">
@@ -56,6 +58,7 @@
                             :title="block.title"
                             :type="block.type"
                             :description="block.description"
+                            @blockAdded="$emit('blockAdded')"
                         />
                     </div>
                 </courseware-collapsible-box>
@@ -72,6 +75,7 @@
                             :icon="block.icon"
                             :type="block.type"
                             :description="block.description"
+                            @blockAdded="$emit('blockAdded')"
                         />
                     </div>
                 </courseware-collapsible-box>
diff --git a/resources/vue/mixins/courseware/container.js b/resources/vue/mixins/courseware/container.js
index fac1ea604ef1d16bf91a1ffc9d19f012c92c3ec8..99b30edfabe5d09cb5c425c23becef7a3fe27943 100644
--- a/resources/vue/mixins/courseware/container.js
+++ b/resources/vue/mixins/courseware/container.js
@@ -1,12 +1,79 @@
-import { mapGetters } from 'vuex';
+import { mapActions, mapGetters } from 'vuex';
 
 const containerMixin = {
     computed: {
-        ...mapGetters(['pluginManager']),
+        ...mapGetters({
+            blockById: 'courseware-blocks/byId',
+            containerById: 'courseware-containers/byId',
+            pluginManager: 'pluginManager',
+        }),
     },
     created: function () {
         this.pluginManager.registerComponentsLocally(this);
     },
+    methods: {
+        ...mapActions({
+            updateBlock: 'updateBlock',
+            updateContainer: 'updateContainer',
+            loadContainer: 'courseware-containers/loadById',
+            lockObject: 'lockObject',
+            unlockObject: 'unlockObject',
+        }),
+        dropBlock(e) {
+            this.isDragging = false; // implemented bei echt container type
+            let data = {};
+            data.originContainerId = e.from.__vue__.$attrs.containerId;
+            data.targetContainerId = e.to.__vue__.$attrs.containerId;
+            if (data.originContainerId === data.targetContainerId) {
+                this.storeSort(); // implemented bei echt container type
+            } else {
+                data.originSectionId = e.from.__vue__.$attrs.sectionId;
+                data.originSectionBlockList = e.from.__vue__.$children.map(b => { return b.$attrs.blockId; });
+                data.targetSectionId = e.to.__vue__.$attrs.sectionId;
+                data.targetSectionBlockList = e.to.__vue__.$children.map(b => { return b.$attrs.blockId; });
+                data.blockId = e.item._underlying_vm_.id;
+                data.newPos = e.newIndex;
+                const indexInBlockList = data.targetSectionBlockList.findIndex(b => b === data.blockId);
+                data.targetSectionBlockList.splice(data.newPos, 0, data.targetSectionBlockList.splice(indexInBlockList,1));
+                this.storeInAnotherContainer(data);
+            }
+        },
+        async storeInAnotherContainer(data) {
+            // update block container id
+            let block = this.blockById({id: data.blockId });
+            block.relationships.container.data.id = data.targetContainerId;
+            block.attributes.position = data.newPos;
+            await this.lockObject({ id: data.blockId, type: 'courseware-blocks' });
+            await this.updateBlock({
+                block: block,
+                containerId: data.targetContainerId,
+            });
+            await this.unlockObject({ id: data.blockId, type: 'courseware-blocks' });
+
+            // update origin container
+            let originContainer = this.containerById({ id: data.originContainerId});
+            originContainer.attributes.payload.sections[data.originSectionId].blocks = data.originSectionBlockList;
+            await this.lockObject({ id: data.originContainerId, type: 'courseware-containers' });
+            await this.updateContainer({
+                container: originContainer,
+                structuralElementId: originContainer.relationships['structural-element'].data.id,
+            });
+            await this.unlockObject({ id: data.originContainerId, type: 'courseware-containers' });
+
+            // update target container
+            let targetContainer = this.containerById({ id: data.targetContainerId});
+            targetContainer.attributes.payload.sections[data.targetSectionId].blocks = data.targetSectionBlockList;
+            await this.lockObject({ id: data.targetContainerId, type: 'courseware-containers' });
+            await this.updateContainer({
+                container: targetContainer,
+                structuralElementId: targetContainer.relationships['structural-element'].data.id,
+            });
+            await this.unlockObject({ id: data.targetContainerId, type: 'courseware-containers' });
+
+            this.loadContainer({id : data.originContainerId });
+            this.loadContainer({id : data.targetContainerId });
+        },
+    }
 };
 
 export default containerMixin;
diff --git a/resources/vue/store/courseware/courseware.module.js b/resources/vue/store/courseware/courseware.module.js
index ae786bfd52034ad4df1bfb24d652bd5df4c3ffbf..b1f12f80914b4bc86aae794b8226ed0801667a58 100644
--- a/resources/vue/store/courseware/courseware.module.js
+++ b/resources/vue/store/courseware/courseware.module.js
@@ -40,8 +40,6 @@ const getDefaultState = () => {
 
         showSuggestOerDialog: false,
 
-        structuralElementSortMode: false,
-
         importFilesState: '',
         importFilesProgress: 0,
         importStructuresState: '',
@@ -201,9 +199,6 @@ const getters = {
     showSuggestOerDialog(state) {
         return state.showSuggestOerDialog;
     },
-    structuralElementSortMode(state) {
-        return state.structuralElementSortMode;
-    },
     importFilesState(state) {
         return state.importFilesState;
     },
@@ -877,10 +872,6 @@ export const actions = {
         context.commit('setShowOverviewElementAddDialog', bool);
     },
 
-    setStructuralElementSortMode({ commit }, bool) {
-        commit('setStructuralElementSortMode', bool);
-    },
-
     setImportFilesState({ commit }, state) {
         commit('setImportFilesState', state);
     },
@@ -1438,10 +1429,6 @@ export const mutations = {
         state.showStructuralElementRemoveLockDialog = showRemoveLock;
     },
 
-    setStructuralElementSortMode(state, mode) {
-        state.structuralElementSortMode = mode;
-    },
-
     setImportFilesState(state, importFilesState) {
         state.importFilesState = importFilesState;
     },