Challenges with the Placement of Buttons

I am facing an issue with the code below:

document.addEventListener("DOMContentLoaded", function(event) {
  // Select all the read more buttons and hidden contents
  const readMoreButtons = document.querySelectorAll(".read-more");
  const hiddenContents = document.querySelectorAll(".hidden");
  // Now loop over the read more buttons 
  readMoreButtons.forEach((readMoreButton, index) => {
    // Add onclick event listeners to all of them
    readMoreButton.addEventListener("click", () => {
      // Change content of read more button to read less based on the textContent
      if (readMoreButton.textContent === "Read More") {
        readMoreButton.textContent = "Read Less";
      } else {
        readMoreButton.textContent = "Read More";
      }
      // Toggle class based on index
      hiddenContents[index].classList.toggle("hidden");
      readMoreButton.closest(".snip1311").classList.toggle("reading");
    })
  })
})
/* Projects */
@import url(https://fonts.googleapis.com/css?family=Raleway:400,500,800);
.project-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    color: white;
}
figure.snip1311.reading {
  overflow-y: auto;
}

figure.snip1311 {
  font-family: 'Raleway', Arial, sans-serif;
  position: relative;
  float: left;
  overflow-y: hidden;
  overflow-x: hidden;
  margin: 10px 1%;
  min-width: 230px;
  max-width: 360px;
  max-height: 256px;
  width: 500rem;
  color: #ffffff;
  text-align: left;
  background-color: #07090c;
  font-size: 16px;
  -webkit-perspective: 50em;
  perspective: 50em;
  border: 5px solid #555;
}
figure.snip1311 * {
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  -webkit-transition: all 0.6s ease;
  transition: all 0.6s ease;
}
figure.snip1311 img {
  max-width: 110%;
  -webkit-transition-delay: 0.2s;
  transition-delay: 0.2s;
  backface-visibility: hidden;
  height: 258px;
}
@media all and (max-width: 500px) {
figure.snip1311 img {
  border: none;
  }
}
figure.snip1311 figcaption {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  -webkit-transform: rotateX(90deg) translate(0%, -50%);
  transform: rotateX(90deg) translate(0%, -50%);
  -webkit-transform-origin: 0% 0%;
  -ms-transform-origin: 0% 0%;
  transform-origin: 0% 0%;
  z-index: 1;
  opacity: 0;
  padding: 0 30px;
}
figure.snip1311 h3,
figure.snip1311 p {
  line-height: 1.5em;
}
figure.snip1311 h3 {
  margin: 0;
  font-weight: 800;
  text-transform: uppercase;
}
figure.snip1311 p {
  font-size: 0.8em;
  font-weight: 500;
  margin: 0 0 15px;
}
figure.snip1311 .read-more {
  border: 2px solid #ffffff;
  padding: 0.5em 1em;
  font-size: 0.8em;
  text-decoration: none;
  color: #ffffff;
  display: inline-block;
}
figure.snip1311 .read-more:hover {
  background-color: #ffffff;
  color: #000000;
}
figure.snip1311 .read-more1 {
  border: 2px solid #ffffff;
  padding: 0.5em 1em;
  font-size: 0.8em;
  text-decoration: none;
  color: #ffffff;
  display: inline-block;
}
figure.snip1311 .read-more1:hover {
  background-color: #ffffff;
  color: #000000;
}
figure.snip1311:hover img,
figure.snip1311.hover img {
  -webkit-transform: rotateX(-180deg);
  transform: rotateX(-180deg);
  opacity: 0;
  -webkit-transition-delay: 0;
  transition-delay: 0;
}
figure.snip1311:hover figcaption,
figure.snip1311.hover figcaption {
  -webkit-transform: rotateX(0deg) translate(0, -50%);
  transform: rotateX(0deg) translate(0, -50%);
  opacity: 1;
  -webkit-transition-delay: 0.35s;
  transition-delay: 0.35s;
}
.hidden{
display:none;
}
.read-more{
cursor:pointer;
}
<figure class="snip1311"><img src="https://www.thespruce.com/thmb/tClzdZVdo_baMV7YA_9HjggPk9k=/4169x2778/filters:fill(auto,1)/the-difference-between-trees-and-shrubs-3269804-hero-a4000090f0714f59a8ec6201ad250d90.jpg" alt="sample98"/>
  <figcaption>
    <h3>Lorem ipsum</h3>
    <p>Lorem ipsum dolor sit amet [...]<br />
  </figcaption>
</figure>

