Home > Mobile >  How can I use the CSS :target selector to create a reusable modal box
How can I use the CSS :target selector to create a reusable modal box

Time:06-29

I have a large collection of proverbs from an endangered language and I'd like to use a modal box for each to make different transcriptions available, without cluttering the page. I've created a div element that expands to show the optional information when clicked on using the CSS :target selector, and I'd like to be able to use that code over and over again for each proverb without creating an unique class or ID for each proverb. The problem is that clicking on a proverb in the middle of the list only expands the first div box. Is there a way to get the div box to open for each proverb that's clicked on without creating a unique expandable div for each proverb (I have hundreds of them)?

Here's the code I used:

#modalBox {
  display: block;
  position: relative;
  text-align: left;
  overflow: hidden;
  background: #ffffff;
  transition: all 0.4s;
  padding: 5px;
  margin-bottom: 2rem;
  height: 2.5rem;
  width: 100%;
  max-width: 800px;
}

#modalBox:target {
  height: 13.5rem;
}
<div >
  <div id="modalBox">
    <a href="#modalBox"> A (g)attë mbrèšarolë facë i (g)attarièddë cëcatë.</a>
    <p id="data"><b>IPA:</b> a atːə mˌbɾɪʃəˈɾolə fat͡ʃ i ˈatːaɾiˌɛdːə t͡ʃə katʰ</p>
    <p id="data"><b>Italian:</b> La gatta frettolosa fa i gattini ciechi.</p>
    <p id="data"><b>English:</b> The hasty cat makes blind kittens.</p>
    </p>
    <a href="#" >&times;</a>
  </div>
</div>

CodePudding user response:

I'm not sure how you could do this cleanly without at least some JavaScript. Here is a vanilla implementation to get you started. Instead of targeting precise ids, we can use a class name instead, and let the interpreter figure out which id is the clicked one.

The JavaScript runs through the HTML, dynamically adding incrementing ids (e.g., modalBox0, modalBox1, etc.) and the corresponding link which opens each modal (e.g., href='#modalBox0', href='#modalBox1', etc.).

const modals = Array.from(document.querySelectorAll('.modalBox'))

modals.forEach((modal, index) => {
  const id = `modalBox${index}`;
  modal.id = id
  const link = modal.querySelectorAll('a')[0];
  link.setAttribute('href', `#${id}`)
})
.modalBox {
  display: block;
  position: relative;
  text-align: left;
  overflow: hidden;
  background: #ffffff;
  transition: all 0.4s;
  padding: 5px;
  margin-bottom: 2rem;
  height: 2.5rem;
  width: 100%;
  max-width: 800px;

}

.modalBox:target {
  height: 13.5rem;
}
<div >
  <div >
    <a href="#"> A (g)attë mbrèšarolë facë i (g)attarièddë cëcatë.</a>
    <p id="data"><b>IPA:</b> a atːə mˌbɾɪʃəˈɾolə fat͡ʃ i ˈatːaɾiˌɛdːə t͡ʃə katʰ</p>
    <p id="data"><b>Italian:</b> La gatta frettolosa fa i gattini ciechi.</p>
    <p id="data"><b>English:</b> The hasty cat makes blind kittens.</p>
    <a href="#" >&times;</a>
  </div>

  <div >
    <a href="#"> A (g)attë mbrèšarolë facë i (g)attarièddë cëcatë.</a>
    <p id="data"><b>IPA:</b> a atːə mˌbɾɪʃəˈɾolə fat͡ʃ i ˈatːaɾiˌɛdːə t͡ʃə katʰ</p>
    <p id="data"><b>Italian:</b> La gatta frettolosa fa i gattini ciechi.</p>
    <p id="data"><b>English:</b> The hasty cat makes blind kittens.</p>
    <a href="#" >&times;</a>
  </div>
</div>

jsFiddle

CodePudding user response:

There are several CSS-first approaches to producing this effect (which do without javascript mostly or entirely).

But one approach barely relies even on CSS: it's an HTML-first solution.

The details / summary pair of elements are the perfect semantic markup for presenting this kind of information.


Working Example:

.modalBox {
  display: block;
  position: relative;
  width: min(98%, 800px);
  padding: 5px;
  overflow: hidden;
}

.modalBox summary {
  font-style: italic;
  cursor: pointer;
}

.modalBox p {
  transform: translateY(30vh);
  transition: transform 0.3s linear;
}

.modalBox[open] p {
  transform: translateY(0);
}
<div >
  <details >
    <summary> A (g)attë mbrèšarolë facë i (g)attarièddë cëcatë.</summary>
    <p data-lang="ipa"><b>IPA:</b> a atːə mˌbɾɪʃəˈɾolə fat͡ʃ i ˈatːaɾiˌɛdːə t͡ʃə katʰ</p>
    <p data-lang="it"><b>Italian:</b> La gatta frettolosa fa i gattini ciechi.</p>
    <p data-lang="en"><b>English:</b> The hasty cat makes blind kittens.</p>
  </details>
  
  <details >
    <summary> A (g)attë mbrèšarolë facë i (g)attarièddë cëcatë.</summary>
    <p data-lang="ipa"><b>IPA:</b> a atːə mˌbɾɪʃəˈɾolə fat͡ʃ i ˈatːaɾiˌɛdːə t͡ʃə katʰ</p>
    <p data-lang="it"><b>Italian:</b> La gatta frettolosa fa i gattini ciechi.</p>
    <p data-lang="en"><b>English:</b> The hasty cat makes blind kittens.</p>
  </details>
  
  <details >
    <summary> A (g)attë mbrèšarolë facë i (g)attarièddë cëcatë.</summary>
    <p data-lang="ipa"><b>IPA:</b> a atːə mˌbɾɪʃəˈɾolə fat͡ʃ i ˈatːaɾiˌɛdːə t͡ʃə katʰ</p>
    <p data-lang="it"><b>Italian:</b> La gatta frettolosa fa i gattini ciechi.</p>
    <p data-lang="en"><b>English:</b> The hasty cat makes blind kittens.</p>
  </details>
</div>


Further Reading:

  • Related