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

1

I have 5 divs forming a column. I want when I hover over one of the columns that column will increase the width by 4% and the rest will be 19%, causing an accordion effect.

I was able to do with jQuery, however it has a delay on the first use, causing it to "blink" the image when it overlaps the mouse.

I had noticed this type of flaw in another project, but 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><divclass="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>
    
asked by anonymous 13.12.2017 / 20:40

2 answers

1

Instead of using background-image , you can insert the image you use from background to <img> within each div , using object-fit to fill all div . This can avoid the mentioned "blink".

In addition, your code has a lot of redundancy, both in CSS and jQuery. Here's an example of 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><divclass="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 notorious IE.

    
14.12.2017 / 18:51
2

It's still possible not to use Javascript for this, using only Flexible Layout . The only important point to consider is the Property Support issue, however as nothing was mentioned in the question I leave here as a possible solution.

The idea is to use display: inline-flex in the element that will be the "container "of <div> that will expand. So you let the width control be done automatically. Then you can use Marconi , 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>
    
14.12.2017 / 15:24