Keeping DIVs in the Same Spot Using CSS

I have a resizable DIV with 6 handlers and each of them is a small DIV that sits half way inside the resizable DIV and its other half is outside. To resize a DIV, one can drag one of the mentioned 6 small handler DIVs. There is one handler DIV sitting on each corner of the resizable DIV and on each side of the resizable DIV, there is a handler DIV that sits on the perimeter midway between two corner DIVs.

The problem I’m having is that when I resize my DIV, the middle handler DIVs don’t stick to the same spots relative to the corner handler DIVs. I tried using positioned fixed but it didn’t work. I’m sure this problem can be solved with javascript but I was hoping it can be solved using only CSS.

It’s hard to give an accurate answer without seeing the html and css etc but in essence if you want to absolutely position some elements in relation to a parent element then the parent element needs to be position:relative (or absolute) to create the stacking context.

Here’s a short demo to explain the concept.

If that doesn’t answer your question then please post a codepen or similar for more direct help :slight_smile:

Note that fixed positioning is of no help to you here as fixed positioned elements are always placed in relation to the viewport and not their parent.

1 Like

Hi Paul,
Thanks for your reply, unfortunately in my situation the DIVs with the wrapper class applied to them have to be absolutely positioned because they are draggable DIVs. Also The small handler DIV in each of the corners of a resizable DIV stays in the same spot as it is supposed to when the resizable DIV is being resized. The problem is the handler DIVs between the corner DIVs don’t stay in the exactly middle between two corners when the resizable DIV is being resized.

That’s ok as long as the absolute handlers are contained within that absolute parent.

The problem is that doesn’t really tell me anything as to the structure of your page. A reduced codepen is required or at least code to replicate the problem.:slight_smile:

How have you placed those elements? It seems that if you can place those elements ok you can place the middle elements in the same way.

The codepen I gave you is the structure you need whether or not the main div is absolute or relative. It really does depend on your mark up and on how you are managing the resize and the drag ec.

Hi Paul, I have placed my code in jsfiddle. Please check it here

Once you go to that fiddle, you’ll see a red DIV. To resize the DIV, right click anywhere within it and you’ll see the handlers appear within the DIV. I have only created functionalities for the bottom right handler. When you left click on the bottom right handler, hold down the mouse, and drag the bottom right handler, you’ll see that all the corner handlers stay in the same spot relative to the corners. However, the middle handlers seem to not stick to the same spot relative to the corners as the DIV is being resized. Please see if you can spot where I went wrong with my CSS which prevents my middle handlers to not stay in in the same spot relative to the corners.

As I said above you need to place the middle elements using percentages and not fixed px.

In your fiddle you place the middle elements at left:21px which is never going to change. The corner elements are ok because they are related to the corner (e.g. top:-6px). However when you say left:21px that is only going to be correct for the very first time and once resized will have no meaning.

Screen Shot 2022-12-03 at 09.42.20

You need to use percentages.

You could add this css:

.n,.s {
  left: 50% !important;
  transform: translateX(-50%)
}
.e,.w {
  top: 50% !important;
  transform: translateY(-50%)
}

Or alternatively integrate it into your JS as follows.

function addHandles(curEl) {
  var nw = document.createElement("div");
  nw.className = "handle nw";
  nw.style.left = -6 + "px";
  nw.style.top = -6 + "px";
  curEl.appendChild(nw);

  var n = document.createElement("div");
  n.className = "handle n";
  n.style.left = "calc(50% - 6px)";
  n.style.top = -6 + "px";
  curEl.appendChild(n);

  var ne = document.createElement("div");
  ne.className = "handle ne";
  ne.style.right = -7 + "px";
  ne.style.top = -6 + "px";
  curEl.appendChild(ne);

  var e = document.createElement("div");
  e.className = "handle e";
  e.style.right = -7 + "px";
  e.style.top = "calc(50% - 6px)";
  curEl.appendChild(e);

  var w = document.createElement("div");
  w.className = "handle w";
  w.style.left = -6 + "px";
  w.style.top = "calc(50% - 6px)";
  curEl.appendChild(w);

  var sw = document.createElement("div");
  sw.className = "handle sw";
  sw.style.left = -6 + "px";
  sw.style.bottom = -6 + "px";
  curEl.appendChild(sw);

  var s = document.createElement("div");
  s.className = "handle s";
  s.style.left = "calc(50% - 6px)";
  s.style.bottom = -7 + "px";
  curEl.appendChild(s);

  var se = document.createElement("div");
  se.className = "handle se";
  se.style.right = -7 + "px";
  se.style.bottom = -6 + "px";
  curEl.appendChild(se);
}

(although generally I would have preferred all the css was in the css and not the js at all).

(BTW, I couldn’t get the box to resize on my mac. The handles appear but disappear on mouseup so you can’t drag the bottom right corner or anything. I believe the context menu behaves differently on a mac but that would be a js question ore than css.)

This seems to work for a quick fix for the mac.
Add this code:

  if (e.button == 2) {
    return;
  }

Put it in here:

function mouseup(e, mouseObj, status) {
  document.removeEventListener("mousemove", mouseObj, false);
  if (e.button == 2) {
    return;
  }
  if (status.handlesAdded == true) {
    removeElementsByClass("handle", status);
  }
}

It seems on the mac that you press the right button (contextmenu) and then prevent the default you get a mouseup event when you let go. Therefore the handles are added on right click and then immediately removed on mouse up.

However this may be a better question for the js forum as my knowledge of events is limited especially on different systems.:slight_smile: