diff --git a/bricktracker/part.py b/bricktracker/part.py
index af901b2b..c847db58 100644
--- a/bricktracker/part.py
+++ b/bricktracker/part.py
@@ -73,7 +73,7 @@ class BrickPart(RebrickablePart):
 
     # A identifier for HTML component
     def html_id(self) -> str:
-        components: list[str] = []
+        components: list[str] = ['part']
 
         if self.fields.figure is not None:
             components.append(self.fields.figure)
diff --git a/static/styles.css b/static/styles.css
index ee82ffe0..0651e203 100644
--- a/static/styles.css
+++ b/static/styles.css
@@ -46,7 +46,7 @@
     object-fit:contain;
 }
 
-.table-td-missing {
+.table-td-input {
     max-width: 150px;
 }
 
diff --git a/templates/macro/form.html b/templates/macro/form.html
index cd126e9f..f88b6731 100644
--- a/templates/macro/form.html
+++ b/templates/macro/form.html
@@ -16,8 +16,13 @@
   {% endif %}
 {% endmacro %}
 
-{% macro input(id, html_id, url, value) %}
-  <input class="form-control form-control-sm flex-shrink-1" type="text" value="{% if value %}{{ value }}{% endif %}"
+{% macro input(name, id, prefix, url, value, all=none, read_only=none) %}
+  {% if all or read_only %}
+    {{ value }}
+  {% else %}
+    <label class="visually-hidden" for="{{ prefix }}-{{ id }}">{{ name }}</label>
+    <div class="input-group">
+      <input class="form-control form-control-sm flex-shrink-1" type="text" id="{{ prefix }}-{{ id }}" value="{% if value %}{{ value }}{% endif %}"
   {% if g.login.is_authenticated() %}
       onchange="change_part_missing_amount(this, '{{ id }}', '{{ html_id }}', '{{ url }}')"
   {% else %}
@@ -25,8 +30,10 @@
   {% endif %}
       autocomplete="off">
   {% if g.login.is_authenticated() %}
-    <span id="status-part-{{ id }}-{{ html_id }}" class="input-group-text ri-save-line"></span>
+        <span id="status-{{ prefix }}-{{ id }}" class="input-group-text ri-save-line"></span>
   {% else %}
     <span class="input-group-text ri-prohibited-line"></span>
+      {% endif %}
+    </div>
   {% endif %}
 {% endmacro %}
diff --git a/templates/part/table.html b/templates/part/table.html
index b7139ede..692a7dc6 100644
--- a/templates/part/table.html
+++ b/templates/part/table.html
@@ -28,14 +28,8 @@
           {% endif %}
         {% endif %}
         {% if not no_missing %}
-          <td {% if not all %}id="sort-part-{{ item.fields.id }}-{{ item.html_id() }}" data-sort="{{ item.fields.total_missing }}"{% endif %} class="table-td-missing">
-            {% if all or read_only_missing %}
-              {{ item.fields.total_missing }}
-            {% else %}
-            <div class="input-group">
-              {{ form.input(item.fields.id, item.html_id(), item.url_for_missing(), item.fields.total_missing) }}
-            </div>
-            {% endif %}
+          <td data-sort="{{ item.fields.total_missing }}" class="table-td-input">
+            {{ form.input('Missing', item.fields.id, item.html_id(), item.url_for_missing(), item.fields.total_missing, all=all, read_only=read_only_missing) }}
           </td>
         {% endif %}
         {% if all %}