Vue.js: Hide element until it reaches the desired position

Currently, I am diving into the world of Vue and finding it quite engaging. One feature I am working on involves having a tab that is fixed to the bottom of the browser window upon page load. The tab should then slide up when clicked to display additional content.

So far, everything seems to be running smoothly. I have successfully implemented the sticky tab at the bottom of the page, and the click events are functioning as expected.

However, I have encountered an issue in calculating the height of the tab (and corresponding div) to properly adjust the CSS property. As a result, when the page first loads, users can visibly see the tab sliding down before settling into place. Ideally, I would like the tab to remain hidden until all calculations are finalized and it seamlessly appears in its correct position.

The code snippet I am currently using:

app.js

new Vue({
    el: '#info',
    delimiters: ['${', '}'],
    data: {
        active: false,
        inactive: true,
        styles: {
            'bottom': 0
        },
    },
    methods() {
        toggle: function (event) {
            event.preventDefault();
            this.active = !this.active;
            this.inactive = !this.inactive;
        }
    },
    mounted() {
        let tabHeight = this.$refs.infoTab.clientHeight;
        let boxHeight = this.$refs.infoBox.clientHeight;  // 473px
    
        this.styles.bottom = -boxHeight + 'px';
    }
});

HTML

<div class="info not-active" id="info" @click="toggle" ref="infoTab"
     v-cloak
     v-bind:class="{ active: active }"
     v-bind:style="styles">
     <!-- content -->
</div>

style.css

[v-cloak] {
    display: none;
}

/* more classes */

.info {
    width: 100%;
    position: fixed;
    &.inactive {
        bottom: -100%;
    }
    &.active {
        bottom: 0 !important;
    }
}

I feel like I'm very close to achieving the desired outcome; however, I want to eliminate the visible sliding effect for users. My attempts with the created hook did not yield the expected results due to the absence of clientHeight.

Any insights or suggestions on how to address this challenge would be greatly welcomed!

Answer №1

If you want to tackle this task using only CSS, you don't need to rely on Vue's lifecycle hooks. I've put together a code snippet using vanilla JS as an example:

let infoNode = document.getElementById('info');

infoNode.addEventListener('click', () => {
  if (infoNode.style.top) {
    // clear inline top style
    infoNode.style.top = '';
  } else {
    // set top to client height + 2 * border thickness
    infoNode.style.top = `calc(100% - ${infoNode.clientHeight}px - 4px)`;
  }
});
#info {
  font-size: 16px;
  width: 200px;
  border: 2px solid hsl(0, 0%, 80%);
  padding: 8px;
  border-radius: 4px;
  cursor: pointer;
  position: fixed;
  /* 100% height of the viewport subtracting:
  tab height: padding, margin, & font size */
  top: calc(100% - (8px + 8px + 24px));
  /* we center the tab horizontally here using
  50% the width of the viewport - 50% the fixed
  width of the tab */
  left: calc(50% - 200px/2);
  transition: top 0.5s;
}

.title {
  font-size: 24px;
  font-weight: 500;
  margin-bottom: 8px;
  display: block;
}

p {
  margin: 0;
}
<div id="info">
  <span class="title">Click on Me</span>
  <p>
    This is the content of the tab, isn't it great? I think so too, and it can be of any arbitrary length!
  </p>
</div>

The key technique here is to utilize calc with top instead of relying on -100% with bottom for positioning. This ensures that your tab is initially positioned correctly and eliminates concerns about misplacement when a user first loads your webpage.

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

What is the best way to retrieve the value of a textbox in AngularJS?

Trying my hand at creating a basic web page using angular. I've got 2 textboxes and 2 buttons - one to set a predefined value in a textbox, and the other to add some text. Here's the code snippet: <!DOCTYPE html> <html lang="en" ng-app ...

Troubleshooting Problem in Coursera's AngularJS Week 3 Exercise 4

Here's the issue I'm facing: After launching the index page with 'gulp watch', there's nothing visible on the screen. An error appears: Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.4.12/$injector/modulerr?p ...

What is the best way to adjust CSS vw and vh values after resizing your website?

Utilizing vw and vh values in my CSS transform has resulted in the cloud image moving smoothly across the screen, from left to right, based on the actual window width. While this works well for various window sizes initially, I have encountered an issue w ...

Utilizing Fullcalendar to Show Multiple Months

