Hover with two effects: increase and decrease width of different Ivs

Asked

Viewed 1,429 times

1

I own 5 divs forming a column. I want that when I hover the mouse over one of the columns this column increases the width by 4% and the others become the size of 19%, causing an accordion effect.

I managed to do it with jQuery, but he has one delay on first use, causing you to "blink" the image when superimposed mouse.

I had already noticed this kind of flaw in another project, but in this one I’m not finding a solution with CSS to solve.

$(".col").mouseleave(function(){
    var largura = $(document).width();
    if(largura>420){
        $(this).css("-webkit-transition","300ms");
        enter = $(this).attr("class");
        $(".col").each(function (){
            if($(this).attr("class") != enter){
                $(this).css("width","20%");
            }
        });        
        $(this).css("width","20%");
        $(this).css("filter","grayscale(100%)");
    }
});
$(".col").mouseenter(function(){
    var largura = $(document).width();
    if(largura>420){
        $(this).css("-webkit-transition","900ms");
        $(this).css("filter","grayscale(0%)");
        enter = $(this).attr("class");
        $(".col").each(function (){
            if($(this).attr("class") != enter){
                $(this).css("width","19%");
            }
        });        
        $(this).css("width","24%");
    }
});
.col{
    width: 20%;
    min-height: 678px;
    height: 100%;
    float: left;
    position: relative;
    filter: grayscale(100%);
}
.col-vestibular{
    background-image: url(../img/PSP-1366.png);
    background-size: auto 768px;
    /*adicionado para faciltar a visualização*/
    background-color: #ccc;
}
.col-enem{
    background-image: url(../img/PSP-1366.png);
    background-size: auto 768px;
    /*adicionado para faciltar a visualização*/
    background-color: #c3c;
}
.col-transferencia{
    background-image: url(../img/PSP-1366.png);
    background-size: auto 768px;
    /*adicionado para faciltar a visualização*/
    background-color: #cc3;
}
.col-segunda-graduacao{
    background-image: url(../img/PSP-1366.png);
    background-size: auto 768px;
    /*adicionado para faciltar a visualização*/
    background-color: #3cc;
}
.col-pos-graduacao{
    background-image: url(../img/PSP-1366.png);
    background-size: auto 768px;
    /*adicionado para faciltar a visualização*/
    background-color: #c33;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
   <div class="col col-enem" style="width: 20%; transition: 300ms; filter: grayscale(100%);">
      
   </div>
   <div class="col col-vestibular" style="width: 20%; transition: 300ms; filter: grayscale(100%);">
      
   </div>
   <div class="col col-segunda-graduacao" style="transition: 300ms; filter: grayscale(100%); width: 20%;">
   </div>
   <div class="col col-transferencia" style="width: 20%; transition: 300ms; filter: grayscale(100%);">
      
   </div>
   <div class="col col-pos-graduacao" style="width: 20%; transition: 300ms; filter: grayscale(100%);">      

   </div>
</div>

  • 1

    Why don’t you use the pseudo element Hover? I made one Fiddle very basic example.

  • 1

    The problem is that I need to grow this element and reduce the size of the others with the same effect as Hover, you know?

  • 1

    I tested it here and it doesn’t blink. Give it a shot: https://jsfiddle.net/a23Lvnmc/

  • 1

    It is possible to do this only with CSS, pseudo element Hover and flexbox. It gives a flexbox read that is very easy.

  • 1

    Another tip would be to pre-load the image, I just don’t know if it works efficiently: body::after{position:absolute;width:0;height:0;overflow:hidden;z-index:-1;content:url(../img/PSP-1366.png);}&#xA;

  • 1

    Look at this pen: It will save you: https://codepen.io/dsantoro/pen/mpyjMb

Show 1 more comment

2 answers

2

Still it is possible not to use Javascript for this, using only flexible layout. The only important point to consider is the question of property support, but as nothing was mentioned in the question I leave here as a possible solution.

The idea is to use a display: inline-flex in the element that will be the "container" of <div> which will expand. So you let the width control be done automatically. Then you can use the suggestion of Marconi of, only increase the value of width in the event of :hover:

/* No caso, meu "container" é o próprio body. */
body { display: inline-flex; width: 100% }

div {
  height: 100%;
  transition: 300ms ease-in-out;
  width: 20%
}

div:hover {
  width: 30%
}

div:nth-child(1) { background: #7BB0A6 }
div:nth-child(2) { background: #63393E }
div:nth-child(3) { background: #97CE68 }
div:nth-child(4) { background: #FACA9B }
div:nth-child(5) { background: #897FBA }

/* Regras não relacionadas, servem somente p/ melhorar aparência do snippet. */
* { box-sizing: border-box; margin: 0; padding: 0 }
html, body { height: 100% }
<div>a</div>
<div>b</div>
<div>c</div>
<div>d</div>
<div>e</div>

1


Instead of using background-image, you can insert the image you use from background as <img> within each div, using Object-fit to fill the whole div. This can avoid the "blinker" mentioned.

In addition, your code has a lot of redundancy, both in CSS and jQuery. See below for an example with optimized code, with significant content reduction:

$(".col").each(function(){
   $(this).append("<img src='https://jpeg.org/images/jpeg-home.jpg' />");
});

$(".col").on('mouseleave mouseenter',function(e){
    var largura = $(document).width();

   if(largura>420){
      if(e.type == "mouseleave"){

         enter = $(this).attr("class");
         $(".col").not($(this)).each(function (){
               $(this).css("width","20%");
         });        
         $(this).css({
            "-webkit-transition" : "300ms",
            "width" : "20%",
            "filter" : "grayscale(100%)"
         });

      }
      
      if(e.type == "mouseenter"){
         enter = $(this).attr("class");
         $(".col").not($(this)).each(function (){
               $(this).css("width","19%");
         });        
         $(this).css({
            "-webkit-transition" : "900ms",
            "width" : "24%",
            "filter" : "grayscale(0%)"
         });
      }
   }

});
.col{
    width: 20%;
    min-height: 678px;
    height: 100%;
    float: left;
    position: relative;
    filter: grayscale(100%);
    /*adicionado para faciltar a visualização*/
    background-color: #ccc;
    background-size: auto 768px;
}

.col img{
   width: 100%;
   height: 100%;
   position: absolute;
   top: 0;
   left: 0;
   object-fit: cover;
   object-position: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
   <div class="col col-enem" style="width: 20%; transition: 300ms; filter: grayscale(100%);">
   </div>

   <div class="col col-vestibular" style="width: 20%; transition: 300ms; filter: grayscale(100%);">
   </div>

   <div class="col col-segunda-graduacao" style="transition: 300ms; filter: grayscale(100%); width: 20%;">
   </div>

   <div class="col col-transferencia" style="width: 20%; transition: 300ms; filter: grayscale(100%);">
   </div>

   <div class="col col-pos-graduacao" style="width: 20%; transition: 300ms; filter: grayscale(100%);">      
   </div>
</div>

The Object-* is not compatible with the infamous IE.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.