Пример вот тут
codepen.io/cleric/pen/uikyh
В нём каждой твари по паре — и абсолютно, и относительно позиционированные блоки, и вложенные в другие позиционированные, и плавающие...
Можно идти 2-мя путями (я пошёл по первому, как по наиболее верному).
Вариант 1
— нужно вставлять закрывающий слой в том же контексте, в котором находится закрываемый элемент (причём сразу за ним)
— выяснием размеры элемента (я предпочитаю для этого getBoundingClientRect, который используется одновременно и для нахождения координат относительно области просмотра)
— при наличии нестатичного позиционирования, узнаём z-index закрываемого слоя (чтобы задать закрывающему слою точно такой же)
Если элемент имеет позиционирование, то необходимо пройти по предкам, начиная с родителя, в поиске первого нестатичного (то бишь контекста). С помощью упомянутого getBoundingClientRect узнаем позицию найденного предка (позицию закрываемого элемента мы нашли выше при нахождении его размеров), берём разницу left, top и получаем координаты.
Осталось только назначить все свойства закрывающему слою и вставить его сразу после элемента, который нужно закрыть.
Плюсы: точно и качественно перекрываем именно то, что нужно
Минусы: нет
Вариант 2
Безусловно, можно вставить и в body, но тогда придётся пройтись по всем контекстам закрываемого элемента, дабы правильно выставить тот упомянутый z-index.
Координаты закрывающего слоя определяются тем же самым getBoundingClientRect у закрываемого элемента.
Плюсы: нет
Минусы: перекрываем самый верхний и стэка контекстов, поэтому перекрываем кардинально всё в этой области (то есть, если элемент, который нужно закрыть, частично перекрыт чем-то, то мы это что-то тоже перекроем)