Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: Expanding a <div> from right to left to reveal text

I'd like to set up a fixed <div>, containing an icon, which expands from right to left when being hovered over (the <div> expands, not the icon), revealing a piece of text on the left side of the icon. The icon's position stays unchanged. Here's a sketch to help illustrate what I'd like to do:

enter image description here

Changing the size of the <div> on hover is no issue, I simply add a class with a larger width (including a transition to animate the expansion). But I struggle with the positioning of the elements. I placed both the icon and the text (inside a <span>) in separate <div> and tried arranging everything using flex. In the expanded/hover state things look the way they should, but once the <div> shrinks down again, the two divs containing the icon and the text try sharing the little space that is left and hence the icon gets cut off and the text gets squished.

Would appreciate if someone could help me figure out how set this up the way I'd like it to be.

Here's a jsFiddle of what I got so far: Button-GrowOnHover

Plus the code itself:

$(document).ready(function() {
  var button = $("#myButton");

  button.mouseenter(function() {
    $(this).addClass("grow");
  });
  button.mouseleave(function() {
    $(this).removeClass("grow");
  });
});
.button-container {
  position: fixed;
  top: 5%;
  right: 5%;
  width: 100px;
  padding: 5px;
  background-color: tomato;
  display: flex;
  justify-content: space-between;
  overflow: hidden;
  transition: width 1s;
}

.button-container.grow {
  width: 300px
}

.button-text-container {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: lightblue;
}

.button-icon-container {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button-container" id="myButton">

  <div class="button-text-container">
    <span>Here comes some text.</span>
  </div>

  <div class="button-icon-container">
    <img src="https://placeholder.pics/svg/100x100/7AFFA6/000000/ICON">
  </div>

</div>
like image 391
JoSch Avatar asked Sep 06 '18 20:09

JoSch


2 Answers

You can do this with only CSS if you rely on flexbox order and you can move the width changes to the text instead of the parent container:

.button-container {
  position: fixed;
  top: 5%;
  right: 5%;
  padding: 5px;
  background-color: tomato;
  display: flex;
  justify-content: space-between;
  overflow: hidden;
}


.button-text-container {
  order:-1;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: lightblue;
  white-space:nowrap; /*Keep text always one line*/
  overflow:hidden;
  width:0;
  transition: width 1s;
}

.button-icon-container {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.button-icon-container:hover + .button-text-container {
  width:200px;
}
<div class="button-container" id="myButton">
  <div class="button-icon-container">
    <img src="https://placeholder.pics/svg/100x100/7AFFA6/000000/ICON">
  </div>
  
  <div class="button-text-container">
    <span>Here comes some text.</span>
  </div>
</div>
like image 178
Temani Afif Avatar answered Nov 14 '22 23:11

Temani Afif


There are better options with css but this does the trick if you want to do it with javascript. Let the actual container that needs to grow change width instead of the one that wraps it.

$(document).ready(function() {
  var button = $("#myButton");

  button.mouseenter(function() {
    $('.button-text-container').addClass("grow");
  });
  button.mouseleave(function() {
    $('.button-text-container').removeClass("grow");
  });
});
.button-container {
  position: fixed;
  top: 5%;
  right: 5%;
  padding: 5px;
  background-color: tomato;
  display: flex;
  justify-content: space-between;

}

.button-text-container.grow {
  width: 300px;
}

.button-text-container {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: lightblue;
  overflow: hidden;
  width: 0px;
  transition: width 1s;
}

.button-icon-container {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button-container" id="myButton">

  <div class="button-text-container">
    <span>Here comes some text.</span>
  </div>

  <div class="button-icon-container">
    <img src="https://placeholder.pics/svg/100x100/7AFFA6/000000/ICON">
  </div>

</div>
like image 37
Mark Baijens Avatar answered Nov 14 '22 22:11

Mark Baijens