diff --git a/src/mol-model/loci.ts b/src/mol-model/loci.ts
index 3def8af3a87fb27038b5b6e2999f758e0e342f47..3064ccfb8ca1afa26e0e21686f8b230230413b31 100644
--- a/src/mol-model/loci.ts
+++ b/src/mol-model/loci.ts
@@ -40,6 +40,9 @@ export function isDataLoci(x: any): x is DataLoci {
 export function areDataLociEqual(a: DataLoci, b: DataLoci) {
     return a.data === b.data && a.tag === b.tag && OrderedSet.areEqual(a.indices, b.indices)
 }
+export function isDataLociEmpty(loci: DataLoci) {
+    return OrderedSet.size(loci.indices) === 0 ? true : false
+}
 export function createDataLoci(data: any, tag: string, indices: OrderedSet<number>): DataLoci {
     return { kind: 'data-loci', data, tag, indices }
 }
@@ -73,6 +76,29 @@ namespace Loci {
         return false
     }
 
+    export function isEmpty(loci: Loci) {
+        if (isEveryLoci(loci)) return false
+        if (isEmptyLoci(loci)) return true
+        if (isDataLoci(loci)) return isDataLociEmpty(loci)
+        if (Structure.isLoci(loci)) return Structure.isLociEmpty(loci)
+        if (StructureElement.Loci.is(loci)) StructureElement.Loci.isEmpty(loci)
+        if (Link.isLoci(loci)) Link.isLociEmpty(loci)
+        if (Shape.isLoci(loci)) return Shape.isLociEmpty(loci)
+        if (ShapeGroup.isLoci(loci)) return ShapeGroup.isLociEmpty(loci)
+        return false
+    }
+
+    export function remap<T>(loci: Loci, data: T) {
+        if (data instanceof Structure) {
+            if (StructureElement.Loci.is(loci)) {
+                loci = StructureElement.Loci.remap(loci, data)
+            } else if (Link.isLoci(loci)) {
+                loci = Link.remapLoci(loci, data)
+            }
+        }
+        return loci
+    }
+
     const sphereHelper = new CentroidHelper(), tempPos = Vec3.zero();
 
     export function getBoundingSphere(loci: Loci, boundingSphere?: Sphere3D): Sphere3D | undefined {
diff --git a/src/mol-model/shape/shape.ts b/src/mol-model/shape/shape.ts
index 413229c084ba03176421e029f159caf8391cb58f..da3fea7f21bff0a51bf7ea961122ed7bc9a2a803 100644
--- a/src/mol-model/shape/shape.ts
+++ b/src/mol-model/shape/shape.ts
@@ -50,6 +50,7 @@ export namespace Shape {
     export function Loci(shape: Shape): Loci { return { kind: 'shape-loci', shape } }
     export function isLoci(x: any): x is Loci { return !!x && x.kind === 'shape-loci' }
     export function areLociEqual(a: Loci, b: Loci) { return a.shape === b.shape }
+    export function isLociEmpty(loci: Loci) { return loci.shape.groupCount === 0 ? true : false }
 }
 
 export namespace ShapeGroup {
@@ -96,4 +97,16 @@ export namespace ShapeGroup {
         }
         return true
     }
+
+    export function isLociEmpty(loci: Loci) {
+        return size(loci) === 0 ? true : false
+    }
+
+    export function size(loci: Loci) {
+        let size = 0
+        for (const group of loci.groups) {
+            size += OrderedSet.size(group.ids)
+        }
+        return size
+    }
 }
\ No newline at end of file
diff --git a/src/mol-model/structure/structure/element/loci.ts b/src/mol-model/structure/structure/element/loci.ts
index 5006485b8d94681951a2810bab0f0f939a50cd02..df9e6ac52703bb34b5b6049a5cfe51e513d8abf3 100644
--- a/src/mol-model/structure/structure/element/loci.ts
+++ b/src/mol-model/structure/structure/element/loci.ts
@@ -53,6 +53,10 @@ export namespace Loci {
         return true
     }
 
+    export function isEmpty(loci: Loci) {
+        return size(loci) === 0 ? true : false
+    }
+
     export function size(loci: Loci) {
         let s = 0;
         for (const u of loci.elements) s += OrderedSet.size(u.indices);
@@ -101,7 +105,7 @@ export namespace Loci {
                     indices = SortedArray.ofSortedArray(_indices)
                 }
 
-                elements.push({ unit, indices })
+                if (OrderedSet.size(indices) > 0) elements.push({ unit, indices })
             }
         });
 
