diff --git a/corsscripts/stacksortable.js b/corsscripts/stacksortable.js
index d362eed6b63d3afd95546b4624406935a4ad4f1c..32f1f5eb7772cb7667458727d611dc1b1f5817f6 100644
--- a/corsscripts/stacksortable.js
+++ b/corsscripts/stacksortable.js
@@ -294,8 +294,8 @@ export function get_iframe_height() {
  * @method generate_available - Generates the available list based on the current state.
  * @method generate_used - Generates the used list based on the current state.
  * @method update_state - Updates the state based on changes in the used and available lists.
- * @method update_grid_css - Updates the CSS styling of grid-items.
- * @method resize_grid_items - Resizes the height and widths of elements with `grid-item` class according to the max values across grid items.
+ * @method update_grid_empty_css - Updates the CSS styling of grid-items.
+ * @method resize_grid_items - Auto-resizes the height and widths of elements with grid-item and grid-item-rigids. 
  * @method validate_options - Validates the sortable user options.
  *
  * @example
@@ -597,10 +597,10 @@ export const stack_sortable = class stack_sortable {
     }
 
     /**
-     * Resizes all grid-item heights and widths according to the maximum content height across all grid-items.
-     * Only resizes widths if in "row" orientation, where we have to fix widths witht the grid-item-rigid class.
+     * Resizes the heights and widths of all grid-item and grid-item-rigid elements according to the maximum content height across all such items.
+     * Only resizes widths if in "row" orientation, where we have to fix widths with the grid-item-rigid class.
      * Otherwise widths are already automatically resized.
-     * Avoids affecting proof mode by virtue of grid-item and grid-item-rigid classes not being used there.
+     * Avoids affecting proof mode by virtue of that mode avoiding grid-item classes entirely.
      * 
      * If `item_height` parameter has been passed, then heights will not be autoresized.
      * Likewise, if `item_width` parameter has been passed, then widths will not be autoresized.
@@ -609,36 +609,16 @@ export const stack_sortable = class stack_sortable {
      * @returns {void}
      */
     resize_grid_items() {
-            const allGridItems = document.querySelectorAll('.grid-item, .grid-item-rigid');
-            const maxHeight = Math.max(...[...allGridItems].map((item) => item.scrollHeight));
-            const maxWidth = Math.max(...[...allGridItems].map((item) => item.scrollWidth));
-
-            // Resize all grid-item or grid-item-rigid divs heights.
-            allGridItems.forEach((item) => {
-                item.style.height = (this.override_item_height)? this.item_height_width['style']['height'] : `${maxHeight}px`;
-                // If the orientation is horizontal, then we also need to adjust widths due to rigid styles.
-                if (this.orientation === "row") {
-                    item.style.width = (this.override_item_width)? this.item_height_width['style']['width'] : `${maxWidth}px`; 
-                } else {
-                    // Reset the width to default if switching from horizontal to vertical.
-                    item.style.width = (this.override_item_width)? this.item_height_width['style']['width'] : '';
-                }
-            });
+            const maxHeight = this._resize_compute_max_height('.grid-item, .grid-item-rigid');
+            const maxWidth = this._resize_compute_max_width('.grid-item, .grid-item-rigid');
 
-            // In grid fixed grid mode we also need to resize the individual item containers.
-            if (this.rows !== "" && this.columns !== "") {
-                for (const [i, value] of this.state.used.entries()) 
-                    for (const [j, val] of value.entries()) {
-                        this.used[i][j].style.height = (this.override_item_height)? this.item_height_width['style']['height'] : `${maxHeight + 12}px`;
-                        // For horizontal orientaion, also adjust width.
-                        if (this.orientation === "row") {
-                            this.used[i][j].style.width = (this.override_item_width)? this.item_height_width['style']['width'] : `${maxWidth + 12}px`; 
-                        } else {
-                            // Reset the width to default if switching from horizontal to vertical.
-                            this.used[i][j].style.width = (this.override_item_width)? this.item_height_width['style']['width'] : '';
-                        }
-                    }
-                }
+            // Resize the heights for both grid-item and grid-item-rigid
+            this._resize_heights('.grid-item, .grid-item-rigid', maxHeight);
+
+            // Additionally resize the width of grid-item-rigid
+            this._resize_widths('.grid-item-rigid', maxWidth);
+            this._resize_grid_container_heights(maxHeight);
+            this._resize_grid_container_widths(maxWidth);
     }
 
     /**
@@ -660,14 +640,15 @@ export const stack_sortable = class stack_sortable {
 
     /**
      * Updates empty class elements according as whether they are no longer empty or become empty.
-     * Also updates the autosizing of all grid-item and grid-item-rigid elements.
+     * This is not used by proof or grouping mode because the lists are never empty (they contain headers).
+     * This only affects the case in grid mode, where there are empty placeholders.
      * This should be passed to `onSort` option of sortables so that every time an element is dragged, 
      * the CSS updates accordingly.
      *
      * @method
      * @returns {void}
      */
-    update_grid_css() {
+    update_grid_empty_css() {
         // Remove empty class if no longer empty.
         const empties = document.querySelectorAll('.empty');
         empties.forEach((el) => {if (!this._is_empty(el)) {
@@ -676,13 +657,13 @@ export const stack_sortable = class stack_sortable {
             el.style.margin = '';
         }})
 
-        // re-assign empty class if empty
+        // re-assign empty class if empty.
         const usedLists = document.querySelectorAll('.usedList');
         usedLists.forEach((el) => {if (this._is_empty(el)) {
             el.classList.add('empty');
+            // We need to auto-resize the height again in this case. 
+            this._resize_set_height(el, this._resize_compute_max_height('.grid-item, .grid-item-rigid'));
         }})
-
-        this.resize_grid_items();
     }
 
     /**
@@ -1005,7 +986,12 @@ export const stack_sortable = class stack_sortable {
         // Keep track of current orientation.
         this.orientation = (this.orientation === "row") ? "col" : "row";
 
-        // Resize the grid-items as appropriate
+        // CSS resizing of grid-items
+        // --------------------------
+        // Reset heights and widths of grid items.
+        document.querySelectorAll('.grid-item, .grid-item-rigid').forEach((item) => item.style.width = '');
+        document.querySelectorAll('.grid-item, .grid-item-rigid').forEach((item) => item.style.height = '');
+        // Then update the CSS accordingly.
         this.resize_grid_items();
     }
 
@@ -1064,6 +1050,116 @@ export const stack_sortable = class stack_sortable {
         return el.textContent.trim() === "" && el.children.length === 0;
     }
 
+    /**
+     * Computes the maximum height of all items as specified by the CSS selector.
+     * 
+     * @method
+     * @returns {void}
+     */
+    _resize_compute_max_height(selector) {
+        const selectedItems = document.querySelectorAll(selector);
+        return Math.max(...[...selectedItems].map((item) => item.scrollHeight));
+    }
+
+    /**
+     * Computes the maximum width of all items as specified by the CSS selector.
+     * 
+     * @method
+     * @returns {void}
+     */
+    _resize_compute_max_width(selector) {
+        const selectedItems = document.querySelectorAll(selector);
+        return Math.max(...[...selectedItems].map((item) => item.scrollWidth));
+    }
+
+    /**
+     * Resizes the height of an element in `px`.
+     * 
+     * If `item_height` parameter has been passed, then height will be overriden by the value in that parameter.
+     *
+     * @method
+     * @returns {void}
+     */
+    _resize_set_height(el, height) {
+        el.style.height = (this.override_item_height) ? this.item_height_width['style']['height'] : `${height}px`;
+    }
+
+    /**
+     * Resizes the width of an element in `px`.
+     * 
+     * If `item_width` parameter has been passed, then width will be overriden by the value in that parameter.
+     *
+     * @method
+     * @returns {void}
+     */
+    _resize_set_width(el, width) {
+        el.style.width = (this.override_item_width) ? this.item_height_width['style']['width'] : `${width}px`;
+    }
+
+    /**
+     * Resizes the heights of items specified by the CSS selector.
+     * 
+     * If `item_height` parameter has been passed, then heights will be overriden by the value in that parameter.
+     *
+     * @method
+     * @returns {void}
+     */
+    _resize_heights(selector, height) {
+        document.querySelectorAll(selector).forEach((item) => this._resize_set_height(item, height));
+    }
+
+    /**
+     * Resizes the widths of items specified by the CSS selector.
+     * 
+     * If `item_width` parameter has been passed, then widths will be overriden by the value in that parameter.
+     *
+     * @method
+     * @returns {void}
+     */
+    _resize_widths(selector, width) {
+        document.querySelectorAll(selector).forEach((item) => this._resize_set_width(item, width));
+    }
+
+    /**
+     * Resizes the heights of all containers containing placeholder lists in grid mode. Adds some extra to account for margin.
+     * 
+     * If `item_height` parameter has been passed, then the heights will be overriden by the value in that parameter.
+     *
+     * @method
+     * @returns {void}
+     */
+    _resize_grid_container_heights(height) {
+        if (this.rows !== "" && this.columns !== "") {
+            for (const [i, value] of this.state.used.entries()) 
+                for (const [j, _] of value.entries()) {
+                    this._resize_set_height(this.used[i][j], height + 12);
+            }
+        }
+    }
+
+    /**
+     * Resizes the widths of all containers containing placeholder lists in grid mode. Adds some extra to account for margin.
+     * 
+     * If `item_width` parameter has been passed, then the widths will be overriden by the value in that parameter.
+     *
+     * @method
+     * @returns {void}
+     */
+    _resize_grid_container_widths(width) {
+        if (this.rows !== "" && this.columns !== "") {
+            for (const [i, value] of this.state.used.entries()) 
+                for (const [j, _] of value.entries()) {
+                    // Adjust the width if in horizontal orientation.
+                    if (this.orientation === "row") {
+                        this._resize_set_width(this.used[i][j], width + 12);
+                    } else {
+                        // Else, set to inherit or override.
+                        this.used[i][j].style.width = (this.override_item_width) ? this.item_height_width['style']['width'] : '';
+                    }
+            }
+        }
+    }
+
     /**
      * Set ghostClass, group and disabled-after-submission options for both "used" and "available" lists.
      *
diff --git a/corsscripts/stacksortable.min.js b/corsscripts/stacksortable.min.js
index aa62f77c363abe1574fcc160ea1d75abe2fc7e5b..7bcf9a7d34a227d6693dff880131ce201718106b 100644
--- a/corsscripts/stacksortable.min.js
+++ b/corsscripts/stacksortable.min.js
@@ -32,13 +32,11 @@ colDiv.append(divRowCol);})})};var availDiv=document.createElement("ul");availDi
 this.used=this.usedId.map(idList=>idList.map(id=>document.getElementById(id)));this.available=document.getElementById(this.availableId);}
 generate_available(){this.state.available.forEach(key=>this.available.append(this._create_li(key,this.item_height_width)));}
 generate_used(){for(const[i,value]of this.state.used.entries()){if(this.rows!==""&&this.columns!==""){for(const[j,val]of value.entries()){this._apply_attrs(this.used[i][j],this.container_height_width);val.forEach(key=>this.used[i][j].append(this._create_li(key,this.item_height_width)));}}else{value[0].forEach(key=>this.used[i][0].append(this._create_li(key,this.item_height_width)));}}}
-resize_grid_items(){const allGridItems=document.querySelectorAll('.grid-item, .grid-item-rigid');const maxHeight=Math.max(...[...allGridItems].map((item)=>item.scrollHeight));const maxWidth=Math.max(...[...allGridItems].map((item)=>item.scrollWidth));allGridItems.forEach((item)=>{item.style.height=(this.override_item_height)?this.item_height_width['style']['height']:`${maxHeight}px`;if(this.orientation==="row"){item.style.width=(this.override_item_width)?this.item_height_width['style']['width']:`${maxWidth}px`;}else{item.style.width=(this.override_item_width)?this.item_height_width['style']['width']:'';}});if(this.rows!==""&&this.columns!==""){for(const[i,value]of this.state.used.entries())
-for(const[j,val]of value.entries()){this.used[i][j].style.height=(this.override_item_height)?this.item_height_width['style']['height']:`${maxHeight+12}px`;if(this.orientation==="row"){this.used[i][j].style.width=(this.override_item_width)?this.item_height_width['style']['width']:`${maxWidth+12}px`;}else{this.used[i][j].style.width=(this.override_item_width)?this.item_height_width['style']['width']:'';}}}}
+resize_grid_items(){const maxHeight=this._resize_compute_max_height('.grid-item, .grid-item-rigid');const maxWidth=this._resize_compute_max_width('.grid-item, .grid-item-rigid');this._resize_heights('.grid-item, .grid-item-rigid',maxHeight);this._resize_widths('.grid-item-rigid',maxWidth);this._resize_grid_container_heights(maxHeight);this._resize_grid_container_widths(maxWidth);}
 update_state(newUsed,newAvailable){var newState={used:newUsed.map((usedList)=>usedList.map((used)=>used.toArray())),available:newAvailable.toArray()};if(this.inputId!==null){this.input.value=JSON.stringify(newState);this.input.dispatchEvent(new Event("change"));}
 this.state=newState;}
-update_grid_css(){const empties=document.querySelectorAll('.empty');empties.forEach((el)=>{if(!this._is_empty(el)){el.classList.remove('empty');el.style.height='';el.style.margin='';}})
-const usedLists=document.querySelectorAll('.usedList');usedLists.forEach((el)=>{if(this._is_empty(el)){el.classList.add('empty');}})
-this.resize_grid_items();}
+update_grid_empty_css(){const empties=document.querySelectorAll('.empty');empties.forEach((el)=>{if(!this._is_empty(el)){el.classList.remove('empty');el.style.height='';el.style.margin='';}})
+const usedLists=document.querySelectorAll('.usedList');usedLists.forEach((el)=>{if(this._is_empty(el)){el.classList.add('empty');this._resize_set_height(el,this._resize_compute_max_height('.grid-item, .grid-item-rigid'));}})}
 validate_options(possibleOptionKeys,unknownErr,overwrittenErr){var err="";var keysRecognised=true;var invalidKeys=[];Object.keys(this.options.used).forEach(key=>{if(!this._validate_option_key(key,possibleOptionKeys)){keysRecognised=false;if(!invalidKeys.includes(key)){invalidKeys.push(key);}}});Object.keys(this.options.available).forEach(key=>{if(!this._validate_option_key(key,possibleOptionKeys)){keysRecognised=false;if(!invalidKeys.includes(key)){invalidKeys.push(key);}}});if(!keysRecognised){err+=unknownErr+invalidKeys.join(", ")+". ";}
 var overwrittenKeys=[];var keysPreserved=true;["ghostClass","group","onSort"].forEach(key=>{if(Object.keys(this.userOptions.used).includes(key)||Object.keys(this.userOptions.available).includes(key))
 {keysPreserved=false;overwrittenKeys.push(key);}});if(!keysPreserved){err+=overwrittenErr+overwrittenKeys.join(", ")+".";}
@@ -59,12 +57,22 @@ var gridItems=document.querySelectorAll(`.${currGridClass}`);gridItems.forEach((
 if(this.rows!==""){[].concat(...this.used).forEach((div)=>{if(this.orientation==="col"){div.classList.remove("row");div.classList.add("col","col-rigid");}else{div.classList.remove("col","col-rigid");div.classList.add("row");}})}}else{var removeClass=(this.orientation==="row")?["row"]:["col"];}
 this.colIds.forEach((colId)=>{var ul=document.getElementById(colId);ul.classList.remove(...removeClass);ul.classList.add(...addClass);});this.available.classList.remove(...removeClass);this.available.classList.add(...addClass);if(this.orientation==="col"){this.available.parentNode.insertBefore(this.available,this.available.parentNode.firstChild);}else{this.available.parentNode.append(this.available);}
 if(this.grid){if(this.orientation==="col"){document.querySelectorAll(".header").forEach((header)=>{if(!header.classList.contains("index")){header.classList.remove("header");header.classList.add("index");}});}else{document.querySelectorAll(".index").forEach((index)=>{if(!index.classList.contains("header")){index.classList.remove("index");index.classList.add("header");}})}
-if(this.use_index){var indexDiv=document.getElementById("index");indexDiv.classList.remove(...removeClass);indexDiv.classList.add(...addClass);if(this.orientation==="col"){document.querySelectorAll("#index > .index").forEach((idx)=>{if(!idx.classList.contains("header")){idx.classList.remove("index");idx.classList.add("header");}})}else{document.querySelectorAll("#index > .header").forEach((header)=>{if(!header.classList.contains("index")){header.classList.remove("header");header.classList.add("index");}})}}};this.orientation=(this.orientation==="row")?"col":"row";this.resize_grid_items();}
+if(this.use_index){var indexDiv=document.getElementById("index");indexDiv.classList.remove(...removeClass);indexDiv.classList.add(...addClass);if(this.orientation==="col"){document.querySelectorAll("#index > .index").forEach((idx)=>{if(!idx.classList.contains("header")){idx.classList.remove("index");idx.classList.add("header");}})}else{document.querySelectorAll("#index > .header").forEach((header)=>{if(!header.classList.contains("index")){header.classList.remove("header");header.classList.add("index");}})}}};this.orientation=(this.orientation==="row")?"col":"row";document.querySelectorAll('.grid-item, .grid-item-rigid').forEach((item)=>item.style.width='');document.querySelectorAll('.grid-item, .grid-item-rigid').forEach((item)=>item.style.height='');this.resize_grid_items();}
 _generate_state(steps,inputId,columns,rows){const usedState=(rows===0||columns===0)?Array(columns).fill().map(()=>[[]]):Array(columns).fill().map(()=>Array(rows).fill([]));let stateStore=document.getElementById(inputId);if(stateStore===null){return{used:usedState,available:[...Object.keys(steps)]};}
 return(stateStore.value&&stateStore.value!="")?JSON.parse(stateStore.value):{used:usedState,available:[...Object.keys(steps)]};}
 _get_moveable_parent_li(target){var li=target;while(!li.matches(".list-group-item")){li=li.parentNode;}
 return li;}
 _is_empty(el){return el.textContent.trim()===""&&el.children.length===0;}
+_resize_compute_max_height(selector){const selectedItems=document.querySelectorAll(selector);return Math.max(...[...selectedItems].map((item)=>item.scrollHeight));}
+_resize_compute_max_width(selector){const selectedItems=document.querySelectorAll(selector);return Math.max(...[...selectedItems].map((item)=>item.scrollWidth));}
+_resize_set_height(el,height){el.style.height=(this.override_item_height)?this.item_height_width['style']['height']:`${height}px`;}
+_resize_set_width(el,width){el.style.width=(this.override_item_width)?this.item_height_width['style']['width']:`${width}px`;}
+_resize_heights(selector,height){document.querySelectorAll(selector).forEach((item)=>this._resize_set_height(item,height));}
+_resize_widths(selector,width){document.querySelectorAll(selector).forEach((item)=>this._resize_set_width(item,width));}
+_resize_grid_container_heights(height){if(this.rows!==""&&this.columns!==""){for(const[i,value]of this.state.used.entries())
+for(const[j,_]of value.entries()){this._resize_set_height(this.used[i][j],height+12);}}}
+_resize_grid_container_widths(width){if(this.rows!==""&&this.columns!==""){for(const[i,value]of this.state.used.entries())
+for(const[j,_]of value.entries()){if(this.orientation==="row"){this._resize_set_width(this.used[i][j],width+12);}else{this.used[i][j].style.width=(this.override_item_width)?this.item_height_width['style']['width']:'';}}}}
 _set_ghostClass_group_and_disabled_options(){var group_val={};group_val.used=(this.rows==="")?{name:"sortableUsed",pull:true,put:true}:{name:"sortableUsed",pull:true,put:(to)=>to.el.children.length<1};group_val.available=(this.clone==="true")?{name:"sortableAvailable",pull:"clone",revertClone:true,put:false}:{name:"sortableAvailable",put:true};var options_to_assign=this.submitted?{used:{ghostClass:"list-group-item-info",group:group_val.used,disabled:true},available:{ghostClass:"list-group-item-info",group:group_val.available,disabled:true}}:{used:{ghostClass:"list-group-item-info",group:group_val.used},available:{ghostClass:"list-group-item-info",group:group_val.available}}
 var options={used:Object.assign(Object.assign({},this.userOptions.used),options_to_assign.used),available:Object.assign(Object.assign({},this.userOptions.available),options_to_assign.available)};return options;}
 _set_user_options(options){var userOptions;if(options===null){userOptions=this.defaultOptions;}else{userOptions={used:Object.assign(this.defaultOptions.used,options.used),available:Object.assign(this.defaultOptions.available,options.available)};}
diff --git a/stack/cas/castext2/blocks/parsons.block.php b/stack/cas/castext2/blocks/parsons.block.php
index 8cfe552f23c7d159dedf4afae2985d7164b6924b..ae7091037c9961131f42866e99f14801586c7200 100644
--- a/stack/cas/castext2/blocks/parsons.block.php
+++ b/stack/cas/castext2/blocks/parsons.block.php
@@ -312,13 +312,14 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block {
             sortableList.forEach((sortable) =>
                 sortable.option("onSort", () => {
                     stackSortable.update_state(sortableUsed, sortableAvailable);
-                    stackSortable.update_grid_css();})
+                    stackSortable.update_grid_empty_css();})
             )
         );' . "\n";
+
         $code .= 'sortableAvailable.option("onSort", 
             () => {
                 stackSortable.update_state(sortableUsed, sortableAvailable);
-                stackSortable.update_grid_css();});' . "\n";
+                stackSortable.update_grid_empty_css();});' . "\n";
 
         // Options can now be validated since sortable objects have been instantiated, we throw warnings only.
         $code .= 'stackSortable.validate_options(