Skip to content

Instantly share code, notes, and snippets.

@duanemoody
Last active August 12, 2019 06:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duanemoody/710565581de47afce0e7e28cd8549287 to your computer and use it in GitHub Desktop.
Save duanemoody/710565581de47afce0e7e28cd8549287 to your computer and use it in GitHub Desktop.
HTML6, a work in progress
<form action="">
<fieldset>
<legend>Payment method:</legend>
<p>
<input
aria-controls="cc tfx fep"
aria-expanded="true"
type="radio" name="howpay" value="myself" id="howpay_0" checked required />
<label for="howpay_0">Paying myself by credit card</label><br>
<input
aria-controls="spc tfx"
aria-expanded="false"
type="radio" name="howpay" value="account" id="howpay_1" />
<label for="howpay_1">Charge account: </label>
</p>
<div role="region" aria-relevant="additions removals" aria-live="polite">
<!-- toggled-item is a wrapper element for aria-controls to point to. The default for a toggled-item is display:none unless the optional SHOW attribute (no arguments) is present. jQuery's hide/show methods inline STYLE attributes instead of attaching/removing a class.
Like many HTML5 syntactical elements, toggled-item is not meant to be used as a styled element although the HTML6 framework does internally use display: properties to hide and show them. -->
<toggled-item id="cc" show>
<label for="mycc">Credit card number: </label>
<input type="luhn" name="mycc" id="mycc" required />
</toggled-item>
<toggled-item id="spc">
<label for="speedchart">Choose speedchart: </label>
<select name="speedchart" id="speedchart" required>
<option></option>
<option>123456</option>
<option>654321</option>
<option>987654</option>
</select>
</toggled-item>
</div>
</fieldset>
<fieldset>
<legend>Options:</legend>
<p>
<input type="checkbox" name="customization" value="mushrooms" id="customization_0"><label for="customization_0">Mushrooms</label>
<input aria-expanded="false" aria-controls="peppers" type="checkbox" id="customization_1"><label for="customization_1">Peppers</label>
<input aria-expanded="false" aria-controls="custinst" type="checkbox" name="customization" value="specrequest" id="customization_2"><label for="customization_2">Special request</label>
<div role="region" aria-relevant="additions removals" aria-live="polite">
<toggled-item id="peppers">
<div>
<input type="checkbox" name="customization" value="green peppers" id="customization_3"><label for="customization_3">Green Peppers</label><br>
<input type="checkbox" name="customization" value="banana peppers" id="customization_4"><label for="customization_4">Banana Peppers</label></div>
</toggled-item>
<toggled-item id="custinst">
<div><label for="instructions">Instructions: </label><textarea name="instructions" id="instructions"></textarea></div>
</toggled-item>
</div>
</p>
</fieldset>
</form>
<details>
<summary>Overview:</summary>
<!-- https://inclusive-components.design/toggle-button/ -->
<p>HTML 3.0 brought forms to what was initially a specification for technical documents, but as application developers eventually realized, the form elements introduced weren't in any sense interactive and they had to write (and recycle) custom JavaScript event handlers to make these forms behave as they do in applications. <br>Four iterations of the HTML spec later, the <em>number</em> of form elements has marginally increased, but still with little attention paid to real-world use cases. <em>Forms in web applications aren't static documents.</em></p>
<p>HTML5's web components are only now beginning to attach behaviors to both existing and custom form elements (that can finally directly submit contents alongside native form elements), but the syntax is still variably self-evident, meaning these components aren't necessarily extending spec.</p>
<p>HTML6 aims to go the next step, providing developers with clear HTML syntax that defines interactive form elements without them writing any JS, classing elements or imposing naming conventions on attributes. Through the use of ARIA-/regular HTML attribute values, one CSS selector and a <small>tiny</small> JS shim, interactive elements actually <strong>know</strong> their relationship to each other and what they're supposed to <strong>do</strong>. And so will developers. </p>
<details>
<summary>Goals:</summary>
<ul>
<li>Clean, self-evident markup that looks like HTML because it <em>is</em> HTML</li>
<li>Coding unnecessary to implement feature set</li>
<li>Least conflict with existing CSS/JS frameworks</li>
<li>Minimal dependence on trendy but syntactically meaningless methods such as:</li>
<ul>
<li>prebaked class names</li>
<li>naming conventions for name/ID attribute values</li>
<li>&quot;data-&quot; attributes</li>
</ul>
<li>Page load presentation state 99% managed through pure HTML/CSS to minimize <a href="https://en.wikipedia.org/wiki/Flash_of_unstyled_content" target="_blank">Flash Of Unstyled Content</a> issues</li>
<li>Minimal overhead: one CSS class and a JS shim</li>
<li>(Custom) wrapper elements only where unavoidable</li>
</ul>
</details>
<details>
<summary>Features:</summary>
<ul>
<li><em>Implemented:</em> Controls which toggle other sections; <code>ARIA-expanded</code> attribute automatically added and updated live</li>
<li><em>TBD:</em> Expandable/contractable templated sections</li>
<li><em>TBD:</em> Formulas for instant calculation</li>
<li><em>TBD:</em> Custom &quot;luhn&quot; <code>type</code> for input field with Luhn validation (<em>e.g.</em> credit cards)</li>
<li><em>TBD:</em> <code>:required</code> attribute to automatically bubble up to associated <code>label</code> whether implicit by wrapping or explicit through <code>FOR</code> attribute, so that CSS-based markers can be defined without classes and update live when a field's required status changes</li>
</ul>
</details>
<details>
<summary>Structure:</summary>
<ul>
<li>ARIA as syntactical foundation to avoid duplication and serve assisted first</li>
<li>Behaviors defined through existing attributes/values with a minimum of wrapper elements</li>
</ul></details></details>
$(document).ready(function() {
//minimalshim, presently radio/checkbox toggling other elements whose IDs are enumerated in aria-controls
$("body").on("change","input[aria-controls]",function(){
var mycontrols = '#' + $(this).attr('aria-controls').split(' ').join(',#');
switch ($(this).attr("type")) {
case 'radio':
var allcontrols = '#' + $('input[name="' + $(this).attr("name") + '"]').map(function() {return this.ariaControls;}).get().join(' ').split(' ').join(',#');
$(allcontrols).not($(mycontrols)).removeAttr('show');
$(mycontrols).attr('show','');
$('input[name="'+$(this).attr("name")+'"]').attr('aria-expanded','false');
break;
case 'checkbox':
$(mycontrols).toggle(); //you saw nothing here, this will be converted to an actual SHOW attribute toggle
break;
}
$(this).attr('aria-expanded',$(this).is(':checked'));
});
//$("input[aria-controls]").attr('aria-expanded',$(this).is(':checked'));
//$("input:checked").trigger("change");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
/* the framework */
toggled-item:not([show]) {display: none;}
/* yep, that's it! */
/* this document */
body{font-family:system-ui,-apple-system;}
legend,summary{font-weight:bold;}
fieldset{width:45%; display:inline-block; vertical-align:top;}
details>details{margin-left:2em;}
details>ul{margin-top:0;}
summary::-webkit-details-marker{color:blue;
}
textarea#instructions{display:block; width:90%; height:8rem;}
label[for=instructions]{display:block; margin-top:1em;}
form{margin-bottom:2em;}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment