What is your opinion of no js modals?

I came across this:

/* 

The main content is inside of our <main> element.

Make it fill the whole window and be scrollable - body should not scroll.

*/

body {
	margin: 0;
	padding: 0;	
	overflow: hidden;
}
.content {
	position: fixed;
	top: 0;
	left: 0;
	bottom: 0;
	right: 0;
	overflow: scroll;
}

/*

Modals should cover the whole screen, but be hidden by default.

When we click a link to #ModalName, #ModalName becomes the :target element and we can use this selector to give it new styles, like display:block;

Notice our "Close" links have an href of "#", which means none of our modals are now the :target. They will now all fall back to the basicl .modal styling.

*/
.modal {
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	right: 0;
	display: none;
	opacity: 0;
	overflow: scroll;
}
.modal:target {
	display: block;
	z-index: 2;
	opacity: 1;
}
.popup:target ~ .content {
	overflow: hidden;
}


/* 	----------------------------
		
      Styling just for funsies. 
      You can ignore this. 

	-------------------------------	*/

body {
	font-family: helvetica, arial, sans-serif;
	font-weight: 100;
	text-align: center;
	color: #FFF;
}

.content {
	background-color: #EDEBEE;
}
.modal-exit,
.modal-exit:hover {
	position: fixed;
	top: 0;
	right: 0;
	width: 1em;
	height: 1em;
	z-index: 10;
	padding: 0.3em;
	font-size: 2em;
	line-height: 1em;
	text-decoration: none;
	color: #FFF;
}
.modal-exit:hover {
	background-color: rgba(255,255,255, 0.3);
}

.modal-open,
.modal-open:hover {
	display: block;
	width: 10em;
	margin: 1em auto;
	padding: 2em 1em;
	border: 1px solid #806973;
	background-color: #FFF;
	font-size: 2em;
	text-align: center;
	text-decoration: none;
	color: #806973;
	box-shadow: 0 0 10px 1px #CCC;
}
.modal-open:hover {
	box-shadow: 0 0 10px 1px #999;
}

.modal-title {
	font-size: 3em;
	font-weight: 100;
}
.modal-description {
	padding: 1em;
	font-size: 1.2em;
	letter-spacing: 0.1em;
	color: #EDEBEE;
}

.bg--purple {
	background-color: #806973;
}
.bg--blue {
	background-color: #696E80;
}
.bg--red {
	background-color: #806969;
}
.bg--green {
	background-color: #69807D;
}
<section class="modal bg--purple" role="dialog" id="modalA" aria-labelledby="modalA-title" aria-describedby="modalA-description">
	<a href="#" class="modal-exit" title="close">&times;</a>
	<h1 id="modalA-title" class="modal-title">Modal A</h1>
	<p id="modalA-description" class="modal-description">Lots of fun things in here to see.</p>
</section>

<section class="modal bg--blue" role="dialog" id="modalB" aria-labelledby="modalB-title" aria-describedby="modalB-description">
	<a href="#" class="modal-exit" title="close">&times;</a>
	<h1 id="modalB-title" class="modal-title">Modal B</h1>
	<p id="modalB-description" class="modal-description">Lots of fun things in here to see.</p>
</section>

<section class="modal bg--red" role="dialog" id="modalC" aria-labelledby="modalC-title" aria-describedby="modalC-description">
	<a href="#" class="modal-exit" title="close">&times;</a>
	<h1 id="modalC-title" class="modal-title">Modal C</h1>
	<p id="modalC-description" class="modal-description">Lots of fun things in here to see.</p>
</section>

<section class="modal bg--green" role="dialog" id="modalD" aria-labelledby="modalD-title" aria-describedby="modalD-description">
	<a href="#" class="modal-exit" title="close">&times;</a>
	<h1 id="modalD-title" class="modal-title">Modal D</h1>
	<p id="modalD-description" class="modal-description">Lots of fun things in here to see.</p>
</section>

<section class="modal bg--purple" role="dialog" id="modalE" aria-labelledby="modalE-title" aria-describedby="modalE-description">
	<a href="#" class="modal-exit" title="close">&times;</a>
	<h1 id="modalE-title" class="modal-title">Modal E</h1>
	<p id="modalE-description" class="modal-description">Lots of fun things in here to see.</p>
</section>

<main class="content">

	<a href="#modalA" class="modal-open">
    View Modal A
  </a>
	<a href="#modalB" class="modal-open">
    View Modal B
  </a>
	<a href="#modalC" class="modal-open">
    View Modal C
  </a>
	<a href="#modalD" class="modal-open">
    View Modal D
  </a>
	<a href="#modalE" class="modal-open">
    View Modal E
  </a>

</main>

Would it make sense or be ideal to replace the js with css here, or no?

Also, is this something that would be simple to figure out how to do?

Here is my html:

    <div class="outer-containerB">
      <div class="containerB">
        <div class="buttonContainerA">
        </div>
        <button class="exitD" type="button" title="Exit" aria-label="Exit"></button>
        <div id="lb" class="modal">
          <div class="inner-modal">
            <div class="buttonContainerB">
              <a href="#" class="linkButton btnB-primary btnB" target="_blank">text</a>
              <a href="#" class="linkButton btnB-primary btnB" target="_blank">text</a>
              <a href="#" class="linkButton btnB-primary btnB" target="_blank">text</a>
            </div>
            <button class="close" title="Close" aria-label="Close">&times;</button>
          </div>
        </div>
      </div>
    </div>

This could be done using CSS?

In my js code I am using this:

(function manageLinkButtonOpen() {

    function openModal(target) {
        const modal = document.querySelector(target);
        modal.classList.add("active");
    }

    function addLinkToButton() {
        const modalButton = document.querySelector(".linkButton");
        modalButton.addEventListener("click", function (event) {
            //const target = event.currentTarget.dataset.destination;
            //openModal(target);
            openModal(event.currentTarget.dataset.destination);
        });
    }
    addLinkToButton();

}());

(function manageLinkButtonClose() {

    function closeModal(modal) {
        modal.classList.remove("active");
    }

    function addCloseEventToModal() {
        const closeModals = document.querySelectorAll(".close");

        closeModals.forEach(function (modal) {
            modal.addEventListener("click", function () {
                //closeModal(event.target.closest(".modalB"));
                closeModal(document.querySelector(".modal"));
            });
        });
    }
    addCloseEventToModal();
}());

My css:

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: #121212;
  padding: 0 8px 0;
}

body:has(.modal.active) {
  overflow: hidden;
}

