Happy New Year!
I’ve been away for a few days because I joined an experimental project(I will wrote another blog about this). For three days, I couldn’t write or modify any code, and could only make changes using the cursor. It was a fascinating experience, but honestly, at this stage, the cursor can only handle about 90% or 95% of the work.
As a result, we managed to complete the development of the new project, but AI couldn’t make any changes to the old project. Given the rapid advancements in AI this year, I truly believe that in the next 5 years, entry-level software developers may be completely replaced by AI. So, let’s keep learning and work towards becoming senior software developers first.
The Good Old Days
The current mainstream way of implementing dropdown lists or dropdown panels is as follows:
Click a button to display the dropdown element, position it absolutely, set its z-index, and hide the dropdown list by clicking anywhere outside of it.
Each of these steps requires JavaScript, meaning the amount of JS code needed for a dropdown component is quite substantial.
Now that browsers support the native popover attribute, the traditional method of implementing dropdown lists can be considered obsolete. I can confidently say that in the future, using the popover attribute to achieve dropdown effects will definitely become the mainstream solution.
There are two main benefits:
- The code is extremely simple;
- The z-index is set to the highest level;
For example, here is the following HTML code:
<button popovertarget="targetimg">click show image</button>
<img id="targetimg" popover src="https://raw.githubusercontent.com/trevortylerlee/n1/main/n1.jpeg" />
No JavaScript is required. By clicking the button, the image will appear, and clicking anywhere outside the image will automatically hide it.
As for the top level:
This is a concept unique to the web, called “top-layer.” When an element is fullscreen, or when a <dialog>
element is displayed using the showModal() method, it behaves as a top-layer, as shown in the image below:
As the name implies, it is the top-level layer, meaning no element on the page can cover it, even with the z-index set to 999999.
A page can have multiple top-level layers. As for which one appears on top, the rule is “last one on top”—the element that is displayed last will be placed on top. This aligns with the principle of realistic user interaction design.
Based on these two points, the popover attribute is definitely the best implementation for dropdown interactions.
Example demonstration
For example, in Material Design, the dropdown effect is implemented like this:
Implementing this effect is very simple. You just need to calculate the positioning when the dropdown appears (by default, it is centered by the browser).
HTML structure example:
<div class="ui-select">
<button id="button" class="ui-select-button" popovertarget="select">
<span class="ui-select-text">please select</span>
</button>
<menu id="select" popover class="ui-select-datalist">
<li class="ui-select-datalist-li"><input type="radio" name="type" value="1">Item 1</li>
<li class="ui-select-datalist-li"><input type="radio" name="type" value="2">Item 2</li>
<li class="ui-select-datalist-li"><input type="radio" name="type" value="3" disabled>Item 3</li>
<li class="ui-select-datalist-li"><input type="radio" name="type" value="4">Item 4</li>
</menu>
</div>
Using radio buttons to simulate the selection behavior allows us to retain the form properties of the <select>
element.
For showing, hiding, and setting the layer, all of this is automatically handled by the popover attribute, so we don’t need to worry about it. Therefore, the only JavaScript code we need is actually just this.
button.onclick = function () {
const bounding = this.getBoundingClientRect();
select.style.top = (bounding.bottom + window.pageYOffset) + 'px';
select.style.left = (bounding.left + window.pageXOffset) + 'px';
select.style.width = bounding.width + 'px';
};
select.onclick = function (event) {
if (event.target.type == 'radio') {
this.hidePopover();
button.textContent = event.target.parentElement.textContent;
}
}
Is it so simple that it’s hard to believe, almost unbelievable?
Compatibility
The popover attribute is supported by all modern browsers, and it’s inevitable that it will be widely used in the near future.