@@ -111,7 +115,7 @@ export namespace Loci {
     /** Create union of `xs` and `ys` */
     export function union(xs: Loci, ys: Loci): Loci {
         if (xs.elements.length > ys.elements.length) return union(ys, xs);
-        if (xs.elements.length === 0) return ys;
+        if (Loci.isEmpty(xs)) return ys;
 
         const map = new Map<number, OrderedSet<UnitIndex>>();
 
@@ -155,7 +159,7 @@ export namespace Loci {
 
     export function areIntersecting(xs: Loci, ys: Loci): boolean {
         if (xs.elements.length > ys.elements.length) return areIntersecting(ys, xs);
-        if (xs.elements.length === 0) return ys.elements.length === 0;
+        if (Loci.isEmpty(xs)) return Loci.isEmpty(ys);
 
         const map = new Map<number, OrderedSet<UnitIndex>>();
 
@@ -286,7 +290,7 @@ export namespace Loci {
     }
 
     export function toScriptExpression(loci: Loci) {
-        if (loci.elements.length === 0) return MS.struct.generator.empty();
+        if (Loci.isEmpty(loci)) return MS.struct.generator.empty();
 
         const models = loci.structure.models;
         const sourceIndexMap = new Map<string, { modelLabel: string, modelIndex: number, xs: UniqueArray<number, number> }>();
diff --git a/src/mol-model/structure/structure/element/stats.ts b/src/mol-model/structure/structure/element/stats.ts
index 2d53df6001a0f719b2f459c38d18f5f402d8b465..497bfd897be5a91e36576e3e1299138dc3925f94 100644
--- a/src/mol-model/structure/structure/element/stats.ts
+++ b/src/mol-model/structure/structure/element/stats.ts
@@ -92,7 +92,7 @@ export namespace Stats {
 
     export function ofLoci(loci: Loci) {
         const stats = create()
-        if (loci.elements.length > 0) {
+        if (!Loci.isEmpty(loci)) {
             for (const e of loci.elements) handleElement(stats, e)
         }
         return stats
diff --git a/src/mol-model/structure/structure/structure.ts b/src/mol-model/structure/structure/structure.ts
index d5575c999a4731e100788c31e230e510b18892e4..a88ab91f81dc5bca543665ce3ae06658e00093f1 100644
--- a/src/mol-model/structure/structure/structure.ts
+++ b/src/mol-model/structure/structure/structure.ts
@@ -468,6 +468,10 @@ namespace Structure {
         return a.structure === b.structure
     }
 
+    export function isLociEmpty(loci: Loci) {
+        return loci.structure.isEmpty
+    }
+
     export function create(units: ReadonlyArray<Unit>, props?: Props): Structure {
         return new Structure(units, props);
     }
diff --git a/src/mol-model/structure/structure/unit/links.ts b/src/mol-model/structure/structure/unit/links.ts
index 8ea138d4d1d8fc8ef0d9e634513c5bb6a4064c13..12e2830c1ad6c07604d467ed5acd0dbc629482c1 100644
--- a/src/mol-model/structure/structure/unit/links.ts
+++ b/src/mol-model/structure/structure/unit/links.ts
@@ -62,6 +62,10 @@ namespace Link {
         return true
     }
 
+    export function isLociEmpty(loci: Loci) {
+        return loci.links.length === 0 ? true : false
+    }
+
     export function remapLoci(loci: Loci, structure: Structure): Loci {
         if (structure === loci.structure) return loci
 
diff --git a/src/mol-plugin/ui/sequence/sequence.tsx b/src/mol-plugin/ui/sequence/sequence.tsx
index 2d1528bc11a77d88016310b099a5f5f19a229b55..d221eb5288d5d62e263f019ee6fa4ce14fcc3c15 100644
--- a/src/mol-plugin/ui/sequence/sequence.tsx
+++ b/src/mol-plugin/ui/sequence/sequence.tsx
@@ -13,6 +13,7 @@ import { ButtonsType, ModifiersKeys, getButtons, getModifiers } from '../../../m
 import { ValueBox } from '../../../mol-util';
 import { Residue } from './residue';
 import { SequenceWrapper } from './wrapper';
+import { StructureElement } from '../../../mol-model/structure';
 
 type SequenceProps = { sequenceWrapper: SequenceWrapper.Any }
 type SequenceState = { markerData: ValueBox<Uint8Array> }
@@ -62,7 +63,7 @@ export class Sequence<P extends SequenceProps> extends PluginUIComponent<P, Sequ
         const ev = { current: Interactivity.Loci.Empty, modifiers }
         if (seqId !== undefined) {
             const loci = this.props.sequenceWrapper.getLoci(seqId);
-            if (loci.elements.length > 0) ev.current = { loci };
+            if (!StructureElement.Loci.isEmpty(loci)) ev.current = { loci };
         }
         this.plugin.behaviors.interaction.highlight.next(ev)
     }
@@ -71,7 +72,7 @@ export class Sequence<P extends SequenceProps> extends PluginUIComponent<P, Sequ
         const ev = { current: Interactivity.Loci.Empty, buttons, modifiers }
         if (seqId !== undefined) {
             const loci = this.props.sequenceWrapper.getLoci(seqId);
-            if (loci.elements.length > 0) ev.current = { loci };
+            if (!StructureElement.Loci.isEmpty(loci)) ev.current = { loci };
         }
         this.plugin.behaviors.interaction.click.next(ev)
     }
diff --git a/src/mol-plugin/util/structure-element-selection.ts b/src/mol-plugin/util/structure-element-selection.ts
index bf82095a7158f553b5e547ae3b6201a3a9625275..cbc8c83201fc2899d048e602031ec7660628f1a9 100644
--- a/src/mol-plugin/util/structure-element-selection.ts
+++ b/src/mol-plugin/util/structure-element-selection.ts
@@ -69,7 +69,7 @@ class StructureElementSelectionManager {
             if (entry) {
                 entry.selection = StructureElement.Loci.subtract(entry.selection, loci);
                 this.plugin.events.interactivity.selectionUpdated.next()
-                return entry.selection.elements.length === 0 ? EmptyLoci : entry.selection;
+                return StructureElement.Loci.isEmpty(entry.selection) ? EmptyLoci : entry.selection;
             }
         }
         return EmptyLoci
@@ -81,7 +81,7 @@ class StructureElementSelectionManager {
             if (entry) {
                 entry.selection = loci;
                 this.plugin.events.interactivity.selectionUpdated.next()
-                return entry.selection.elements.length === 0 ? EmptyLoci : entry.selection;
+                return StructureElement.Loci.isEmpty(entry.selection) ? EmptyLoci : entry.selection;
             }
         }
         return EmptyLoci;
@@ -94,7 +94,7 @@ class StructureElementSelectionManager {
             const k = keys.next();
             if (k.done) break;
             const s = this.entries.get(k.value)!;
-            if (s.selection.elements.length > 0) selections.push(s.selection);
+            if (!StructureElement.Loci.isEmpty(s.selection)) selections.push(s.selection);
             s.selection = StructureElement.Loci(s.selection.structure, []);
         }
         this.plugin.events.interactivity.selectionUpdated.next()
diff --git a/src/mol-plugin/util/structure-representation-helper.ts b/src/mol-plugin/util/structure-representation-helper.ts
index e9b9131891531f339922938d2262e7335a5611f9..f14484abf60621c0acceb57c1e3ecbde50502ad9 100644
--- a/src/mol-plugin/util/structure-representation-helper.ts
+++ b/src/mol-plugin/util/structure-representation-helper.ts
@@ -65,7 +65,7 @@ export class StructureRepresentationHelper {
                 bundle: StructureElement.Bundle.fromLoci(combinedLoci)
             })
         } else {
-            const combinedLoci = getCombinedLoci(modifier, loci, StructureElement.Loci(s, []))
+            const combinedLoci = getCombinedLoci(modifier, loci, StructureElement.Loci.none(s))
             const params = StructureRepresentation3DHelpers.getDefaultParams(this.plugin, type as any, s)
 
             const p = params.type.params
diff --git a/src/mol-repr/structure/complex-representation.ts b/src/mol-repr/structure/complex-representation.ts
index 4ffd090a3693850cf6bd409b1ef337c750ffcc81..eae6db967ffbe77367020d834a7c99fa0c1084c1 100644
--- a/src/mol-repr/structure/complex-representation.ts
+++ b/src/mol-repr/structure/complex-representation.ts
@@ -58,11 +58,9 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
         if (!_structure) return false
         if (!StructureElement.Loci.is(loci) && !Link.isLoci(loci)) return false
         if (!Structure.areRootsEquivalent(loci.structure, _structure)) return false
-        if (StructureElement.Loci.is(loci)) {
-            loci = StructureElement.Loci.remap(loci, _structure)
-        } else if (Link.isLoci(loci)) {
-            loci = Link.remapLoci(loci, _structure)
-        }
+        // Remap `loci` from equivalent structure to the current `_structure`
+        loci = Loci.remap(loci, _structure)
+        if (Loci.isEmpty(loci)) return false
         return visual ? visual.mark(loci, action) : false
     }
 
diff --git a/src/mol-repr/structure/units-representation.ts b/src/mol-repr/structure/units-representation.ts
index 6eb6ba7a96985b31519468f58be4b3f989061847..5ae02a3d0581935075da83fe7c06a60edfac6491 100644
--- a/src/mol-repr/structure/units-representation.ts
+++ b/src/mol-repr/structure/units-representation.ts
@@ -167,13 +167,9 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
         if (!_structure) return false
         if (!StructureElement.Loci.is(loci) && !Link.isLoci(loci)) return false
         if (!Structure.areRootsEquivalent(loci.structure, _structure)) return false
-        if (StructureElement.Loci.is(loci)) {
-            loci = StructureElement.Loci.remap(loci, _structure)
-            if (loci.elements.length === 0) return false
-        } else if (Link.isLoci(loci)) {
-            loci = Link.remapLoci(loci, _structure)
-            if (loci.links.length === 0) return false
-        }
+        // Remap `loci` from equivalent structure to the current `_structure`
+        loci = Loci.remap(loci, _structure)
+        if (Loci.isEmpty(loci)) return false
         visuals.forEach(({ visual }) => {
             changed = visual.mark(loci, action) || changed
         })