The margin of the parent container is influencing the margin of the child element

Purple

Working on displaying a rectangle shape in a browser using divs in my React project. Everything works fine, but when I add margin to the parent base and then draw the boxes, there's some space between the mouse cursor and the actual box.

The same issue occurs if I add a top margin to a base

Check out my code below:

 const divRef = useRef<HTMLDivElement>(null);
    const [mousedown, setMouseDown] = useState(false);
    const [last_mousex, set_last_mousex] = useState(0);
    const [last_mousey, set_last_mousey] = useState(0);
    const [mousex, set_mousex] = useState(0);
    const [mousey, set_mousey] = useState(0);
    const [rectx, setrectx] = useState(0);
    const [recty, setrecty] = useState(0);
    const [rectwidth, setrectwidth] = useState(0);
    const [rectheight, setrectheight] = useState(0);
    const [visual, setVisualRect] = useState(false);

    const mouseDown = (event: any) => {
        set_last_mousex(event.clientX);
        set_last_mousey(event.clientY);
        setMouseDown(true);
    };

    const mouseMove = (event: any) => {
        set_mousex(event.clientX);
        set_mousey(event.clientY);
        visualRect();
    };

    const visualRect = () => {
        if (mousedown) {
            const width = Math.abs(mousex - last_mousex);
            const height = Math.abs(mousey - last_mousey);
            const rx = mousex < last_mousex ? mousex : last_mousex;
            const ry = mousey < last_mousey ? mousey : last_mousey;
            rectx !== rx && setrectx(rx);
            recty !== ry && setrecty(ry);
            rectheight !== height && setrectheight(height);
            rectwidth !== width && setrectwidth(width);
            setVisualRect(true);
        }
      };

    const mouseUp = () => {
        setMouseDown(false);
        setVisualRect(false);
    };

    return (
        <div className={"base"}>
            <div className={"container"} ref={divRef}>
                <div
                    className={"drawArea"}
                    onMouseDown={mouseDown}
                    onMouseUp={mouseUp}
                    onMouseMove={mouseMove}
                >
                    {visual && 
                        (<div className={"rectBox"} style={{left: rectx, top: recty, width:rectwidth, height:rectheight}}></div>)
                    }
                </div>
            </div>
        </div>
    );

CSS styling:

.base {
  width: 600px;
  height: 500px;
  /* this margin is causing issue */
  margin-left: 200px;
}

.drawArea {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
}

.rectBox {
  position: absolute;
  border: 3px solid #581d1d;
}

.container {
  height: 500px;
  width: 100%;
  background-color: rgb(219, 219, 219);
  position: relative;
}

View demo on CodeSandbox here

Answer №1

According to @CBroe, clientX and clientY are relative to the viewport. To adjust for this, simply subtract the element's viewport X & Y from the coordinates to obtain the proper positioning relative to the element.

For instance, if the element's X is 200px and the click position is 245px, both relative to the viewport, by calculating 245px - 200px, you'll end up with 45px, which corresponds to the element's position as you've removed the element's X value from the click's X value.

  const mouseDown = (event: any) => {
    const x = event.clientX - event.currentTarget.getBoundingClientRect().left
    const y = event.clientY - event.currentTarget.getBoundingClientRect().top
    set_last_mousex(x);
    set_last_mousey(y);
    setMouseDown(true);
  };

  //... 
  
  const mouseMove = (event: any) => {
    const x = event.clientX - event.currentTarget.getBoundingClientRect().left
    const y = event.clientY - event.currentTarget.getBoundingClientRect().top
    set_mousex(x);
    set_mousey(y);
    visualRect();
  };

Learn more about getBoundingClientRect here: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

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

Utilize Bootstrap to combine two tables within a single column efficiently

I am facing an issue with my layout that involves organizing 3 tables in a specific way. Two smaller tables are supposed to take up 3 bootstrap columns on the left side, while one larger table should occupy 9 columns on the right side. However, when I impl ...

Tips for Incorporating HTML Code into an ASP Button's Text Attribute

How can I add a symbol to a button's text without it showing as blank? The symbol in question is an arrow, which you can find here. <asp:button id="btnAdd" runat="server" class="next"/> CSS: .next { content = &#10095; width:50px; } ...

Is it more effective to import an entire library or specific component when incorporating it into Create-React-App?

I have a question about optimizing performance. I understand that every library has its own export method, but for instance, on react-bootstrap's official documentation, it suggests: It is recommended to import individual components like: react-boo ...

Is it considered the most appropriate method to implement a dynamic web page refresh by utilizing PHP, HTML, and AJAX in order to read a

My PHP page currently displays data from a database in tables, but the information is frequently changing. This means that the entire page has to be reloaded every few seconds. I am looking for a way to query the database and update only the section of HT ...

What is preventing me from using .bind(this) directly when declaring a function?

Consider the code snippet below: function x() { this.abc = 1; function f1() { alert(this.abc); }.bind(this) var f2 = function b() { alert(this.abc); }.bind(this); } I am curious about how to make the "this" of the out ...

Struggling to perfectly center the NavBar within the wrap container

After working on my navbar and utilizing this site for guidance, I was able to center it using text align. However, there is an odd indent in the navbar that I can't seem to figure out. This indentation throws off the alignment when centered, giving i ...

Gain command over the underline style of text without relying on the border property

Ingredients: just a simple text input field. Question: Is there a way to customize the size, color, and position of the underline styling on an input tag? I noticed that the property text-decoration-color is supported in the moz browser engine, but I&apos ...

Static Header - Halts Animation on Downward Scroll, Resumes when Scrolling Ceases

I've implemented a fixed menu on my website. Everything seems to be working fine, but here's the issue: When I scroll down and the fixed menu starts animating, if I continue scrolling quickly, the animation pauses. It only continues when I stop ...

Can you explain the differences between offsetHeight, clientHeight, and scrollHeight for me?

Have you ever wondered about the distinction between offsetHeight, clientHeight, and scrollHeight? What about offsetWidth, clientWidth, and scrollWidth? Understanding these differences is crucial for working effectively on the client side. Without this kn ...

Angular directive ceases to trigger

I am currently working on implementing an infinite scrolling directive. Initially, when the page loads and I start scrolling, I can see the console log. However, after the first scroll, it stops working. It seems like it only triggers once. Can anyone poi ...

Ways to ensure that two divs have equal heights based on whichever one has the greater height using CSS

I need help with adjusting the heights of two divs inside a container div using CSS. Specifically, I want the height of the img_box div to match the height of the content_con div based on their actual content. For example, if the content_con div contains t ...

Positioning Backgrounds with Padding in DIV Elements

I am trying to figure out how to add a check mark next to text in a button with specific styling. I have managed to get the check mark aligned properly using Background:left center, but I also want to add padding and adjust spacing. Is there a way to achie ...

The lobster custom font is malfunctioning in Internet Explorer

I am trying to use the unique font called lobster. After downloading the lobster.woff2 file, I stored it in the font folder. In my custom CSS, I added the following: @font-face { font-family: 'Lobster'; font-style: normal; font-weight: 40 ...

Modifying the input type of Material-UI TextField to only accept numbers

Currently, the TextField Material-UI with type = "number" accepts numbers (0-9), comma (,), and double dash(--) However, I only require a single dash(-) I have tried inserting a pattern in inputProps, but it does not seem to work Any assistanc ...

How can elements be displayed differently depending on the return value of a function?

Basically, I am looking to display different content based on the status of a job: Show 'Something1' when the job is not processing Show 'Something2' when the job is running and has a status of '0' Show 'Something3&apos ...

d3.js attempting to animate data, but each time the data is altered it is always perceived as new

I have a JSON dataset that consists of an array of frames, with each frame containing an array of 10 nodes. Each node is represented as a dictionary with the node id and x,y coordinates. My objective is to devise a d3 animation that smoothly transitions be ...

When using the `Document.write()` method, an error is returned stating, "Uncaught TypeError: Cannot read property 'document' of null"

I am currently integrating Angular2 into a website as the front-end framework, and it will be displayed on another website using an iframe. When working with the HTTP post method, I am able to receive a JSON response. Here is the API Post method that retu ...

The conditional statement for multiplying in JavaScript

I have a JavaScript function that selects a report number based on multiple parameters (2 checkboxes, 3 dropdown fields), and the current implementation involves a complex conditional statement as shown below: switch(ReportNumDrop) { case 0 ...

Unexpected problem discovered with Firefox and JqueryUI - content is misaligned within the dialog box

I seem to be having an issue with a dialog that I recently set up. I've been working with jqueryUi for quite a while so I'm not sure why I can't figure this out. When using Firefox, I noticed that the dialog opens and closes when clicking " ...

JSON.stringify does not transform arrays into strings

It seems like I may have approached this task incorrectly, perhaps due to mishandling recursion. I'm unsure of where the mistake lies. You can view the example here. Below is the JavaScript code snippet - function propertyTest(currentObject, key) { ...