Mastering jQuery placement using CSS3 "transform: scale"

There seems to be an issue with jQuery not functioning well with CSS "transform: scale()" (however, it works fine with "transform: translate()")

Please examine this straightforward example:

$(document).ready(function() {

  $('#root').dblclick(function() {
    $('#box').position({
      my: 'right bottom',
      at: 'right bottom',
      of: $('#root')
    });
  })

  $('#box').draggable({
    containment: $('#root'),
  });

});
body {
  position: relative;
  margin: 0;
}
#root {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 500px;
  height: 500px;
  border: solid 2px red;
  transform-origin: 0 0 0;
  transform: scale(0.5);
}
#box {
  position: absolute;
  top: 100px;
  left: 50px;
  display: inline-block;
  width: 50px;
  height: 50px;
  background: red;
  border: solid 1px black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

drag red box :)
<br/>double click in square to position box
<div id="root">
  <div id="box"></div>
</div>

The root node needs to be scaled because I utilize fullscreen mode in my actual application and must adjust content to the window resolution. However, when scaling the parent element, jQuery UI draggable and jQuery position do not function correctly.

The crucial question is how to rectify this issue and make it work seamlessly?

Although there are numerous similar inquiries, a suitable solution remains elusive.

Answer №1

After reviewing this answer originally posted by Martii Laine, I made adjustments to accommodate containment and improve double-click positioning:

$(document).ready(function () {

    var $root = $('#root');
    var $box = $('#box');
  
    var minLeft = parseFloat($root.css("paddingLeft"));
    var minTop = parseFloat($root.css("paddingTop"));
    var maxLeft = minLeft + $root.width() - $box.outerWidth();
    var maxTop = minTop + $root.height() - $box.outerHeight();

    $root.dblclick(function () {
        $box.css({
            left: maxLeft,
            top: maxTop
        });
    })
    
    var zoom = 0.5;
    var click = { x: 0, y: 0 };
  
    $box.draggable({
        start: function (event) {
            click.x = event.clientX;
            click.y = event.clientY;
        },
      
        drag: function (event, ui) {
            var original = ui.originalPosition;
            var left = (event.clientX - click.x + original.left) / zoom;
            var top = (event.clientY - click.y + original.top) / zoom; 
            ui.position = {
                left: Math.max(minLeft, Math.min(maxLeft, left)),
                top: Math.max(minTop, Math.min(maxTop, top))
            };
        }
    });
});
body
{
    position: relative;
    margin: 0;
}

#root
{
    position: absolute;
    top: 20px;
    left: 20px;
    width: 500px;
    height: 500px;
    border: solid 2px red;
    transform-origin: 0 0 0;
    transform: scale(0.5);
}

#box
{
    position: absolute;
    top: 100px;
    left: 50px;
    display: inline-block;
    width: 50px;
    height: 50px;
    background: red;
    border: solid 1px black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

drag red box :)
<br/>double click in square to position box
<div id="root">
    <div id="box"></div>
</div>

To achieve different alignments upon double-clicking within the root div, the code:

$root.dblclick(function () {
    $box.css({
        left: maxLeft,
        top: maxTop
    });
})

can be modified as shown below:

left: minLeft,                  // Left aligned
left: maxLeft,                  // Right aligned
left: (minLeft + maxLeft) / 2,  // Centered (horizontally)

top: minTop,                    // At the top
top: maxTop,                    // At the Bottom
top: (minTop + maxTop) / 2,     // Centered (vertically)

Answer №2

Using an iframe, I successfully applied a transformation to it :)

UPDATE: The previous version of my solution turned out to be buggy. However, I have saved the snippet for anyone who wishes to review it.

/*
 * jQuery UI FIX
 * Take focus on window.transformScale
 */

