Eliminate any height changes in the ul element during a CSS transition

Here is the code I've been using to style my side navigation, which has been working perfectly without any transitions.

SCSS Code and a functional JSFiddle

.side-nav{
  position: fixed;
  z-index: 100;
  right: 0;
  margin-top: 15vh;

  ul {
    list-style: none;
    background: red;
    border-style: solid;
    border-right-style: none;
    border-width: 3px;
    border-color: blue;
    @include border-radius(20px, 0, 20px, 0);
    width: 1cm !important;
  }

  li {
    position: relative;
    display: block;
    right: 0;
    width: 1cm;

    span {
      white-space: pre;

      &.short {
        color: black;
        display: block;
      }

      &.long {
        display: none;
        color: white;
      }
    }

    &:hover {
      right:200%;
      width: 3cm;
      @include border-radius(20px, 0, 20px, 0);
      border-style: solid;
      border-right-style: none;
      border-width: 3px;
      border-color: blue;
      background: red;
      margin: -3px 0;

      span {
        &.short {
          display: none;
        }

        &.long {
          display: block;
        }
      }
    }
  }

  a {
    position: relative;
    display: block;
    text-decoration: none;

    padding: 10px 0;
    text-align: center;
  }
}

However, when I add transition code as shown in this updated JSFiddle, the height of the ul fluctuates during interactions.

SCSS Code and JSFiddle showcasing the issue

.side-nav{
  position: fixed;
  z-index: 100;
  right: 0;
  margin-top: 15vh;

  ul {
    list-style: none;
    background: red;
    border-style: solid;
    border-right-style: none;
    border-width: 3px;
    border-color: blue;
    @include border-radius(20px, 0, 20px, 0);
    width: 1cm !important;
  }

  li {
    position: relative;
    display: block;
    right: 0;
    width: 1cm;
        @include transition(all 1s);

    span {
      white-space: pre;

      &.short {
        color: black;
        display: block;
      }

      &.long {
        display: none;
        color: white;
      }
    }

    &:hover {
          @include transition(all 1s);
      right:200%;
      width: 3cm;
      @include border-radius(20px, 0, 20px, 0);
      border-style: solid;
      border-right-style: none;
      border-width: 3px;
      border-color: blue;
      background: red;
      margin: -3px 0;

      span {
        &.short {
          display: none;
        }

        &.long {
          display: block;
        }
      }
    }
  }

  a {
    position: relative;
    display: block;
    text-decoration: none;

    padding: 10px 0;
    text-align: center;
  }
}

The issue arises when adjusting borders to maintain consistency while preventing height changes. To align borders of top and bottom li elements with that of ul, a margin: -3px 0 line was added due to a border-width of 3px.

How can I ensure a smooth transition where both margins and borders remain consistent, thus keeping ul height unchanged?

Answer №1

You have applied a border on hover which changes the height of the list item.

Instead, set a default transparent border and only change the border color on hover.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.side-nav {
  position: fixed;
  z-index: 100;
  right: 0;
  margin-top: 1vh;
}
.side-nav ul {
  list-style: none;
  background: red;
  border-style: solid;
  border-right-style: none;
  border-width: 3px;
  border-color: blue;
  -moz-border-top-left-radius: 20px;
  border-top-left-radius: 20px;
  -moz-border-top-right-radius: 0;
  border-top-right-radius: 0;
  -moz-border-bottom-left-radius: 20px;
  border-bottom-left-radius: 20px;
  -moz-border-bottom-right-radius: 0;
  border-bottom-right-radius: 0;
  width: 1cm !important;
}
.side-nav li {
  position: relative;
  display: block;
  right: 0;
  width: 1cm;
  border: 3px solid transparent;
  -webkit-transition: all 1s;
  transition: all 1s;
}
.side-nav li span {
  white-space: pre;
}
.side-nav li span.short {
  color: black;
  display: block;
}
.side-nav li span.long {
  display: none;
  color: white;
}
.side-nav li:hover {
  -webkit-transition: all 1s;
  transition: all 1s;
  right: 200%;
  width: 3cm;
  -moz-border-top-left-radius: 20px;
  border-top-left-radius: 20px;
  -moz-border-top-right-radius: 0;
  border-top-right-radius: 0;
  -moz-border-bottom-left-radius: 20px;
  border-bottom-left-radius: 20px;
  -moz-border-bottom-right-radius: 0;
  border-bottom-right-radius: 0;
  border-color: blue;
  background: red;
}
.side-nav li:hover span.short {
  display: none;
}
.side-nav li:hover span.long {
  display: block;
}
.side-nav a {
  position: relative;
  display: block;
  text-decoration: none;
  padding: 10px 0;
  text-align: center;
}
<nav id="side-nav" class="side-nav" role="navigation">
  <ul>
    <li><a href="#"><span class="short">S</span><span class="long">Long</span></a>
    </li>
    <li><a href="#"><span class="short">S</span><span class="long">Long</span></a>
    </li>
    <li><a href="#"><span class="short">S</span><span class="long">Long</span></a>
    </li>
    <li><a href="#"><span class="short">S</span><span class="long">Long</span></a>
    </li>
    <li><a href="#"><span class="short">S</span><span class="long">Long</span></a>
    </li>
  </ul>
</nav>

JSfiddle Demo

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

Steps for aligning an image to the right using Bootstrap Vue