Is there a way to display two months side by side using the FullCalendar plugin? I have not been able to find a solution in other similar questions. Here is my current setup: <div class="calendar-box"> <div clas ...

A pair of HTML elements linked by a solitary JavaScript event listener

My JavaScript code looks like this: //for dom element 1// $(document).on( 'click', '.dom1', function() { something; }); //for dom element 2 $(document).on( 'click', '.dom2', function() { something; }); Bot ...

Tips for restricting the preloader display to once per session

My website features a preloader on every page. <div id="preloader" > <div id="status"></div> <div id="statustext">some text</div> </div> This preloader is activated using the following jQuery code: //<![CDATA[ var ...

Is there a way to customize the scrollbar color based on the user's preference?

Instead of hardcoding the scrollbar color to red, I want to change it based on a color variable provided by the user. I believe there are two possible solutions to this issue: Is it possible to assign a variable to line 15 instead of a specific color lik ...

What is the process of initializing divs in DataTables?

My application has a DataTable installed, but I encountered an error message stating "DataTables warning: Non-table node initialisation (DIV). For more details about this error, please visit http://datatables.net/tn/2". I'm aware that DataTables is d ...

How to Keep Button Highlighted After Clicking

I've experimented with various methods like using :active, :focus, adding a class, and modifying CSS rules through jQuery to maintain the button highlight, but none of them have been successful. Please take a look at my code and point out any mistakes ...

The CSS media queries are failing to adjust the properties from 1024 to 768 as expected

Currently, I am working on implementing media queries to customize the color scheme for different screen sizes - particularly in 1024 view and 768 view. However, one issue that I encountered is that the properties defined for the 1024 view are being inheri ...

attempting to transfer website form data to WhatsApp platform

I have developed a website where users can fill out a form and submit their data. I want to send this form data to WhatsApp, so I tried using Twilio. However, Twilio is only free for the first day. Is there any other software that allows me to send form da ...

The hover effect on <a href element will only activate after clicking or refreshing the page

Having an issue with my website where I'm using HTML and CSS exclusively. The problem arises when I have multiple "a hrefs" that should change their background colors slightly when hovered over. However, whenever I clear the browser cache or go into i ...

What is the best way to line up my columns when they are split between groups of three and two?

I am having trouble aligning my columns in the way I want. The image shows that some tables have 3 columns while others have 2, and I would like to align the blue with the blue and the red with the red as shown in the picture: https://i.stack.imgur.com/1bL ...

Should pages be indexed to index.php or should the top and bottom parts of the page be created and included in all content pages?

I've been out of the webpage creation game for a while, but I've recently decided to get back into it. Like everyone else, I want to learn the best way to do this. However, I find myself facing a dilemma on how to structure my pages. My initial i ...

What is the best way to get a table header with collapsed borders and tbody cells with spacing between them?

Example I am currently in the process of creating a table design for a web project, inspired by the example above. Here is my attempt: .table_RMA table{ width: 100%; border-collapse: separate; border-spacing: .5rem; } .table_RMA table thead{ color:white ...

Discover the key to unlocking various types of content within individual pop-up windows

<html> <script type="text/javascript> function newWindow(url) { window.open(url, "_blank", "toolbar=no, scrollbars=no, resizable=no, top=200, left=300, width=870, height=650"); } </script> &l ...

Display a navigation link in Bootstrap 4 when the website is viewed on a mobile

I am facing an issue with displaying a nav link on a responsive page. Below is the code snippet for reference: <div class="collapse navbar-collapse w-100 order-1 order-lg-0" id="navbarNav"> <ul class="n ...

Determined characteristics for every item within the array

I am facing a scenario where my data storage contains an array of products, each with its price and quantity. My goal is to calculate the 'total' value for each product by multiplying the price with the quantity. I currently achieve this by crea ...

Using Django to stream H.264 video files with FileWrapper through HTML5

Encountering a peculiar problem while attempting to stream H.264 video with Django using the FileWrapper class. The view function being used is as follows: def mp4(request, path): wrapper = FileWrapper(open(path, 'rb')) content_type = mimety ...

Ways to overwrite styles and block inheritance in CSS

Currently immersed in a project, I've crafted a webpage solely using HTML and CSS. Seeking responsiveness, I've implemented three distinct stylesheets - one for widths exceeding 2000px, another for widths ranging from 901px to 1999px, and the las ...