// Offset fix
(function() {

function getWindow(elem) { return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView; }

jQuery.fn.offset = function( options ) {
  
  // Preserve chaining for setter
  if ( arguments.length ) {
      return options === undefined ?
          this :
          this.each( function( i ) {
              jQuery.offset.setOffset( this, options, i );
          } );
  }
  
  var docElem, win, rect, doc,
      elem = this[ 0 ];
  
  if ( !elem ) {
      return;
  }
  
  // Support: IE <=11 only
  // Running getBoundingClientRect on a disconnected node in IE throws an error
  if ( !elem.getClientRects().length ) {
      return { top: 0, left: 0 };
  }
  
  var transform = $(document.body).css('transform');
  $(document.body).css('transform', 'none');
  
  rect = elem.getBoundingClientRect();
  
  $(document.body).css('transform', transform);
  
  // Make sure element is not hidden...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Replacing a DOM Element on Page Load using jQuery

I am looking to substitute the following HTML element: <input type="submit" id="send_product_enquiry" value="Send Enquiry" class="button"> with this updated version: <input type="submit" id="send_product_enquiry" onclick="ga('send', & ...

Inaccurate Guild Member Filtering

Recently, I've been working on creating a unique member counter for my server. The goal is to accurately count the total number of members in the server, excluding bots, and counting only bots as well. However, when I attempt to display these counts i ...

I'm struggling to make this script replace the values within the table

I am struggling with a script that I want to use for replacing values in a google doc template with data from a google sheet. The script is able to recognize the variables and generate unique file names based on the information from the google sheet. Howev ...

Monochrome tabletop solid in one hue

I'm trying to eliminate the space between the columns in my table so it looks solid. Here's the CSS style I've been using: <style> tr, th, td {margin:0;padding:0;border:0;outline:0;font-size:90%;background:transparent;} table{ margin: ...

How to Convert Python Lists into JavaScript?

octopusList = {"first": ["red", "white"], "second": ["green", "blue", "red"], "third": ["green", "blue", "red"]} squidList = ["first", "second", "third"] for i in range(1): squid = random.choice(squidList) octopus = random. ...

Unable to set the height for ul/div elements

I'm struggling to make my navbar appear when I click the "menu button". The div seems to be present in the code, but with a height of 0. Here's the relevant section of the code causing the issue. Any suggestions on how I can resolve this? var ...

Is it possible to use CSS to create a gap between the cursor and the placeholder text within an input field?

Could you please assist me with a bug I have encountered on an older version of Firefox for OSX (37.0.2)? I have included a screenshot of the issue here: https://i.sstatic.net/dzK0G.png Is there a way to use css to move the first character of the placehol ...

The typescript error TS2339 is triggered by the property 'webkitURL' not being found on the 'Window' type

Currently utilizing Angular 2 in a project that is compiled with TypeScript. Encountering an issue when attempting to generate a blob image: Error TS2339: Property 'webkitURL' does not exist on type 'Window' The TypeScript code causi ...

Which file is the optimal placement for the Bootstrap directory: 'header.php' or 'function.php'?

Having dabbled in WordPress Theme templates for a while, I've decided to try my hand at creating a theme from scratch. After uploading the Bootstrap features onto my server, I'm pondering whether it's better to call the Bootstrap.css files ...

JavaScript - Uncaught TypeError: type[totypeIndex] is not defined

After following a tutorial and successfully completing the project, I encountered a JavaScript error saying "Uncaught TypeError: totype[totypeIndex] is undefined". When I tried to log the type of totype[totypeIndex], it initially showed as String, but late ...

Have I potentially compromised my project by executing the command `npm audit fix --force`?

While working on a React project using Vite, everything was going smoothly. I decided to incorporate some charts and came across the recharts package, which I found quite appealing. So, I added it to my project using the command npm i recharts. After runn ...

The functionality of the WordPress Contact Form 7 Plugin becomes erratic when integrated into dynamically loaded AJAX content

I am currently facing a challenge with integrating the WordPress Contact Form 7 Plugin into a website I have built on WordPress. The theme of the site utilizes jQuery to override default link behavior and AJAX to load pages without refreshing the entire pa ...

Tips for centering content in the middle of a line

How can I center align 3 buttons on a line using CSS and HTML? This is what I have tried so far: 1/ CSS : .center-buttons { display: flex; justify-content: center; } .button { margin: 0 10px; } 2/ HTML: <div class="row"> <di ...

Loading a gallery dynamically using AJAX in a CakePHP application

I am currently working with Cakephp 2.8.0 and I am facing an issue with implementing ajax in my application. I have a list of categories displayed as li links, and upon clicking on a category, I need to remove certain html code, locate the necessary catego ...

Troubleshooting issue: Inability to assign classes to child elements within divs of a designated class

Currently, I am facing an issue while attempting to insert divs into multiple divs that share a common class called ".description". My goal is to assign a unique class to each internal div, but for some reason, this only seems to work for the first div w ...

``The problem of cross-origin resource sharing (CORS)

Encountering a CORS error when sending the request, although it works fine in Postman Error Message: The fetch request to (cloud function url) from my web app origin is being blocked by CORS policy: No 'Access-Control-Allow-Origin' header is p ...

Issue with exporting data from Datatables

I followed the instructions, and the Datatables export function worked perfectly in localhost, but when I tried it in Google Apps script, it didn't work. For more information about the issue, you can visit this link: DataTables TableTools buttons not ...

Triggering a modal window with unique content by clicking on various images

Is there a way to trigger a modal window through clicking on an image? Additionally, can different images open different content upon clicking? I am planning to showcase a portfolio where clicking on an image will activate a modal that displays other image ...

Eliminate the unnecessary code repetition in my functions using Typescript

I have 2 specific functions that manipulate arrays within an object. Instead of repeating the same code for each array, I am looking for a way to create reusable functions. Currently, my functions look like this: setLists(): void { if (this.product.ord ...

Modifying button styles in Angular UI Datepicker

In this plunk, there is an Angular UI Datepicker with a template. I'm trying to customize the colors of the "Today", "Clear", and "Close" buttons by editing the popup.html. However, even after changing the classes in the code, the datepicker still sho ...