Draggable element with a centered margin of 0 auto

Encountering an issue with jQuery UI sortable/draggable where the element being dragged, when centered using margin:0 auto, starts dragging from the left side of the container instead of the center where it is positioned.

Check out this demo to see the problem in action: http://codepen.io/anon/pen/YqWRvV. Just try dragging the red square.

If you eliminate margin:0 auto from the '.drag' element, you'll notice that the dragging behaves normally.

Any suggestions on how to resolve this issue and ensure the element drags from its true center location when centered using margin:0 auto?

This issue appears to be specific to Google Chrome.

$("#c").sortable();

`.drag {
   margin: 0 auto;
   width: 200px;
   height: 200px;
   background-color: red;
}`

Centering the element with CSS 'calc' does address the problem, but considering my element's width can change dynamically, 'calc' isn't as widely supported as 'margin'.

Although wrapping the draggable in a container resolves the issue, I'm seeking a solution that doesn't involve altering the HTML structure.

UPDATE: It turns out this isn't a jQuery bug but rather a bug within Google Chrome. It seems Chrome retrieves an incorrect position for the element, causing jQuery to initiate the drag from where Chrome inaccurately places it. I've outputted the left position of the element in the console which shows as 13px even though it isn't. Check it out here: http://codepen.io/anon/pen/YqWRvV. I wonder if this issue has been reported.

SOLUTION Discover the solution at: http://codepen.io/anon/pen/MyjeJP. Thank you Julien Grégoire. Please note: This solution may require a method to refresh the helper position.

Answer №1

When working with Chrome and Firefox, you may notice a discrepancy in how they return position values. However, using the offset property can help obtain consistent coordinates, especially when dealing with sortable elements. The issue arises during mouseStart where margins are excluded from calculations, causing problems specifically with auto margins.

To address this issue, one approach is to introduce an option to ignore margins by tweaking the _mouseStart function:

$("#c").sortable({
  ignoreMargins: true
});

$.ui.sortable.prototype._mouseStart = function(event, overrideHandle, noActivation) {
    ...
    if (!this.options.ignoreMargins) {

      this.offset = {
        top: this.offset.top - this.margins.top,
        left: this.offset.left - this.margins.left
      };
    }
    ...
}

http://codepen.io/anon/pen/BKzeMp

Alternatively, without modifying the plugin, adjusting the start and stop event handlers can also resolve the issue. One workaround involves explicitly defining margins within the sortable call, which may lack flexibility. Another method entails dynamically checking and setting auto margins:

$("#c").sortable({
  start: function(e, ui) {
    var marginsToSet = ui.item.data().sortableItem.margins;
    // Set specific margins here to maintain consistency
      ui.item.css('margin-left', marginsToSet.left);
      ui.item.css('margin-top', marginsToSet.top);

  },
  stop: function(e, ui) {
    // Reset margins after dragging stops
    // Ideally this should be dynamic, but determining auto margins dynamically poses challenges.
    ui.item.css('margin', '20px auto');
  }
});

http://codepen.io/anon/pen/mPrdYp

Answer №2

Just wanted to let you know that I tested your Codepen on both Mozilla and Chrome browsers.

I noticed that what you mentioned only applies to Chrome. Interestingly, everything seems to be working fine on Mozilla.

The left property value differs between the two browsers. While dragging, it's set to left: 560px in Mozilla but starts at left: 0 in Chrome.

This discrepancy is causing a significant difference in how the dragging element appears from the left side.

Hopefully this information proves helpful to you!

Answer №3

Make sure to enhance your jQuery code by including the clone helper:

$("#new").sortable({
 helper: "clone"
});

Don't forget to adjust your CSS for better positioning and overflow management:

#new {
  width: 100%;
  padding: 30px 0px;
  border: solid 3px;
  box-sizing: border-box;
  overflow: hidden;
  position: relative;
}

Check out the updated Codepen demo here

Answer №4

After some experimentation, I discovered a solution that works for me which involves using the http://codepen.io/anon/pen/SbbbbX

Replace the use of 'auto' with the 'calc' function in CSS

Answer №5

If you're unable to center using CSS, another option is to center with JQuery. Take a look at the updated Demo in your codebase based on your feedback and requirements mentioned in this post and other answers. Demo

$("#c").sortable();

$(".drag").css("margin-left",($(document).width()/2)-125);
$(window).resize(function(){
   $(".drag").css("margin-left",($(document).width()/2)-125);
});

Answer №6

When using Chrome, it appears that the .sortable() function doesn't accurately determine the position of an element when margin: 0 auto is used and only the left position is set to 0. It seems like you might need to explore alternative methods to horizontally center your element.


One approach is to apply text-align: center to the parent element and use display: inline-block on the child element.

$("#c").sortable();
#c {
  width: 100%;
  padding: 50px 0px;
  border: solid 5px;
  box-sizing: border-box;
  text-align: center;
}

.drag {
  width: 200px;
  height: 200px;
  background-color: red;
  display: inline-block;
}
<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.11.4/jquery-ui.min.js"></script>
<link href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<div id="c">
  <div class="drag"></div>
</div>

Another option is to utilize Flexbox and center child elements by using justify-content: center.

$("#c").sortable();
#c {
  width: 100%;
  padding: 50px 0px;
  border: solid 5px;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
}

.drag {
  width: 200px;
  height: 200px;
  background-color: red;
}
<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.11.4/jquery-ui.min.js"></script>
<link href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<div id="c">
  <div class="drag"></div>
