Изменение размера изображения с помощью calc() css

Я пытаюсь изменить размер любого изображения с существующими свойствами высоты и ширины в процентах (и сохранить пропорции). Я знаю, что transform: scale(1.05) возьмет изображение размером 100 на 100 пикселей и сделает его размером 105 на 105 пикселей, но оно все равно будет занимать только исходное пространство 100x100 в потоке страницы.

Как бы я сделал что-то вроде:

<img src="an.svg" width="100" height="100" alt="bigger please" class="resize"  data-width="100" data-height="100"/>

img.resize {
  height: auto;
  width: calc(original width * 5%);
}

Чтобы браузер отображал изображение размером 105 на 105 пикселей, занимающее все 105x105 пикселей?

Я использую упрощенные числа для этого вопроса, но изображения могут иметь любое значение для любого измерения.

Кроме того, я не могу использовать оболочку или фоновое изображение, но у меня есть доступ к атрибутам высоты данных и ширины данных, присутствующим в изображениях. Codepen находится здесь: https://codepen.io/spicedham/pen/qMKLYq


person spicedham    schedule 13.09.2018    source источник
comment
Изображение 100px на 100px, преобразованное с помощью transform: scale(1.05), по умолчанию будет занимать 105px на 105px в потоке страниц. Если ваше изображение этого не делает, у вас есть дополнительные ограничения, такие как max-width: 100%. Убедитесь, что вы предоставили минимальный, полный и поддающийся проверке пример проблемы.   -  person Obsidian Age    schedule 14.09.2018
comment
Масштаб @ObsidianAge — это визуальное преобразование, поэтому макет/поток не изменится, а содержимое не будет перемещено при увеличении изображения. Также максимальная ширина не повлияет на масштабирование.   -  person Temani Afif    schedule 14.09.2018
comment
@Obsidian Age Добавил кодовую ручку здесь: codepen.io/spicedham/pen/qMKLYq, которая показывает, как масштабирование у меня не работает, но вполне возможно, что я его использую неправильно.   -  person spicedham    schedule 14.09.2018


Ответы (4)


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

проверьте это перо, чтобы увидеть пример. https://codepen.io/calebswank11/pen/gdKBRE

.container {
  width: 300px;
  height: 300px;
}
img {
  display: block;
  width: calc(100% + 5%);
  height: calc(100% + 5%);
  left: -2.5%;
  top:-2.5%;
  position: relative;
}
person Caleb Swank    schedule 13.09.2018
comment
это 5% а не 5px - person Temani Afif; 14.09.2018
comment
Поэтому используйте 5% вместо 5px. Там будет такая же концепция. Занимает 5% от своего родителя. И измените -2,5 на проценты, а также по центру - person Caleb Swank; 14.09.2018
comment
это не для меня .. и вам, вероятно, следует сосредоточиться на том факте, что вы используете SASS, а не чистый CSS - person Temani Afif; 14.09.2018
comment
достаточно справедливо, обновленный ответ и ручка, чтобы отразить чистый css. - person Caleb Swank; 14.09.2018

Я не думаю, что вы можете использовать атрибут ширины/высоты изображения для определения новой ширины/высоты. Вероятно, вы можете рассмотреть встроенные стили и переменную CSS следующим образом:

img {
  width:calc((var(--width) * 5/100 + var(--width))*1px);
  height:auto;
}
<img src="https://picsum.photos/100/100?image=1069" height="100" >
<br>
<img src="https://picsum.photos/100/100?image=1069" height="100" style="--width:100">

person Temani Afif    schedule 13.09.2018
comment
Я не могу использовать встроенные стили, но у меня есть доступ к атрибутам высоты и ширины данных. Можно ли их использовать как переменные? codepen.io/spicedham/pen/qMKLYq - person spicedham; 14.09.2018
comment
@spicedham, к сожалению, вы не можете использовать чистый CSS, единственное решение CSS, которое я вижу здесь, - это встроенная переменная syle + CSS ... Я думаю, вам нужно будет полагаться на JS, в этом случае это должно быть легко - person Temani Afif; 14.09.2018

Если использование тега img не является абсолютно необходимым (и изображение всегда имеет одинаковое соотношение сторон, если оно динамическое), вы можете использовать div с фоновым изображением и присвоить ему height: 0; и padding-bottom: 100% (или любой другой процент, который создаст подходящее соотношение сторон) и измените его таким образом с помощью CSS-преобразований.

person sdjn    schedule 13.09.2018

После исчерпывающего перебора всех перестановок, которые я мог придумать, у меня действительно есть своего рода решение. Для этого требуются две вещи, которых я пытался избежать (контейнер и встроенные стили), но он работает как часть системы. Некоторая дополнительная информация: я работаю над веб-приложением, которое позволяет пользователям устанавливать базовый размер шрифта (например, 12, 14, 16 или 18 pt), а затем также обрабатывает масштабирование в диапазоне от 10% до 300% для пользователи со слабым зрением. У нас есть некоторые изображения (в основном математические выражения), которые встроены в окружающий контент страницы в виде SVG. На уровнях печати и масштабирования по умолчанию SVG с номером «3» имеет тот же размер, что и обычный текст с номером 3 рядом с ним. Но вещи становятся несоответствующими, поскольку другие переменные начинают меняться. Метод, описанный ниже, когда он будет применен, позволит нам точно контролировать, как эти изображения совпадают с окружающим текстом, независимо от размера шрифта или уровня масштабирования.

Вот ссылка на решение в codepen https://codepen.io/spicedham/pen/pxzYYe и вариант с использованием... переменных https://codepen.io/spicedham/pen/MPgxxo.

Вот CSS:

        .container {
            display: inline-flex;
            vertical-align: middle;
            border-left: solid .05em transparent;
            border-right: solid .05em transparent;
        }
        .scaleMe {
            transform: scale(1.1);
            margin: .05em 0;
        }

А вот как выглядят образы и контейнеры:

<span class="container" style="font-size: 300px;"><img class="scaleMe" src="svg.svg" width="300" height="100" alt="" style="font-size: 100px"/></span>

<span class="container" style="font-size: 100px"><img class="scaleMe" src="svg.svg" width="100" height="200" alt="" style="font-size: 200px"/></span>

Проблема, с которой я столкнулся, независимо от того, использовал ли я calc() или transform:scale(), заключалась в том, что я не мог заставить контент последовательно перекомпоновываться вокруг изображения с измененным размером - увеличенное изображение перекрывало смежный контент. Это было бы возможно, если бы все изображения были одинакового размера или все они имели бы одинаковые пропорции, но я не могу на это рассчитывать в нашей системе.

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

Таким образом, решение состояло в том, чтобы создать запасную относительную единицу em. Я взял ширину изображения (скажем, 300 пикселей) и установил ее в качестве размера шрифта для контейнера. Затем я взял высоту изображения (скажем, 100 пикселей) и установил ее в качестве размера шрифта изображения. Это позволяет мне открыть контейнер, чтобы он занимал то же место, что и масштабированное изображение. Обходит ограничение невозможности использовать проценты для ширины границ и точно устанавливает эквивалент процентов для верхнего и нижнего полей изображения.

person spicedham    schedule 27.09.2018