After running the code snippet above, I noticed that when clicking the read more button, it suddenly disappears due to the lengthy text pushing it upwards. How can I ensure that the read-more button remains at the top regardless of the text length?

Desired Output

https://i.sstatic.net/PU7ZJ.png

The main goal is to maintain the same margin between the read more button and the top of the card as shown in the desired output image. The alignment should stay unchanged, only ensuring that the button always appears with a consistent margin-top, irrespective of the text length. Any suggestions on achieving this result would be greatly appreciated.

Answer №1

Your element is undergoing a center flip, causing it to overflow towards the top of the scrollable section and positioning the text at a mid-top location from the center based on the content within the element once it becomes visible.

UPDATE: There are two instances in your CSS where you have applied translate(0%, -50%). The second one affects the Y axis, pushing the content 50% upwards and leading to the issue of the top not being visible.

To determine the clientHeight of the flipped element, first add a class, shown, to the element after removing the hidden class. Then use a timeout of 10 to ensure that the DOM is properly set before fetching the clientHeight of the added class shown. Divide this value by 2, subtract half of the parent element's height, including padding, and locate the top position of your content.

Next, pass this unit as a variable to your CSS using the root element =>

document.documentElement.style.setProperty('--distTrans', 'distance')
. This action will establish a CSS variable for setting the distance to position the top of your flipped content. In the CSS, adjust the transform property of the shown selector to translateY(var(--distTrans)), which will move the text to the top of the content excluding padding.

// JavaScript functions for handling showing and hiding content
function showLess(e) {
  document.querySelectorAll('.showBtn').forEach(btn => {
    if (e.target === btn) {
      btn.closest(".snip1311").classList.toggle("reading");
      btn.parentNode.classList.toggle('shown')
      btn.parentNode.classList.toggle('hidden')
    }
  })
}

// Parse the content upon DOM load
function parseContent(event) {
  // Select all the read more buttons and hidden contents
  const readMoreButtons = document.querySelectorAll(".read-more");
  const hiddenContents = document.querySelectorAll(".hidden");
  // Loop over the read more buttons 
  readMoreButtons.forEach((readMoreButton, index) => {
    // Add onclick event listeners
    readMoreButton.addEventListener("click", function(e) {
      setTimeout(() => {
        // Calculate the distance to translate
        document.documentElement.style.setProperty('--transDist', document.querySelector('.shown').clientHeight / 2 - document.querySelector('.snip1311').clientHeight / 2 + 'px');
      }, 10);
      // Toggle classes
      hiddenContents[index].classList.toggle("hidden");
      hiddenContents[index].classList.toggle("shown");
      
      let shown = document.querySelectorAll('.shown')
      if (shown) {
        shown.forEach(item => {
          item.addEventListener('click', showLess)
        })
      }
      readMoreButton.closest(".snip1311").classList.toggle("reading");
    })
  })
}

// Call the parseContent function upon DOM content load
document.addEventListener("DOMContentLoaded", parseContent)
/* Styling code for projects */

:root {
  --transDist: 100px;
}

@import url(https://fonts.googleapis.com/css?family=Raleway:400,500,800);
.project-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  color: white;
}

figure.snip1311.reading {
  overflow-y: auto;
}

/* Rest of the CSS styling rules for figure.snip1311 ... */
<figure class="snip1311"><img src="sample-image.jpg" alt="Sample Image" />
  <figcaption>
    <h3>Lorem ipsum</h3>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sed orci interdum, eleifend nisl suscipit, ornare urna. Curabitur vel maximus lacus.</p>
    <button class="read-more">Read More</button>
    <br>
    <p class="hidden">
        /* Content inside the hidden section */
    </p>
  </figcaption>
</figure>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Maximizing efficiency in website reloading and development with Sinatra using Ruby along with Rack and Haml

In my efforts to build a Sinatra website, I have gone from using Shotgun to now utilizing Rerun for reloading my Thin server whenever I make file edits. However, the development cycle is proving to be quite time-consuming. Even small changes to CSS, JavaS ...

Sustaining the Status of a Changeable Form Element

To fulfill the requirement of constructing a Form Builder component that generates forms based on JSON data from the backend, I have identified 7 types of input fields that may be encountered: email password select file date input of type text input of ty ...

Search for and swap HTML text. Exclude any web links

After developing a simple script to search and replace strings within the DOM, I encountered an issue where URLs of links were being affected as well. For instance, replacing "example" with "my example" resulted in breaking the following link; <a href ...