button,
a {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

.outer-containerA {
  background: #181d38;;
}

.outer-containerA,
.outer-containerB,
.modal {
  display: flex;
  position: fixed;
  inset: 0;
  overflow: auto;
  /* Enable scroll if needed */
}

.buttonContainerA,
.buttonContainerB {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  max-width: 569px;
  gap: 10px;
}

.playButton,
.linkButton {
  flex-basis: 183px;

  /* 
  width of each button */
  margin: 0;

  /* 
  spacing between buttons */
  cursor: pointer;
}

.modal {
  display: flex;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  overflow: auto;
  /*background: rgba(0, 0, 0, 0.4);*/
  transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;
  transform: translate(0, -25%);
  opacity: 0;
  pointer-events: none;
  z-index: -99;
  border-radius: 50%;
  --units: 8px;
  --brick1: #222;
  --brick2: #222;
  --lines: #121212;
  --gp-ln: 50%/calc(var(--units) * 10) calc(var(--units) * 5);
  --gp-cn: 50%/calc(var(--units) * 5) calc(var(--units) * 5);
  background:
    repeating-conic-gradient(from 90deg at 95% 55%, var(--lines) 0% 25%, #fff0 0% 100%) var(--gp-cn),
    repeating-linear-gradient(180deg, var(--lines) 0 5%, #fff0 0 50%, var(--lines) 0 55%, var(--brick2) 0 100%) var(--gp-ln),
    repeating-linear-gradient(90deg, var(--brick1) 0 47.5%, var(--lines) 0 50%, var(--brick1) 0 97.5%, var(--lines) 0 100%) var(--gp-ln);
}

.modal.active {
  opacity: 1;
  transform: scale(1);
  z-index: 1000;
  pointer-events: initial;
  border-radius: 0;
  overflow: auto;
  padding: 8px 8px;
}

.inner-modal {
  position: relative;
  margin: auto;
}

.btnA-primary {
  color: #fff;
  background-color: #0d6efd;
  border-color: #0d6efd;
}

.btnA,
.btnB {
  display: inline-block;
  line-height: 1.5;
  text-align: center;
  text-decoration: none;
  vertical-align: middle;
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  background-color: #0d6efd;
  border: 1px solid transparent;
  box-sizing: border-box;
  padding: 6px 12px;
  font-size: 16px;
  border-radius: 4px;
  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
  font-family: "Poppins", sans-serif;
  font-weight: 500;
  font-style: normal;
}

.btnA:hover {
  background-color: #0056b3;
  border-color: #0a58ca;
  color: #ffffff;
}

.played {
  border-color: #0a58ca;
  background-color: #0056b3;
  box-shadow: 0 0 0 2px rgb(255 0 0);
}

.btnB-primary {
  color: #2fdcfe;
  background-color: #000000;
  border-color: #2fdcfe;
}

.btnB {
  border: 1px solid #2fdcfe;
}

.btnB:hover {
  background-color: #121212;
}

.exitD,
.close {
  position: absolute;
  margin: 6px auto 0;
  left: 0;
  right: 0;
  width: 47px;
  height: 47px;
  background: black;
  border-radius: 50%;
  border: 5px solid red;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.exitD::before,
.exitD::after,
.close::before,
.close::after {
  content: "";
  position: absolute;
  width: 100%;
  height: 5px;
  background: red;
  transform: rotate(45deg);
}

.exitD::after,
.close::after {
  transform: rotate(-45deg);
}

.outer-containerA.hide,
.video-containerA.hide,
.video-containerB.hide,
.video-containerC.hide,
.outer-containerB.hide,
.containerB.hide,
.containerC.hide {
  display: none;
}

How simple or easy would it be to implement that here: https://jsfiddle.net/dt06c15v/

My last code version of it.

Where modal is working fully.

A basic simple example there

That’s an old technique probably been around for 20 years. :slight_smile:

The problem with using :target is that the modal needs to be the :target or it disappears. As an example add an anchor in the modal and click it.

<section class="modal bg--purple" role="dialog" id="modalA" aria-labelledby="modalA-title" aria-describedby="modalA-description">
	<a href="#" class="modal-exit" title="close">&times;</a>
	<h1 id="modalA-title" class="modal-title">Modal A</h1>
	<p id="modalA-description" class="modal-description">Lots of fun things in here to see.</p>
 
 <a href="#modalA-title">This will also close the modal and not go to the h1 fragment</a>

</section>

If that’s not a problem for you then the :target method is fine and as I said has been around for many many years.

However opening and closing modals is easily accomplished in a couple of lines of js and has none of the drawbacks of the:target method. The css is slightly simpler also.

For more persistent CSS modals you can use the checkbox hack method but that makes the css more complicated than it needs to be.

As your page already uses masses of JS in order to function a couple of lines of js to add a class to a modal seems a no brainer :slight_smile:

Change the button to an anchor with an href:

 <div class="outer-containerB">
     <div class="containerB">
       <div class="buttonContainerA">
       </div>

       <a href="#lb" class="exitD" type="button" title="Exit" aria-label="Exit"></a>/* was a button*/
       
      <div id="lb" class="modal">
         <div class="inner-modal">
           <div class="buttonContainerB">
             <a href="#" class="linkButton btnB-primary btnB" target="_blank">text</a>
             <a href="#" class="linkButton btnB-primary btnB" target="_blank">text</a>
             <a href="#" class="linkButton btnB-primary btnB" target="_blank">text</a>
           </div>
           <button class="close" title="Close" aria-label="Close">&times;</button>
         </div>
       </div>
     </div>
   </div>

Then add the css:

.modal:target {
  opacity: 1;
  transform: scale(1);
  z-index: 1000;
  pointer-events: initial;
  border-radius: 0;
  overflow: auto;
  padding: 8px 8px;
}

The problem with using :target is that the modal needs to be the :target or it disappears. As an example add an anchor in the modal and click it.

My understanding here is that the button/anchor is the target, not modal.

Am I wrong?

Like this? https://jsfiddle.net/gy09451a/1/

html:

   <div class="outer-containerB">
     <div class="containerB">
       <div class="buttonContainerA">
       </div>
       <button class="exitD" type="button" title="Exit" aria-label="Exit"></button>
       <div id="lb" class="modal">
         <div class="inner-modal">
           <div class="buttonContainerB">
             <a href="#" class="linkButton btnB-primary btnB" target="_blank">text</a>
             <a href="#" class="linkButton btnB-primary btnB" target="_blank">text</a>
             <a href="#" class="linkButton btnB-primary btnB" target="_blank">text</a>
           </div>
           <a href="#" class="close" title="Close" aria-label="Close">&times;</a>/* was a button*/
         </div>
       </div>
     </div>
   </div>

js:

(function manageStuff() {

  const managePlay = [{

    buttonClass: "linkButton btnB-primary btnB",
    title: "Last Song Played",
    href: "#lb" // Add href here
  }];

  const buttonContainer = document.querySelector(".buttonContainerA");
  managePlay.forEach(function(link) {
    const anchor = document.createElement("a"); // Change button to anchor
    if (link.src) {
      // Add anchor to the container
      buttonContainer.appendChild(anchor);
    } else if (link.buttonClass) {
      anchor.className = link.buttonClass;
      anchor.textContent = link.title;
      anchor.classList.add("linkButton", "btnB-primary", "btnB");
      anchor.href = link.href; // Set href attribute
      buttonContainer.appendChild(anchor);
    }
  });

}());

Deleted:

/*(function manageLinkButtonOpen() {

  function openModal(target) {
    const modal = document.querySelector(target);
    modal.classList.add("active");
  }

  function addLinkToButton() {
    const modalButton = document.querySelector(".linkButton");
    modalButton.addEventListener("click", function(event) {
      //const target = event.currentTarget.dataset.destination;
      //openModal(target);
      openModal(event.currentTarget.dataset.destination);
    });
  }
  addLinkToButton();

}());

(function manageLinkButtonClose() {

  function closeModal(modal) {
    modal.classList.remove("active");
  }

  function addCloseEventToModal() {
    const closeModals = document.querySelectorAll(".close");

    closeModals.forEach(function(modal) {
      modal.addEventListener("click", function() {
        //closeModal(event.target.closest(".modalB"));
        closeModal(document.querySelector(".modal"));
      });
    });
  }
  addCloseEventToModal();
}());*/

I gave you an example of where it fails so study that use case and if your use case isn’t reliant on the modal retaining its target status then you should be ok.

1 Like

However opening and closing modals is easily accomplished in a couple of lines of js

That is more than a couple of lines of javascript:

(function manageLinkButtonOpen() {

  function openModal(target) {
    const modal = document.querySelector(target);
    modal.classList.add("active");
  }

  function addLinkToButton() {
    const modalButton = document.querySelector(".linkButton");
    modalButton.addEventListener("click", function(event) {
      //const target = event.currentTarget.dataset.destination;
      //openModal(target);
      openModal(event.currentTarget.dataset.destination);
    });
  }
  addLinkToButton();

}());

(function manageLinkButtonClose() {

  function closeModal(modal) {
    modal.classList.remove("active");
  }

  function addCloseEventToModal() {
    const closeModals = document.querySelectorAll(".close");

    closeModals.forEach(function(modal) {
      modal.addEventListener("click", function() {
        //closeModal(event.target.closest(".modalB"));
        closeModal(document.querySelector(".modal"));
      });
    });
  }
  addCloseEventToModal();
}());

Yes but half that is something else.:slight_smile:

Here’s a bare bones script for multiple modals.

Less than 10 lines of actual code.

1 Like