Patrick Desjardins Blog
Patrick Desjardins picture from a conference

How to create a bottom-right fixed button in CSS with expanding hover animation

Posted on: 2015-08-18

If you need to have a button with minimal information and when the user hovers this one give more input before executing the action, here is something interesting. The code illustrates a use case that the button is fixed to the browser at the bottom-right of the screen but this kind of button can be used everywhere. The main purpose is to have a rich user experience with pro-active feedback in a minimal way. The initial state of the button is just a single icon.

Expected rendering

For that example, I haven't use a glyph icon, neither an image, just a single plus character. This could be replaced with what ever you want. The idea is that when the user hover the icon that we have a transition to a bigger button.

Here is the button's Html. The container is not required and is just there for the purpose of having this button sticky at the bottom-right of the window. The button element is the real button. This one will grows when hovering. It contains two texts: one when collapsed and one when extended.

<div class="right-corder-container">     
	<button class="right-corder-container-button">         
		<span class="short-text">+</span>         
		<span class="long-text">Add Me</span>     
	</button> 
</div>

The css does 90% of the job. The remaining 10% is that we need to have a hover JavaScript to add and remove a class to add the long text visibility. The first CSS style is about fixing the container at the bottom-right of the browser's window.

.right-corder-container {     
    position:fixed;     
    right:20px;     
    bottom:20px; 
}

The next CSS style is what round up the button into a perfect circle. This is also where we setup the transition effect timing.

.right-corder-container .right-corder-container-button {     
     height: 62px;     
     width: 62px;     
     border:none;    
     background-color:#6FB583;     
     border-radius: 62px;        /*Transform the square into rectangle, sync that value with the width/height*/     
     transition: all 300ms;      /*Animation to close the button (circle)*/     box-shadow:2px 2px 5px rgb(25, 73, 15);     
     cursor:pointer; 
}

The span specify the plus sign to be placed in the middle. We use absolute position to have fined precision about where to place the text. Also, this is easier to ensure that even during the effect that this one remains at the same place.

.right-corder-container .right-corder-container-button span {     
    font-size: 72px;     
    color:white;     
    position: absolute;    
    left: 10px;     
    top: 16px;     
    line-height: 28px; 
}

The hover is where we specify the size of the final stage of the button. We also change the right side to be less round. This way, the button appears to be less than an oval, more to a label.

.right-corder-container .right-corder-container-button:hover {     
    transition: all 400ms cubic-bezier(.62,.1,.5,1);     
    width:200px;     
    border-top-right-radius: 5px;     
    border-bottom-right-radius: 5px; 
}

The next style block is about the long text effect. We want this text to appear slowly. We need to tweak some properties to be sure that the vertical scroll-bar does not get affected.

/*
Long text appears slowly with an animation. That code prepare the animation by hidding the text.
The use of display is not there because it does not work well with CSS3 animation. 
*/ 
.right-corder-container .right-corder-container-button .long-text {     transition: opacity 1000ms; /*Only the text fadein/fadeout is animated*/     
opacity:0;                /*By default we do not display the text, we want the text to fade in*/     
color:white;     
white-space: nowrap;     
font-size: 0;             /*Set to 0 to not have overflow on the right of the browser*/     
width: 0;                 /*Set to 0 to not have overflow on the right of the browser*/     
margin:0;                 /*Set to 0 to not have overflow on the right of the browser*/ }

This is how we show the long text. We need to add a delay in the transition opacity because we do not want to start showing the text too early. Mostly because the container size is animated and not big enough to receive the text yet.

 /*
 Animation to have a text that appear progressively. We need to play with a delay     
 on the width and the font-size to not have the browser have the text appears on the right     
 side of the browser view port. This has the side-effect of having an horizontal bar. 
 */ 
.right-corder-container .right-corder-container-button .long-text.show-long-text{   
    transition: opacity 700ms,               
    width 1ms linear 270ms,       /*two thirds of the animation on the container width*/               
    font-size 1ms linear 270ms;   /*two thirds of the animation on the container width*/   
    opacity:1;   
    margin-top: 2px;                          /*Center the position vertically*/   
     margin-left: 65px;                        /*Center between the + and the right end side*/   
    font-size: 20px;                          /*Text size, cannot be defined initially without moving the scrollbar*/   
    width: auto;                              /*Required to be set with a delay (see animation) to not have scrollbar. Delay is to wait container to size up*/ 
}

The JavaScript is minimal and you do not have to use JQuery for a simple task as this. However, I had this one already available to here is the code with JQuery.

$(".right-corder-container-button").hover(
    function() 
    {     
        $(".long-text").addClass("show-long-text"); 
    }, 
    function () {     
        $(".long-text").removeClass("show-long-text"); 
    }
);

This code is available in JSFiddle.