When properties remain unchanged, they do not hold the same value in a Firestore-triggered Cloud Function

Within my Firestore database, there is a collection named events consisting of documents with attributes such as begin, end, and title. The function in question is triggered when any changes occur within a document. The begin and end fields are both categ ...

What is the best way to align an element at the bottom in order to allow it to grow vertically

I have a unique structure on one of my pages that I want to use for a tooltip style behavior. When the "container" element is clicked, the "child" element, which is initially hidden, should appear above the container. However, since the child's height ...

When using requirejs and vue.js together, the error message "Vue is not defined" may be encountered

My code snippet looks like this: <script type="text/javascript" src="../../node_modules/requirejs/require.js"></script> <script type="text/javascript" src="../../node_modules/vue/dist/vue.js"></script> <script>console.log(Vue ...

Node Js issue stemming from unaddressed promises leading to rejection

Hi, everyone! I'm currently facing some challenges while trying to deploy this API. The error message I keep getting is: "UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error may have occurred due to either throwing inside an asyn ...

Retrieve data from an AJAX call and PHP script upon successful completion

Utilizing AJAX (jQuery), my aim is to submit a form to user-ajax.php and expect the page to echo back a response like "success". In my AJAX code, I am checking the response value for success but it's not working as expected. Below is the PHP code snip ...

Swap the < symbol with &gt; and & with &amp; within a specific node or location in an XML document

Hello everyone, I have a XML file with a node named Section, where certain characters like & and < are treated as invalid. I need to replace < with &lt; and & with &amp; only within the Section Node. Currently, I am using the following Java ...

Changes in bottom position when scrolling in landscape mode on iOS Safari

I'm currently using ReactJS and have implemented a mobile menu bar with CSS properties position: fixed and bottom: 0. The menu bar stays locked at the bottom of the page in both portrait and landscape orientations on all browsers except for Safari. I ...

Manage the element that should receive focus() after tab is pressed from an input field

On my webpage, there is a variety of elements such as inputs and anchors. I need to specify which input field the browser should move focus to when I press the tab key while on an input. Currently, pressing tab from one specific input takes me to a menu i ...

Ways to Soothe Long Polling

Currently, I am developing a basic chat feature using AJAX in a function that triggers a setTimeout call to itself upon successful execution. This occurs approximately every 30 seconds. While this setup serves its purpose, I am seeking a more immediate not ...

Tips for positioning slideshow below header in web design

I am currently working on enhancing the slideshow feature on my website. If you take a look at the image link provided below, you'll notice that the alignment of the slideshow is slightly off on both sides. Despite my attempts to adjust the CSS width ...

Issues arise with the blinking of my table rows

I'm working on a page with a table where certain rows need to blink under specific conditions. This page is a partial view that I load using the setInterval function. However, I've encountered an issue where the blinking functionality goes hayw ...

Is it possible to include a scroll bar at the top of an overflow-x <div> in addition to or instead of the bottom?

Can the scroll bar be positioned at the top of a table instead of just the bottom? <div style="overflow-x: auto;"> <table> ... ... </table> </div> I am looking for a way to have the scroll bar appear at the top of my t ...

Traditional alignment challenges arise when trying to position two elements in a row using HTML and CSS

Greetings to the community of stack overflow! I am facing a mundane issue with two elements (refer to code snippet below) that requires my attention. Any help or advice would be greatly appreciated. I am aiming for the final output to resemble this: With ...

Having trouble with tabs in jQuery?

I'm having trouble setting up tabs in a reservation form with 3 tabs that include text boxes for user input. I can't seem to get it working properly and I'm not sure where I've gone wrong. Could it be due to the placement of the content ...

Any ideas on how to extract binary data from PHP passthru using a JavaScript ajax request?

I am facing an issue with retrieving and playing an audio file from a server using JavaScript. The ajax call in my code doesn't seem to callback, and I'm not certain if I'm handling the audio correctly in JavaScript. Below is the PHP file t ...

What is the process for incorporating Express.js variables into SQL queries?

Recently delving into the world of node.js, I've embarked on a journey to create a login and registration system using express.js, vanilla JS, CSS, HTML, and MySql. Within the following code lies the logic for routing and handling HTTP Post requests ...

The Flask form within the Bootstrap input-group is breaking onto a new line when viewed on mobile devices

I want the 'Go' button to remain next to the search field. It displays correctly on Desktop view, but on mobile view, the submit button wraps (breaking up the input-group). How can I prevent this? Additionally, Bootstrap is adding gray lines aro ...