Modals Are An Experience Antipattern
"An antipattern is just like a pattern, except that instead of a solution it gives something that looks superficially like a solution, but isn't one." ~ Linda Rising - The Patterns Handbook wikipedia.org/wiki/Anti-pattern
9 times out of 10
when designers/egineers
employ a modal
in an App.
they are doing so inappropriately
and inadvertently making
the experience/interface worse
for the person
.
If you are unfamiliar with them, a good place to learn is: bootstrap.com/modal
A modal
overlays information
on top of what is already displayed on the page.
It hijacks the person's focus
to what the dev wants them to see
and requires the person
to manually dismiss it
before being allowed to resume what they were doing.
This is an unwelcome interruption
to the flow and a generally horrible experience.
Modals
are a relic of the old web
where ads hijacked people's screens with pop-ups:
The situation got completely out-of-hand
and made browsing the web a horrible experience.
All modern browsers block pop-ups by default now
but designers/devs who don't respect
the people
using their site/app
still reach for modals
for hijacking attention.
Modals are almost never a good way of displaying information.
Modals in Phoenix
?
Phoenix 1.7
added the new
modal
component.
We really wish the creators of Phoenix
had not done it
because it will inevitably be misused.
Naive devs who mean well
but haven't studied UX,
will use a modal
when a basic <div>
would be considerably better.
It is used by default
for inserting new content:
This is a horrible experience.
The New Item
modal
overlays the Listing Items
page
instead of just showing a New Item
page.
This adds absolutely no value to the person
inputing the item
;
it's just a distraction.
This shows that the devs building
Phoenix
have not done very much UX/Usability testing
because this would immediately confuse
an older less tech-savvy person.
They would ask is this page "Listing Items"
or is it allowing me to create a "New Item"?
And if they accidentally clicked/tapped
on the "X" they would lose the text they inputted.
Horrible.
Quick Example
After executing the mix phx.gen.auth
command
and then running the project with:
mix phx.server
The following 2 links are added to the header of home page:
The code that creates these links is: /lib/auth_web/components/layouts/root.html.heex#L15-L55
Clicking on the register
link we navigate to: http://localhost:4000/people/register
Here we can enter an Email
and Password
to and click on the Create an account
button:
This redirects us back to the homepage http://localhost:4000/
and we see the following modal
:
The person viewing this screen
has to manually dismiss
the modal
in order to see
the content that is relevant to them:
Inspecting the DOM
of the page in our browser:
We see that the <div id="flash"
has the following HTML
:
<div id="flash" phx-mounted="[["show",{"display":null,"time":200,"to":"#flash","transition":[["transition-all","transform","ease-out","duration-300"],["opacity-0","translate-y-4","sm:translate-y-0","sm:scale-95"],["opacity-100","translate-y-0","sm:scale-100"]]}]]" phx-click="[["push",{"event":"lv:clear-flash","value":{"key":"info"}}],["hide",{"time":200,"to":"#flash","transition":[["transition-all","transform","ease-in","duration-200"],["opacity-100","translate-y-0","sm:scale-100"],["opacity-0","translate-y-4","sm:translate-y-0","sm:scale-95"]]}]]" role="alert" class="fixed hidden top-2 right-2 w-80 sm:w-96 z-50 rounded-lg p-3 shadow-md shadow-zinc-900/5 ring-1 bg-emerald-50 text-emerald-800 ring-emerald-500 fill-cyan-900" style="display: block;">
<p class="flex items-center gap-1.5 text-[0.8125rem] font-semibold leading-6">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" clip-rule="evenodd"></path>
</svg>
Success!
</p>
<p class="mt-2 text-[0.8125rem] leading-5">Person created successfully.</p>
<button type="button" class="group absolute top-2 right-1 p-2" aria-label="close">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="h-5 w-5 stroke-current opacity-40 group-hover:opacity-70" fill="currentColor" viewBox="0 0 24 24">
<path fill-rule="evenodd" d="M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z" clip-rule="evenodd"></path>
</svg>
</button>
</div>
This is a lot of code
just to inform the person
that the successfully registered.
We know there's a much better way. We will be demonstrating it in the next few pages.
For now, we're just going to remove the line:
<.flash_group flash={@flash} />
From the file:
/lib/auth_web/components/layouts/app.html.heex#L40
To remove all flash
modals.
And just like magic,
the tests that were failing previously,
because the modal
(noise)
was covering the email
address,
now pass:
mix test
Compiling 2 files (.ex)
The database for Auth.Repo has already been created
19:08:47.892 [info] Migrations already up
..........................................................
.........................................................
Finished in 0.5 seconds (0.3s async, 0.1s sync)
115 tests, 0 failures
With all tests passing,
we can finally get on
with building Auth
!