use shadowdom for this:
"""
class RectRegionShapeFactory {
  // Static property to ensure CSS is injected only once
  static isCSSInjected = false;

  /**
   * Constructor to initialize default options.
   * @param {Object} defaultOptions - Default customization options.
   */
  constructor(defaultOptions = {}) {
    // Merge user-provided default options with inherent defaults
    this.defaultOptions = {
      vertexSize: '25px',       // Size of the corner squares
      vertexColor: '#3498db',   // Color of the corner squares
      borderColor: '#000',      // Color of the rectangle border
      borderWidth: '2px',       // Width of the rectangle border
      ...defaultOptions
    };

    // Inject CSS if not already done
    if (!RectRegionShapeFactory.isCSSInjected) {
      this.injectCSS();
      RectRegionShapeFactory.isCSSInjected = true;
    }
  }

  /**
   * Injects necessary CSS styles into the document head.
   */
  injectCSS() {
    const style = document.createElement('style');
    style.type = 'text/css';
    style.textContent = `
      .rect-region {
        /* CSS Variables */
        --vertex-size: 25px;
        --vertex-color: #3498db;
        --border-width: 2px;
        --border-color: #000;

        position: absolute; /* Fixed on page, not affecting document flow */
        width: var(--width);
        height: var(--height);
        border: var(--border-width) solid var(--border-color);
        box-sizing: border-box;
      }

      .rect-region::before {
        content: '';
        position: absolute;
        width: var(--vertex-size);
        height: var(--vertex-size);
        background-color: var(--vertex-color);
        box-sizing: border-box;
        
        /* Intermediate variables */
        --offset: calc(-0.5 * (var(--border-width) + var(--vertex-size)) );
        --adjusted-width: calc(var(--width) - var(--border-width));
        --adjusted-height: calc(var(--height) - var(--border-width));
        /* Center the first dot at (0,0) by shifting it by half its size */
        top: var(--offset);
        left: var(--offset);

        /* Creating three more squares using box-shadow, centered at each corner */
        box-shadow:
          var(--adjusted-width) 0 0 0 var(--vertex-color),
          var(--adjusted-width) var(--adjusted-height) 0 0 var(--vertex-color),
          0 var(--adjusted-height) 0 0 var(--vertex-color);
      }
    `;
    document.head.appendChild(style);
  }

  /**
   * Creates a rectangle element with centered corner dots.
   * @param {number} x - The left position in pixels.
   * @param {number} y - The top position in pixels.
   * @param {number} width - Width of the rectangle in pixels.
   * @param {number} height - Height of the rectangle in pixels.
   * @param {Object} options - Customization options.
   * @returns {HTMLElement} - The created rectangle element.
   */
  createRect(x, y, width, height, options = {}) {
    // Merge options with default options
    const finalOptions = { ...this.defaultOptions, ...options };

    // Create the rectangle div
    const rect = document.createElement('div');
    rect.classList.add('rect-region');

    // Set position
    rect.style.left = `${x}px`;
    rect.style.top = `${y}px`;

    // Set width and height via CSS variables
    rect.style.setProperty('--width', `${width}px`);
    rect.style.setProperty('--height', `${height}px`);

    // Set customization options via CSS variables
    rect.style.setProperty('--vertex-size', finalOptions.vertexSize);
    rect.style.setProperty('--vertex-color', finalOptions.vertexColor);
    rect.style.setProperty('--border-width', finalOptions.borderWidth);
    rect.style.setProperty('--border-color', finalOptions.borderColor);

    return rect;
  }

  updateRect(rect, options = {}) {
    if (!(rect instanceof HTMLElement)) {
      console.error('The first argument to updateRect must be a DOM element.');
      return;
    }

    if (!rect.classList.contains('rect-region')) {
      console.error('The provided element does not have the class "rect-region".');
      return;
    }

    // Destructure possible options
    const {
      x,
      y,
      width,
      height,
      vertexSize,
      vertexColor,
      borderColor,
      borderWidth
    } = options;

    // Update position if provided
    if (x !== undefined) {
      rect.style.left = typeof x === 'number' ? `${x}px` : x;
    }

    if (y !== undefined) {
      rect.style.top = typeof y === 'number' ? `${y}px` : y;
    }

    // Update size if provided
    if (width !== undefined) {
      rect.style.setProperty('--width', typeof width === 'number' ? `${width}px` : width);
    }

    if (height !== undefined) {
      rect.style.setProperty('--height', typeof height === 'number' ? `${height}px` : height);
    }

    // Update customization options if provided
    if (vertexSize !== undefined) {
      rect.style.setProperty('--vertex-size', vertexSize);
    }

    if (vertexColor !== undefined) {
      rect.style.setProperty('--vertex-color', vertexColor);
      // Also update the box-shadow colors to match the new vertex color
      rect.style.setProperty('--vertex-color', vertexColor);
      // Force re-render of box-shadows by updating the style
      rect.style.boxShadow = rect.style.boxShadow;
    }

    if (borderColor !== undefined) {
      rect.style.setProperty('--border-color', borderColor);
    }

    if (borderWidth !== undefined) {
      rect.style.setProperty('--border-width', borderWidth);
    }
  }
}

// Instantiate the factory with optional default options
const factory = new RectRegionShapeFactory({
  vertexSize: '20px',
  vertexColor: '#e74c3c',
  borderColor: '#2c3e50',
  borderWidth: '3px'
});

// Reference to the container where rectangles will be added
const container = document.getElementById('rectangle-container');

// Create multiple rectangles with different properties
const rect1 = factory.createRect(50, 50, 200, 100, {
  vertexSize: '12px',
  vertexColor: '#1abc9c',
  borderColor: '#16a085',
  borderWidth: '2px'
});

const rect2 = factory.createRect(300, 150, 250, 150, {
  vertexSize: '24px',
  vertexColor: '#f1c40f',
  borderColor: '#f39c12',
  borderWidth: '4px'
});

const rect3 = factory.createRect(600, 80, 180, 120); // Uses default options

// Append rectangles to the container
container.appendChild(rect1);
container.appendChild(rect2);
container.appendChild(rect3);
"""