-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HTML anatomy of items in the layers list needs refactoring #263
Comments
Legend links (which I personally don't think should be a thing) and the "Remove Layer" buttons are also problematic since they're interactive elements inside summary. |
This comment has been minimized.
This comment has been minimized.
Proposal for alternative layer item anatomy:<fieldset class="mapml-layer-item" aria-labelledby="mapml-layer-item-name-{1}" aria-grabbed="false">
<div class="mapml-layer-item-properties">
<label class="mapml-layer-item-toggle" title="Enable layer">
<input type="checkbox" checked />
</label>
<span class="mapml-layer-item-name" id="mapml-layer-item-name-{1}">Layer 1</span>
<div class="mapml-layer-item-controls">
<button type="button" class="mapml-layer-item-remove-control mapml-button" title="Remove layer">
<span class="mapml-button-icon" aria-hidden="true">
<!-- icon (inline SVG or CSS background-image) -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="22" width="22">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M18.3 5.71c-.39-.39-1.02-.39-1.41 0L12 10.59 7.11 5.7c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41L10.59 12 5.7 16.89c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0L12 13.41l4.89 4.89c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4z"/>
</svg>
</span>
</button>
<button type="button" class="mapml-layer-item-settings-control mapml-button" title="Layer settings" aria-expanded="false">
<span class="mapml-button-icon" aria-hidden="true">
<!-- icon (inline SVG or CSS background-image) -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="22" width="22">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
</svg>
</span>
</button>
</div>
</div>
<div class="mapml-layer-item-settings" hidden>
<details class="mapml-layer-item-opacity">
<summary id="mapml-layer-item-opacity-name-{1}">Opacity</summary>
<input type="range" min="0" max="1.0" value="1.0" step="0.1" aria-labelledby="mapml-layer-item-opacity-name-{1}" />
</details>
</div>
</fieldset> The proposed anatomy:
Required CSS(side note: builds on the generic button.mapml-button:disabled,
.mapml-button[aria-disabled="true"],
.mapml-layer-item:disabled button.mapml-button {
opacity: .3;
}
.mapml-button-icon {
pointer-events: none;
}
.mapml-button-icon svg {
fill: currentColor;
}
.mapml-layer-item,
.mapml-layer-item *,
.mapml-layer-item ::before,
.mapml-layer-item ::after {
box-sizing: border-box;
}
.mapml-layer-item {
border: 0;
margin: 0;
padding: 0;
}
.mapml-layer-item:not(:last-of-type) {
border-bottom: 1px solid #e3e3e3;
}
.mapml-layer-item-properties {
align-items: center;
display: flex;
justify-content: space-between;
}
.mapml-layer-item-controls {
margin-inline-start: auto;
}
.mapml-layer-item-controls button svg {
vertical-align: middle;
}
.mapml-layer-item-controls,
label.mapml-layer-item-toggle,
.mapml-layer-item-remove-control {
align-items: center;
display: flex;
justify-content: center;
}
.mapml-layer-item-name {
padding: .5rem;
padding-inline-start: 0;
word-break: break-word;
}
.mapml-layer-item-toggle,
.mapml-layer-item-remove-control,
.mapml-layer-item-settings-control {
min-height: 44px;
min-width: 44px;
height: 44px;
width: 44px;
}
.mapml-layer-item-settings > * {
display: block;
padding-block-start: .25rem;
padding-block-end: .25rem;
padding-inline-start: 44px;
padding-inline-end: 20px;
}
.mapml-layer-item-settings summary {
-webkit-user-select: none;
user-select: none;
}
.mapml-layer-item-opacity [type="range"] {
margin-inline-end: 0;
margin-inline-start: 0;
width: 100%;
} The required styles:
Implementation details:
Result:(from copy & pasting 2 example layer items into the existing layer control along with the required CSS)<!-- Example disabled layer item -->
<fieldset class="mapml-layer-item" aria-labelledby="mapml-layer-item-name-{1}" aria-grabbed="false" disabled>
<div class="mapml-layer-item-properties">
<label class="mapml-layer-item-toggle" title="Enable layer">
<input type="checkbox" checked />
</label>
<span class="mapml-layer-item-name" id="mapml-layer-item-name-{1}">Layer 1</span>
<div class="mapml-layer-item-controls">
<button type="button" class="mapml-layer-item-remove-control mapml-button" title="Remove layer">
<span class="mapml-button-icon" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="22" width="22">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M18.3 5.71c-.39-.39-1.02-.39-1.41 0L12 10.59 7.11 5.7c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41L10.59 12 5.7 16.89c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0L12 13.41l4.89 4.89c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4z"/>
</svg>
</span>
</button>
<button type="button" class="mapml-layer-item-settings-control mapml-button" title="Layer settings" aria-expanded="false">
<span class="mapml-button-icon" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="22" width="22">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
</svg>
</span>
</button>
</div>
</div>
<div class="mapml-layer-item-settings" hidden>
<details class="mapml-layer-item-opacity">
<summary id="mapml-layer-item-opacity-name-{1}">Opacity</summary>
<input type="range" min="0" max="1.0" value="1.0" step="0.1" aria-labelledby="mapml-layer-item-opacity-name-{1}" />
</details>
</div>
</fieldset>
<!-- Example enabled layer item with expanded settings -->
<fieldset class="mapml-layer-item" aria-labelledby="mapml-layer-item-name-{2}" aria-grabbed="false">
<div class="mapml-layer-item-properties">
<label class="mapml-layer-item-toggle" title="Enable layer">
<input type="checkbox" checked />
</label>
<span class="mapml-layer-item-name" id="mapml-layer-item-name-{2}">Layer 2, this has a longer name</span>
<div class="mapml-layer-item-controls">
<button type="button" class="mapml-layer-item-remove-control mapml-button" title="Remove layer">
<span class="mapml-button-icon" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="22" width="22">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M18.3 5.71c-.39-.39-1.02-.39-1.41 0L12 10.59 7.11 5.7c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41L10.59 12 5.7 16.89c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0L12 13.41l4.89 4.89c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4z"/>
</svg>
</span>
</button>
<button type="button" class="mapml-layer-item-settings-control mapml-button" title="Layer settings" aria-expanded="true">
<span class="mapml-button-icon" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="22" width="22">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
</svg>
</span>
</button>
</div>
</div>
<div class="mapml-layer-item-settings">
<details class="mapml-layer-item-opacity">
<summary id="mapml-layer-item-opacity-name-{2}">Opacity</summary>
<input type="range" min="0" max="1.0" value="1.0" step="0.1" aria-labelledby="mapml-layer-item-opacity-name-{2}" />
</details>
</div>
</fieldset> Thoughts? |
@Malvoz we're going to try to address this issue. After, we want to try implementing multiple Any advice you can give us beyond that you've already offered is much appreciated. Thank you! |
I will say that the proposed layer item anatomy is probably not perfect from a design point of view, though it should resolve the current accessibility issues. Also it did not take into consideration: #497, but none of our components currently do, so that should be fine. |
Are the toggles to be regarded as settings for a particular layer? The proposed anatomy allows for new types of settings as children of <div class="mapml-layer-item-settings">
<!-- opacity settings -->
<details class="mapml-layer-item-opacity">
...
</details>
<!-- new extent/projection settings can be added here (or before opacity, if it's deemed more important) -->
<details class="mapml-layer-item-projections"><!-- or what you want to call it, also doesn't have to be <details> -->
<!-- add anything you want here, e.g. input controls -->
</details>
</div> |
Not exactly. Currently, there is only one extent allowed / used per layer. When a layer is enabled, all the settings that we expose, for example, opacity or checked, apply to the whole layer, including all the templated links within the extent. What we would like to achieve is the ability to treat individual extent elements as virtual child layers of the layer, each with its own individually settable settings, including opacity and checked. In effect: nested "layers" only one level of nesting deep. The nesting, I think need only be visual, not marked up in the sense of nesting interactive elements being undesirable. We will need to think about how to achieve it in a user friendly way, but we would like the user to have ability to turn on/off individual extents (checked / unchecked), as well as set opacity for them and so on. Finally all of the extents in a layer should turn on/off or similarly respond to changes in settings of the parent |
@Malvoz is it also not recommended to have details element nested within details? |
@Anshpreet8 nesting details is fine, generally avoid nesting interactive content (including elements in the tab order due to Edit: while that's a bit contradictive since details is on that list, you can nest details: https://html5doctor.com/the-details-and-summary-elements/#:~:text=Nesting%20multiple%20%3Cdetails%3E%20elements (without causing issues for screen readers). |
@prushforth re #263 (comment): I suppose that means extents must be labelable, to expose them in a meaningful matter in the layer control? |
Added label
|
I think so. I was thinking on using the Currently the label for the layer (and therefore the singular extent) is from the |
HTML anatomy of a layer item
Nesting interactive elements inside
<summary>
is problematic:IIRC this was "fixed" due to Set<summary>
is not keyboard operable if it has descendant<label>
/<input>
when using a screen reader. This is a critical issue. I filed NVDA bug: <summary> not activatable if it has descendant <input> nvaccess/nvda#12008.role="application"
#467.<summary>
specifically may be disallowed in the future: Disallow interactive content in <summary> whatwg/html#2272.<summary>
isn't clickable using a mouse pointer due to nested<label>
, this required settingpointer-events: none
on<label>
.Refactoring the layer items is not a small task. First we need to decide on a new layout that does not entail nesting interactive elements in
<summary>
, sigh.The text was updated successfully, but these errors were encountered: