Home > Web Front-end > CSS Tutorial > Pop(over) the Balloons

Pop(over) the Balloons

Joseph Gordon-Levitt
Release: 2025-03-08 10:12:10
Original
796 people have browsed it

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):

Pop(over) the Balloons

Processing popover attribute

As long as we design it with the

attribute, any element can be used as a pop-up box: popover

<div popover="">...</div>
Copy after login
Copy after login
Copy after login
Copy after login
We don't even need to provide values ​​for

. 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. autoPopboxes are so interdependent. auto

Another option is to set

to popover value: manual

<div popover="manual">...</div>
Copy after login
Copy after login
Copy after login
Copy after login
This means that the element is manually turned on and off – we have to click a specific button to turn it on and off. In other words,

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

Use the

element as the starting point

One of the challenges of building a game with the Popover API is that the popup box is already open when you cannot load the page... If our goal is to build the game with only HTML and CSS, you can't solve this problem with JavaScript.

The

element is needed at this time. Unlike pop-up boxes, the details element can be opened by default: details

&lt;details open=&quot;&quot;&gt;&lt;/details&gt;
Copy after login
Copy after login
Copy after login
If we take this approach, we can display a bunch of buttons (balloons) and "poke" all the balloons by turning off <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>
Copy after login
Copy after login
This way we can click on the balloon in

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:

  1. The only way to turn off the <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.
  2. <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 &lt;details open=&quot;&quot;&gt;&lt;/details&gt; 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>
Copy after login
Copy after login
Copy after login
Copy after login

This is the idea when everything is connected together:

Open and close pop-up box

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>
Copy after login
Copy after login
Copy after login
Copy after login

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>popovertargetactionStyle balloon

Now we need to set the same style for

and button elements so that players can't distinguish them. Please note that I'm talking about

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>

  • First, set the <code><summary></summary> attribute to 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.
  • Safari doesn't like the same method. To remove the <code><details></details> tag here, we need to set a special vendor prefix pseudo-element, and summary::-webkit-details-marker is set to display: none;.
  • It would be great if the mouse cursor indicates that the balloon is clickable, so we can also set <code><summary></summary> on the cursor: pointer element.
  • The last detail is to set the <code><summary></summary> attribute to user-select on none to prevent the balloon (just emoji text) from being selected. This makes them more like objects on the page.
  • Yes, it's 2024 now, and we still need the prefix -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>
Copy after login
Copy after login
Copy after login
Copy after login
One problem with

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>
Copy after login
Copy after login
Copy after login
Copy after login

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.

&lt;details open=&quot;&quot;&gt;&lt;/details&gt;
Copy after login
Copy after login
Copy after login

Congratulations to the player (or not to congratulate)

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 &lt;details open=&quot;&quot;&gt;&lt;/details&gt; 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>
Copy after login
Copy after login
Copy after login
Copy after login
Here, it is great to have a

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>
Copy after login
Copy after login
Copy after login
Copy after login
If we play the game at this time, we can receive the victory message without poking all the balloons out. Again, the manual pop-up box will not close unless the correct button is clicked - even if we close its ancestor

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

&lt;details open=&quot;&quot;&gt;&lt;/details&gt;
Copy after login
Copy after login
Copy after login
Now, congratulations will only be received when the player actually wins

. 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()

But we don't want the failure message to fire when the victory screen is displayed, so we can write a selector to prevent the
<details open=""><summary>?</summary>???</details>
Copy after login
Copy after login
message from being displayed simultaneously with the

message. #fail #congrats

We need a game timer
<details open=""><summary>?</summary>?</details><div popover="manual">
  <h2>Level 1 Popup</h2>
</div>
Copy after login

Players should know how much time-popping all the balloons. We can create a rather "simple" timer with an element that takes up the full width of the screen (100vw), scales it horizontally, and matches it with the animation above, which allows the

message to fade in.

#fail

Only one failure point might make the game too simple, so let's try adding a second
<details open=""><summary>?</summary>??</details><div popover="manual">
  <h2>Level 1 Popup</h2>?
</div>
Copy after login
element and using the second "root" ID,

. 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

Summary
.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;
}
Copy after login

The only thing left is to play the game!

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!

Previous article:The Intersection of Speed and Proximity Next article:CSS Stuff I'm Excited After the Last CSSWG Meeting
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Latest Issues
Related Topics
More>
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template