diff --git a/src/js/custom/inputWithoutLabelHasTitle.js b/src/js/custom/inputWithoutLabelHasTitle.js
new file mode 100644
index 000000000..2f0b75e32
--- /dev/null
+++ b/src/js/custom/inputWithoutLabelHasTitle.js
@@ -0,0 +1,9 @@
+quail.inputWithoutLabelHasTitle = function() {
+ quail.html.find('input, select, textarea').each(function() {
+ if(!$(this).parent('label').length &&
+ !quail.html.find('label[for=' + $(this).attr('id') + ']').length &&
+ (!$(this).attr('title') || !quail.containsReadableText($(this).attr('title')))) {
+ quail.testFails('inputWithoutLabelHasTitle', $(this));
+ }
+ });
+};
\ No newline at end of file
diff --git a/src/resources/tests.yml b/src/resources/tests.yml
index a6683f5c3..276003eba 100644
--- a/src/resources/tests.yml
+++ b/src/resources/tests.yml
@@ -2404,6 +2404,33 @@ inputTextValueNotEmpty:
en: "Text\" input elements require a non-whitespace default text"
description:
en: "All input
elements with a type of \"text\" should have a default text which is not empty."
+inputWithoutLabelHasTitle:
+ type: "custom"
+ callback: "inputWithoutLabelHasTitle"
+ components:
+ - "placeholder"
+ testability: 1
+ tags:
+ - "form"
+ - "content"
+ guidelines:
+ wcag:
+ 1.1.1:
+ techniques:
+ - "H65"
+ 1.3.1:
+ techniques:
+ - "H65"
+ 3.3.2:
+ techniques:
+ - "H65"
+ 4.1.2:
+ techniques:
+ - "H65"
+ title:
+ en: "Form controls without label should have a title attribute"
+ description:
+ en: "If it is not possible to have a label for a form control, then a title attribute on the element should be provided that describes the purpose of the control."
labelDoesNotContainInput:
selector: "label:has(input)"
tags:
diff --git a/test/quail.html b/test/quail.html
index a1831c804..800d560e5 100644
--- a/test/quail.html
+++ b/test/quail.html
@@ -381,6 +381,8 @@
"testfiles/common/inputTextHasValue-pass.html",
"testfiles/common/inputTextValueNotEmpty-fail.html",
"testfiles/common/inputTextValueNotEmpty-pass.html",
+ "testfiles/common/inputWithoutLabelHasTitle-pass.html",
+ "testfiles/common/inputWithoutLabelHasTitle-fail.html",
"testfiles/common/labelDoesNotContainInput-fail.html",
"testfiles/common/labelDoesNotContainInput-pass.html",
"testfiles/common/labelMustBeUnique-fail.html",
diff --git a/test/testfiles/common/inputWithoutLabelHasTitle-fail.html b/test/testfiles/common/inputWithoutLabelHasTitle-fail.html
new file mode 100644
index 000000000..1263262a5
--- /dev/null
+++ b/test/testfiles/common/inputWithoutLabelHasTitle-fail.html
@@ -0,0 +1,35 @@
+
+
+
+
+