I'm currently learning Bootstrap Vue and I'm trying to align an image on the right using a b-card header. The challenge I'm facing is that when I add the image, it disrupts the perfect size of the template header, causing the image to show a ...

Determine the vertical dimension of an element through a JavaScript event listener

I've been working on creating an Apple-style image sequence scroller from a codepen demo. Here's the link to the original: https://codepen.io/jasprit-singh/pen/LYxzQjB My goal is to modify the JavaScript so that the scroll height is based on a p ...

HTML text/code ratio display tool

I need help finding a firefox/firebug plugin (or any OFFLINE tool is fine) that can show me the real text/markup ratio. While there are some online options available like and a Firefox plugin at https://addons.mozilla.org/en-US/firefox/addon/150366/ (whi ...

JavaScript communication between clients and servers

I am looking to develop two scripts, one for the client-side and one for the server-side. I came across a snippet that allows for asynchronous calling of JavaScript: <html> <head> </head> <body> <script> (function() { ...

Transition from mouse wheel scroll to page scroll not functioning properly when overflow is enabled

The website has a fixed element that uses overflow:auto. Users can scroll this element by positioning the mouse over it. However, once the element reaches the end of its scroll, the page does not seamlessly take over the scrolling. Instead, there is about ...

Automatically add shimmer with CSS styling

Is it possible to make the shine effect work automatically (without needing hover) every 5 seconds? http://jsfiddle.net/AntonTrollback/nqQc7/ .icon:after { content: ""; position: absolute; top: -110%; left: -210%; width: 200%; height: 200%; ...

What is causing the div element to act as a container?

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="95f7fafae1e6e1e7f4e5d5a1bba3bba5">[email protected]</a>/dist/css/bootstrap.min.css" integrity="sha384-B0v ...

Embedding a thread in an HTML document (Difficult task)

I'm currently working on a method to achieve the following task: Embedding a specific string (such as "TEST") into the content of an HTML page, after every certain number of words (let's say 10). The challenge here is ensuring that the word count ...

To prevent flickering when using child flex elements, it's best to use position fixed along with a dynamically updated scrollbar position using Javascript

My navigation component includes a slim banner that should hide upon scroll and a main-nav bar that should stick to the top of the screen and shrink when it does so. I initially looked into using Intersection Observer based on a popular answer found here: ...

The CSS code seems to be ineffective when attempting to center elements with a specific width in react.js

Hey everyone, I'm currently working on developing a web application using react-bootstrap and I've encountered an issue with adjusting the width of my row and centering it. I have already created the necessary CSS and JS files, but I am unable to ...

"Problem with binding a dropdownlist to an object causing the selected object not to return

I have successfully bound an object to a dropdownlist using Knockout 2.2.1. The binding correctly displays the items in the list, but I am facing difficulties retrieving the selected OBJECT. To illustrate this issue, I have created a JSFiddle: http://jsfid ...

Create a stylish Bootstrap 3 modal featuring an image and convenient scroll bars

My dilemma is with a modal dialog containing an image of fixed width set at 1500px. I want the image to maintain this size and for scroll bars to appear on smaller screen sizes, allowing users to scroll through the entire image. Essentially, I need the mod ...

Display information based on the radio button chosen

I've set up a radio button with options for "no" and "yes", but neither is selected by default. Here's what I'm trying to achieve: If someone selects "no", nothing should happen. However, if they select "yes", then a message saying "hello w ...

How can I set up an automatic refresh for an angularjs iframe?

This code utilizes Angularjs and is designed to be run on a localhost server. The first part of the code can be found in index.html: <iframe src="{{Url}}" width="100%" height="500"></iframe> The second part of the code is located in app.js: ...

Prevent clicking until the IE 10 and 9 windows have fully loaded

My goal is to prevent clicking on an image element until all the resources have finished loading, enabling the click only after the window.load() or when document.readystate reaches complete status. While this code works well in Chrome and Safari, I am fac ...

Prevent automatic submission of forms when selecting attributes in HTML forms using AngularJS

I need to create a form where users can select their branch of study. Here is the form I have designed- <form method="post" [formGroup]="formData" (click)="dataSubmit()" > <div class="form-group"> <label for="branch">Selec ...

How to ensure Angular mat-button-toggle elements are perfectly aligned within their respective groups

https://i.stack.imgur.com/Wjtn5.png Hello there, I'm trying to make the numbers in the first group match the style of the second group (noche, mañana...). I've set both the group and individual element width to 100%, but the numbers beyond 22 ...

Hide or show list items in an unordered list using jQuery

I am interested in creating a script that can toggle between "show more" and "show less" functionality for elements in a list. I came across this script: HTML <ul id="myList"> <li>One</li> <li>Two</li> <li> ...

The border should not start at the left of the page; instead, I would like it to begin at the letter "T" in "Tech."

I am having an issue with the bottom border starting from the extreme left of the page. I want it to start from the letter "T" in Tech instead. #page-container { width: 1250px; margin: 0 auto; } h2 { font-weight: normal; padding-left: 15px; ...

Leveraging jQuery to extract the value from a concealed form field

Seeking assistance with a jQuery issue... I am attempting to use jQuery to retrieve the values of hidden fields in a form. The problem I am facing is that there are multiple forms displayed on the same page (result set items for updating), and the jQuery ...