</div>

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

Employing v-btn for navigating to a different route depending on whether a specific condition is satisfied

Is there a way to prevent this button from redirecting to the specified URL? I want to implement a validation check in my method, and if it fails, I need to stop this button from performing any action. Any suggestions or assistance would be highly apprec ...

Troubleshooting the issue of post-initialization store updates not functioning in AlpineJS

When setting up a store, I initially use: document.addEventListener('alpine:init', () => { Alpine.store('selectedInput', 0) }) However, when attempting to update selectedInput within a function later on, it doesn't reflect th ...

Building a dynamic cities dropdown menu in ReactJs based on the chosen country

I have an array called countryList that looks like this: export const countryList = [ {name: 'Singapore', code: 'SG', cities:[ "Ang Mo Kio New Town", "Ayer Raja New Town", ...

Troubleshooting scope evaluation in AngularJS within style tags on IE9 not functioning

My issue involves a div block with a style attribute that includes left:{{left}}px; and right:{{right}}px. Even though $scope.left and $scope.right are being updated, my item still doesn't move as expected. I have created a fiddle to demonstrate th ...

The process of toggling a div to slide up and down explained

I'm attempting to create a slide toggle effect on a hidden DIV when a user hovers over specific link buttons. JavaScript: $(function () { // DOM ready shorthand var $content = $(".sliderText"); var $contentdiv = $(".sliderCo ...

Asynchronous setTimeout for server-side operations

I am currently facing an issue with my web server. Whenever a request is made, the server initiates a phone call, waits for 3 seconds, and then checks if the call is still ongoing. I have utilized setTimeout to achieve this functionality, but it seems to b ...

Capture microphone and audio in a SIP call with sip.js

Greetings Stack Overflow community! I am in need of assistance with a project involving sip.js and VoIP for making real phone calls. The Objective I aim to enable users to record audio from both parties during a call and save the data on a server (either ...

Check out how to utilize the jQuery .ajax Post method in a function

Can an AJAX POST be directed to a specific function in a PHP file? $.ajax({ type: "POST", url: "functions.php", //is there a way to specify a function here? data: "some data...", success: function(){ alert('Succ ...

When using JSON.stringify(value, replacer), the output may vary between Chrome and Firefox

I'm encountering an issue when attempting to utilize JSON.stringify with the "replacer" function. var scriptTag = document.createElement('script'); scriptTag.type = 'text/javascript'; scriptTag.src = 'https:// ...

Is the value being used as the key for the array of objects?

Here is an array of objects: { 'data': [{ value: 1000, year: 1990 }, { value: 1001, year: 1990 }, { value: 1002, year: 1990 }, ...

How to target an ID containing a dot using jQuery

My nodes sometimes have a dot in their ID attribute, as shown in this example: <div id="site_someSite.com"></div> When I try to select this element using jQuery with the following code: variable = $('#site_'+user); (where user is &a ...

Action creator incomplete when route changes

In my React-Redux application, there is an action creator that needs to make 4 server calls. The first three calls are asynchronous and the fourth call depends on the response of the third call. However, if a user changes the route before the response of t ...

The content inside a Textbox cannot be clicked on. I am seeking help with implementing JavaScript to enable it to be

As a newcomer in the world of programming, I am sharing a snippet of my JavaScript and HTML code with you. I am facing an issue where I want to enable users to start typing in a text box upon clicking on the text "User Name", without deleting any existing ...

Adding dynamic elements to a pop-up window with the use of jQuery's .load() function

When implementing Javascript to create a modal, I have encountered an issue where the close button disappears. The modal opens and loads different HTML files dynamically using the jQuery load() method, but the close button vanishes. I suspect that the mod ...

The error message "Unexpected node environment at this time" occurred unexpectedly

I am currently watching a tutorial on YouTube to enhance my knowledge of Node.js and Express. To enable the use of nodemon, I made modifications to my package.json file as shown below: package.json "scripts": { "start": "if [[ $NODE_ENV == 'p ...

Guide to storing a variable value when a user clicks on the client-side in a Grid View:

How can I store data in a variable on client click within a grid view? I have a Stored Procedure that returns Service Id based on the Department code provided. We are binding these details to a Grid View. How can we bind the Service Id to a variable that ...

An onClick event is triggered only after being clicked twice

It seems that the onClick event is not firing on the first click, but only works when clicked twice. The action this.props.PostLike(id) gets triggered with a delay of one click. How can I ensure it works correctly with just one click? The heart state togg ...

Postpone reloading automatically if a division is in view

I endeavored to develop a small project aimed at monitoring flights passing over my vicinity. Utilizing the flight-radar24 API python package, I managed to extract the necessary data. Subsequently, I designed a systemd service to execute my python script ...

What is the best way to send a populated custom class from JavaScript to a .NET MVC app using AJAX?

I am working with a .NET class in C# called BusinessModel: public class BusinessModel { public string BlobName { get; set; } public string NewName { get; set; } } In my MVC Ajax Controller, I have an action called DoBusiness: [HttpPost] public A ...

Attempted to utilize zipstatic but received no feedback

I attempted to utilize the Zipstatic API with jQuery in my code, as shown below. However, I am not receiving any response. Could there be something missing? jQuery(function() { jQuery("#form").hide(); jQuery("#postcode").keyup(function() { var c ...