Элемент позиции над фоновым изображением. Но BG img меняет размер с помощью окна. CSS

У меня есть фоновое изображение, которое меняет размер на размер окна, и мне нужно поместить на него элемент, чтобы он всегда находился в одном и том же месте относительно фонового изображения.

КАК!?

CSS

background:url("http://placehold.it/100x100") no-repeat center center fixed;
-webkit-background-size:"cover";
-moz-background-size:"cover";
-o-background-size:"cover";
background-size:"cover";

Фоновое изображение покрывает весь фон и изменяет размер с помощью окна, но сохраняет пропорции с помощью некоторого наложения.

EDIT - 2016

Мое решение для этого с помощью чистого CSS состоит в том, чтобы позиционировать элемент в середине, а затем правильно смещать его с помощью функции calc. И затем, чтобы изменить его размер, я использую значение vmin:

$offset-top: ...;
$offset-left: ...;

.element {
  top: 50%;
  left: 50%;
  transform: translate(calc(-50% + #{$offset-top}), calc(-50% + #{$offset-top}));
  width: 50vim; 
  height: 50vim;
}

Ответ 1

То, о чем вы просите, вовсе не является тривиальной задачей, в основном это связано с выяснением того, как работает background-size:cover, а затем позиционирует ваш элемент с помощью JavaScript. Из-за природы background-size:cover, как изображение может вытекать из оси x или оси y, это невозможно сделать с помощью CSS.

Вот мое решение проблемы, при загрузке и изменении размера оно вычисляет масштаб изображения и смещение x или y и рисует указатель в соответствующем месте.

jsFiddle (красная точка в Google red 'o')

enter image description here

HTML

<div id="pointer"></div>

CSS

body {
    background:url(https://www.google.com.au/images/srpr/logo4w.png) no-repeat center center fixed;
    -webkit-background-size:cover;
    -moz-background-size:cover;
    -o-background-size:cover;
    background-size:cover;
}

#pointer {
    margin-left:-10px;
    margin-top:-10px;
    width:20px;
    height:20px;
    background-color:#F00;
    position:fixed;
}

JS

var image = { width: 550, height: 190 };
var target = { x: 184, y: 88 };

var pointer = $('#pointer');

$(document).ready(updatePointer);
$(window).resize(updatePointer);

function updatePointer() {
    var windowWidth = $(window).width();
    var windowHeight = $(window).height();

    // Get largest dimension increase
    var xScale = windowWidth / image.width;
    var yScale = windowHeight / image.height;
    var scale;
    var yOffset = 0;
    var xOffset = 0;

    if (xScale > yScale) {
        // The image fits perfectly in x axis, stretched in y
        scale = xScale;
        yOffset = (windowHeight - (image.height * scale)) / 2;
    } else {
        // The image fits perfectly in y axis, stretched in x
        scale = yScale;
        xOffset = (windowWidth - (image.width * scale)) / 2;
    }

    pointer.css('top', (target.y) * scale + yOffset);
    pointer.css('left', (target.x) * scale + xOffset);
}

Ответ 2

Мне нужно будет догадаться о вашей разметке, но предположим, что у вас есть контейнер для фонового изображения, а другое изображение, которое должно быть также центрировано, находится внутри него:

<div class="holdBGimg">
    <img src="image.jpg">
</div>

вы можете сделать что-то вроде:

.holdBGimg {
    position: relative;
}
.holdBGimg img {
    width: 100px;
    height: 100px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -50px;
    margin-left: -50px;
}

где вы компенсируете смещение высоты и ширины, убрав половину этого измерения из относительных полей.

Если вы хотите масштабировать его, решение может быть больше по строкам:

.holdBGimg {
    position: relative;
}
.holdBGimg img {
    width: 20%;
    height: 20%;
    position: absolute;
    top: 40%;
    left: 40%;
}

Это все зависит от размера изображения, которое вы пытаетесь центрировать.

Ответ 3

Добавьте центрирующий контейнер:

#container {
    position: fixed;
    width: 0;
    height: 0;
    top: 50%;
    left: 50%;
    overflow: visible;
}

И затем добавьте position: relative элементы внутри.

Ответ 4

Относительное (масштабируемое, отзывчивое, вставляемое слово buzz здесь) единиц (%).

Отзывчивый дизайн требует много работы. Вам нужно будет проверить, где области изображения, которые вы хотите выровнять, соответствуют размеру окна, а затем соответствуют этим значениям для размещения элементов в соответствии с размером окна. Но крышка уходит от формата изображения самого изображения и соответствует ширине или высоте. Таким образом, в зависимости от соотношения сторон окна, это испортит ваш макет.

Вы можете попробовать использовать jQuery и javascript для получения размеров окна, jquery затем сопоставляет размер вашего изображения с этим и изменяет размеры ваших элементов. Много работы по кодированию, жесткие на загрузках страниц, но мы должны жертвовать, не так ли?

Ответ 5

Я бы создал массив позиций для реквизита, который вы собираетесь наложить на фон. Используйте положения x и y в полноэкранном фоновом изображении...

var propPositions = [
  { name: "StoveBurner1", x: 23, y: 566 },
  { name: "StoveBurner2", x: 676, y: 456 },
  { name: "TableChair1", x: 765, y: 35 },
  ...
];

Вам нужно также удержать размер фона в полном размере, чтобы вы могли использовать его при изменении размера, чтобы вычислить коэффициент масштабирования.

var fullBackgroundSize = { width: 1920, height: 1080 };

Когда размер изображения изменяется, вычислите масштабный коэффициент, а затем масштабируйте позиции x и y для каждого элемента массива...

for (var i = 0; i < propPositions.length; i++)
{
    propPositions[i].x *= scalingFactor;
    propPositions[i].y *= scalingFactor;
}

Это позволит вам точно позиционировать все ваши реквизиты независимо от размера изображения.

Это также позволяет вам искать позиции по имени, что позволит вам делать такие вещи, как...

placeObject(pot1, "StoveBurner1");
placeObject(pot2, "StoveBurner2");
placeObject(SittingPerson, "TableChair1");

Таким образом, единственный код, который вычисляет позиции и перемещает объекты к ним, находится в одной небольшой функции.