The power of HTML and CSS is always amazing. The new interactive features of the Popover API once again prove the amazing results that can be achieved with both languages alone.
You may have seen other tutorials showing the capabilities of the Popover API, but this post focuses more on "complete conquest". We will add some extra "fun" elements, such as balloons...some literal "blasting" effects.
I created a game using HTML and CSS only (of course) and rely on the Popover API. Your mission is to poke as many balloons as possible in one minute. But be careful! Some balloons (as Guru said) are "crawling" and trigger more balloons.
I cleverly named it Pop(over) the Balloons and we will make it step by step together. Once done, it will look like (well, exactly like this):
attribute, any element can be used as a pop-up box: popover
<div popover="">...</div>
. By default, the initial value of popover
is popover
and uses what is called "lightweight shutdown" in the specification. This means that the pop-up box can be closed by clicking anywhere outside the pop-up box. When the popup box is open, any other popup box on the page closes unless they are nested together. auto
Popboxes are so interdependent. auto
to popover
value: manual
<div popover="manual">...</div>
creates a stubborn popup that only closes when you click the correct button and is completely independent of the other popups on the page. manual
The
element is needed at this time. Unlike pop-up boxes, the details
element can be opened by default: details
<details open=""></details>
<p></p>
until the last one. In other words, we can place the starting balloons in the open <code><details></details>
element so that they are displayed when the page is loaded. <code><details></details>
This is what I call the basic structure:
<details open=""><summary>?</summary>???</details>
to close <code><summary></summary>
and "poke" all button balloons, leaving a balloon (the last <code><details></details> (we'll address how to remove it later). <code><summary></summary>
You might think <dialog></dialog>
is a more semantic direction for our game, you are right. But there are two disadvantages to using <dialog></dialog>
, which we cannot use here:
<dialog></dialog>
that is open when the page is loading is to use JavaScript. As far as I know, there is no way we can add to the game to turn off the <dialog></dialog>
that is turned on when the page is loading. <dialog></dialog>
is modal and prevents clicking on other content when opened. We need to allow players to poke balloons outside of <dialog></dialog>
to defeat the timer. So we will use the <details open=""></details>
element as the top container for the game and the normal <div> as the popup itself, i.e. <code><div popover="">. For now, we just need to make sure that all of these pop-up boxes and buttons are connected together so that clicking the button opens the pop-up box. You may have learned this from other tutorials, but we need to tell the popup element which button it needs to respond to, and then tell the button which popup it needs to open. To do this, we provide a unique ID for the pop-up element (all IDs should be) and then reference it on the button using the <code>popovertarget
attribute:
<div popover="">...</div>
This is the idea when everything is connected together:
A little more work is needed in the last demonstration. One drawback of the game so far is that clicking the popup button will open more popups; clicking the same button again and they will disappear. This makes the game too simple.
We can separate the opening and closing behavior by setting the popovertargetaction
attribute on the button (no, HTML specification authors don't care about simplicity). If we set the property value to show
or hide
, the button will only perform one action on that particular pop-up.
<div popover="manual">...</div>
Note that I have added a new button in <div> which is set to target another <code><div>, which is turned on or off by intentionally setting the <em> property above. See how challenging it is to "poke through" the element (in a good way): </em>
<code>popovertargetaction
Style balloon
and not <code><summary></summary>. This is because <code><summary></summary> is the actual element of the container we click to open and close. <code><details></details> <code><summary></summary>Most of the work is standard CSS work: set background, fill, margin, size, border, etc. But there are some important things that are not necessarily intuitive and need to be included. <code><details></details>
list-style-type
on the none
element to remove the triangle mark indicating whether <code><details></details> is on or off. The tag is very useful and is very good by default, but for games like this it's better to remove the prompt for a better challenge. summary::-webkit-details-marker
is set to display: none;
. cursor: pointer
element. user-select
on none
to prevent the balloon (just emoji text) from being selected. This makes them more like objects on the page. -webkit-user-select
attribute to consider Safari support. Thanks, Apple. Put all this code in the <code><summary></summary> class that we will use for buttons and .balloon
elements:
<div popover="">...</div>
Balloons is that some of them are intentionallydo nothing. This is because their closed popup boxes are not open. Players may think they have not clicked/clicked on a specific balloon or the game is broken, so let's add some zoom when the balloon is in the :active
state of clicking:
<div popover="manual">...</div>
Bonus: Because the cursor is a hand pointing to its index finger, clicking on a balloon is a bit like poking a balloon with your finger. ???
The way we distribute balloons on the screen is another important factor to consider. Without JavaScript, we can't place them randomly, so this is impossible. I've tried a lot of ways, such as creating my own "random" numbers, defined as custom properties that can be used as multipliers, but I can't get the overall "random" effect without overlapping the balloons or building some kind of visual pattern.
I ended up using a class to locate balloons in different rows and columns - not like CSS grids or multiple columns, but fictitious rows and columns based on physical interpolation. It looks a bit like a grid and is not as "random" as I want it to be, but as long as no balloons have the same two classes, they don't overlap each other.
I decided to use an 8×8 grid, but left the first "row" and "column" blank so that the balloon doesn't obscur the left and upper edges of the browser.
<details open=""></details>
We have most of the game components ready, but it's better to have a win pop-up box congratulating the player on successfully poking all the balloons within the specified time.
Everything goes back to the <details open=""></details>
element. Once the element is not open, the game should end, and the last step is to poke the last balloon. So if we give the element an ID, e.g. , we can create a condition that hides it using #root
when it is not open: display: none;
<div popover="">...</div>
pseudo-selector because we can use it to select the parent element of the :has()
element so that when #root
is closed, we can select the child element of that parent element—a new element with #root
ID—to display a pseudo-pop-up box that shows the congratulations message to the player. (Yes, I know it's ironic.) #congrats
<div popover="manual">...</div>
element. <code><details></details>
Is there a way to know in CSS if the pop-up box is still open? Yes, enter pseudo-class. :popover-open
Pseudo-class selects an open pop-up box. We can use this in conjunction with the previous :popover-open
to prevent messages from appearing when the pop-up box is still open on the page. Here is how to link these together to work like a :has()
conditional statement. and
<details open=""></details>
. In contrast, if the player cannot poke all balloons before the one-minute timer expires, we should notify the player of the end of the game. Since we don't have a
conditional statement in CSS (at least not yet), we will run a one-minute animation so that this message fades in to end the game.
if()
<details open=""><summary>?</summary>???</details>
message. #fail
#congrats
<details open=""><summary>?</summary>?</details><div popover="manual"> <h2>Level 1 Popup</h2> </div>
#fail
<details open=""><summary>?</summary>??</details><div popover="manual"> <h2>Level 1 Popup</h2>? </div>
. Similarly, we can use <code><details></details> to check whether neither #root2
and :has
elements are open, and then the #root
message is displayed. #root2
#congrats
.balloon { background-color: transparent; border: none; cursor: pointer; display: block; font-size: 4em; height: 1em; list-style-type: none; margin: 0; padding: 0; text-align: center; -webkit-user-select: none; /* Safari fallback */ user-select: none; width: 1em; }
Funny, right? I'm sure we can build something stronger without self-imposed JavaScript method restrictions, and we're not taking accessibility seriously, but pushing the API to the limit is both fun and educational, right? I'm interested: What other weird ideas can you think of to use popup boxes? Maybe you think of another game, some pretty UI effects, or some clever way to combine pop-up boxes with other emerging CSS features like anchor positioning. Whatever it is, please share!
The above is the detailed content of Pop(over) the Balloons. For more information, please follow other related articles on the PHP Chinese website!