Make a splitter very thin and grab it

870 views Asked by At

I want to make a draggle splitter between 2 panels. The following is a working version.

Now, I want to make the width of handle as thin as possible (less than 0.1px?), so there is no way to make the width (appear) smaller than 1px?

Additionally, when the splitter is thin, it is hard to select by the mouse. Is there a way to make a splitter easy to grab?

Taking JSBin as example, how did they manage to realise the splitters among the panels?

(function($) {
  $.fn.drags = function(opt) {
    
    opt = $.extend({
      handle: "",
      cursor: "ew-resize",
      min: 10
    }, opt);

    if (opt.handle === "") {
      var $el = this;
    } else {
      var $el = this.find(opt.handle);
    }

    var priorCursor = $('body').css('cursor');

    return $el.css('cursor', opt.cursor).on("mousedown", function(e) {
      
      priorCursor = $('body').css('cursor');
      $('body').css('cursor', opt.cursor);

      if (opt.handle === "") {
        var $drag = $(this).addClass('draggable');
      } else {
        var $drag = $(this).addClass('active-handle').parent().addClass('draggable');
      }
      
      var z_idx = $drag.css('z-index'),
        drg_h = $drag.outerHeight(),
        drg_w = $drag.outerWidth(),
        pos_y = $drag.offset().top + drg_h - e.pageY,
        pos_x = $drag.offset().left + drg_w - e.pageX;
      
      var mouseMove = function(e) {        
        
        var prev = $('.draggable').prev();
        var next = $('.draggable').next();

        var total = prev.outerWidth() + next.outerWidth();
        
        var totalPercentage = parseFloat(prev.css('flex')) +  parseFloat(next.css('flex'));

        var offset = prev.offset();
        if(offset){
          var leftPercentage = ((e.pageX - offset.left - drg_w / 2) / total) * totalPercentage;
          var rightPercentage = totalPercentage - leftPercentage;

          if (leftPercentage * 100 < opt.min || rightPercentage * 100 < opt.min) {
            return;
          }

          prev.css('flex', leftPercentage.toString());
          next.css('flex', rightPercentage.toString());
        }
      }
      
      $drag.css('z-index', 1000).parent().on("mousemove", mouseMove).on("mouseup", function() {
            $(this).off("mousemove", mouseMove).off("mouseup");
            $('body').css('cursor', priorCursor);
            $('.draggable').removeClass('draggable').css('z-index', z_idx);
        });
      e.preventDefault(); // disable selection
    });
  }
})(jQuery);

$('.handle').drags();
.flex-box {
  display: flex;
  width: 100%;
  margin: 0;
  height: 300px;
}
.flex-box .col {
  border: 1px solid grey;    
  flex: 0.33;
  padding: 12px;
  overflow-y: auto;
  overflow-x: hide;
}
.handle {
  width: 1px;
  text-align: center;
  background: grey;
  transition: all ease-in 0.1s;
}
.draggable {
  background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex-box">
  <div class="col">
    <p>Pellentesque ...</p>
  </div>
  <div class="handle"></div>
  <div class="col">
    <p>Pellentesque ...</p>
  </div>
</div>

1

There are 1 answers

2
vicgoyso On BEST ANSWER

If you'd like the handle to appear thinner try applying a negative value to the right "col" e.g. margin-left: -2px; so it overlaps the left "col" border on the left of it. I don't think you can make the width "appear" as 0.1px. Firefox is the only browser that renders such value. (https://css-tricks.com/forums/topic/0-1px-borders/)

.flex-box .col:last-child {
   margin-left: -2px;
}

//raise handle layer to top

.handle {
    .....
    z-index: 9999; 
}

Hope this helps...

*Edit:

This is the closest I could get to your request:

.flex-box {
  display: flex;
  width: 100%;
  margin: 0;
  height: 300px;
}
.flex-box .col {
  border: 1px solid grey;
  flex: 0.33;
  padding: 12px;
  overflow-y: auto;
  overflow-x: hide;
}
.flex-box .col:last-child {
   margin-left: -6px;
}
.handle {
  width: 5px;
  text-align: center; 
  transition: all ease-in 0.1s;
  z-index: 999;
  overflow: visible;  
}
.handle-inner{ 
   width: 5px; 
   height: 100%; 
   position: relative; 
   margin-left: -10px;
} 
.draggable {
  background: grey;  
}

Jsbin : https://jsbin.com/nupefekuhu/edit?html,css,js,output