Как получить высоту div для автоматической настройки на размер фона?

270

Как мне получить div, чтобы автоматически подстраиваться под размер фона, который я для него установил, не устанавливая для него конкретную высоту (или минимальную высоту)?

JohnIdol
источник

Ответы:

255

Другим, возможно, неэффективным решением было бы включение изображения в imgэлемент, для которого установлено значение visibility: hidden;. Затем сделайте background-imageокружающий div таким же, как изображение.

Это установит окружающий div к размеру изображения в imgэлементе, но отобразит его как фон.

<div style="background-image: url(http://your-image.jpg);">
 <img src="http://your-image.jpg" style="visibility: hidden;" />
</div>
ТЦМВ
источник
16
не совсем полезно, так как изображение будет использовать «пробел», а содержимое будет выглядеть с большим полем сверху.
Барт Каликсто
35
Возможно, я что-то упускаю, но если вы все imgравно собираетесь вставить свою разметку, почему бы просто не скрыть фактическое <img>и не заморачиваться с тем или background-imageдругим? Какое преимущество в том, чтобы делать вещи таким образом?
Марк Амери
3
Хороший ответ, но разве браузер не должен загружать его дважды?
www139
8
@ www139 Когда вы говорите «загрузить», что именно вы имеете в виду? Как только изображение загружено, оно предположительно кэшируется. С этого момента любые другие запросы основаны на локальной копии. Так что нет. Он не загружается дважды. Но он загружается дважды.
Tmac
2
@MarkAmery Одна из самых крутых вещей в background-imageтом, что он может использовать режимы наложения CSS , а imgне может.
Аарон Грей
539

Есть очень хороший и крутой способ заставить фоновое изображение работать как imgэлемент, чтобы оно heightавтоматически настраивало его . Вам нужно знать изображение widthи heightсоотношение. Установите heightдля контейнера значение 0 и установите padding-topпроцентное соотношение в зависимости от отношения изображения.

Это будет выглядеть следующим образом:

div {
    background-image: url('http://www.pets4homes.co.uk/images/articles/1111/large/feline-influenza-all-about-cat-flu-5239fffd61ddf.jpg');
    background-size: contain;
    background-repeat: no-repeat;
    width: 100%;
    height: 0;
    padding-top: 66.64%; /* (img-height / img-width * container-width) */
                /* (853 / 1280 * 100) */
}

Вы только что получили фоновое изображение с автоматической высотой, которая будет работать как элемент img. Вот рабочий прототип (вы можете изменить размер и проверить высоту div): http://jsfiddle.net/TPEFn/2/

Hasanavi
источник
23
Действительно потрясающе! Просто для будущих поколений, которые следят за этим ответом, если вы используете компас (scss), я создал из этого миксина, используя его вспомогательные функции для выполнения вычислений за вас: @mixin div-same-size-as-background-img($url) { background-image: url($url); background-size: contain; background-repeat: no-repeat; width: 100%; height: 0; padding-top: percentage(image-height($url) / image-width($url)); }
Бенджамин К.,
20
К сведению тех, кто интересуется, верхний слой не создает пустое пространство, потому что он просто добавляет высоту элементу. Изображение является фоновым изображением, поэтому оно отображается с правильным расположением и интервалом. Это довольно глупо, что мы должны придумать такие приемы для CSS.
ahnbizcad
9
К сожалению, padding-top не позволяет вам помещать в div что-либо еще, например элементы формы поверх фона.
Гэри Хейс
14
@GaryHayes вы можете установить position:relativediv и поместить еще один div с position:absolute; top:0; bottom:0; left:0; right:0;set
lexith
17
Хотя этот метод работает для отображения фонового изображения, он делает сам div менее полезным, заполняя его отступами. Криптик предложил добавить внутри контейнера абсолютно позиционированный div, но зачем тогда использовать фоновое изображение? Затем вы можете просто использовать фактическое изображение в содержимом div, если вы собираетесь просто позиционировать абсолютно все. Это побеждает цель использования фонового изображения в первую очередь.
Полмз
35

Нет способа автоматически настроить размер фонового изображения с помощью CSS.

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

Вы также можете взломать некоторый javascript для изменения размера div в зависимости от размера изображения (после того, как изображение было загружено) - это в основном то же самое.

Если вам нужен ваш div для автоматической подгонки изображения, я могу спросить, почему бы вам просто не вставить <img>тег в ваш div?

Орион Эдвардс
источник
Спасибо - но мне это нужно в качестве фона, чтобы трюк с изображением этого не делал. Я думаю, что я собираюсь взломать Javascript, как вы говорите, в худшем случае, но, вероятно, оно того не стоит.
JohnIdol
3
^^ Это, вероятно, не очень хорошая идея. Браузер может занять несколько секунд, прежде чем ваше изображение будет загружено, и вы не сможете измерить его до тех пор, так что ваш div будет зависать в неправильном размере в течение довольно долгого времени!
Орион Эдвардс
1
Он мог просто запустить JavaScript, когда документ будет готов.
Скотт Теслер
1
Вы не можете изменить srcобъект imgс медиа-запросами, но вы можете изменить файл, используемый в качестве фонового изображения с медиа-запросами.
Скотт Маркус
21

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

.wrapper {
  width: 100%;
  /* whatever width you want */
  display: inline-block;
  position: relative;
  background-size: contain;
  background: url('https://upload.wikimedia.org/wikipedia/en/thumb/6/67/Wiki-llama.jpg/1600px-Wiki-llama.jpg') top center no-repeat;
  margin: 0 auto;
}
.wrapper:after {
  padding-top: 75%;
  /* this llama image is 800x600 so set the padding top % to match 600/800 = .75 */
  display: block;
  content: '';
}
.main {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  color: black;
  text-align: center;
  margin-top: 5%;
}
<div class="wrapper">
  <div class="main">
    This is where your overlay content goes, titles, text, buttons, etc.
  </div>
</div>

horsejockey
источник
2
-1 для использования! Важный - и ссылка на другой ответ. Пожалуйста, подумайте над тем, чтобы скопировать соответствующий код из другого ответа (с указанием авторства), чтобы он был более полным и содержал ссылки.
totallyNotLizards
@jammypeach это лучше?
хоккей
1
@horsejockey, если я что-то упустил, это не масштабирует изображение. Это просто маскирует это.
dwkns
@dwkns Как ни странно, все фоновые вызовы должны быть в одном элементе. Я обнаружил, что это обрезка, когда я указал «background: url ()» для определенного идентификатора и «background-size: Содержать» в общем классе.
Натан Уильямс
Обновление @dwkns: я смог решить эту проблему, используя «background-image: url ()» вместо «background: url ()».
Натан Уильямс
15

Может быть, это может помочь, это не совсем фон, но вы поняли:

<style>
div {
    float: left;
    position: relative;
}
div img {
    position: relative;
}

div div {
    position: absolute;
    top:0;
    left:0;
}
</style>

<div>
    <img src="http://antwrp.gsfc.nasa.gov/apod/image/0903/omegacen_davis.jpg" />
    <div>Hi there</div>
</div>
Лука Маттеис
источник
объясните пожалуйста, почему вы сохранили положение img как относительное?
Дивьяншу Джимми
1
Вероятно, потому, что float: left;сломал его позиционирование
Исаак
12

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

.imaged-container{
  background-image:url('<%= asset_path("landing-page.png") %> ');
  background-repeat: no-repeat;
  background-size: 100%;
  height: 65vw;
}

Я хотел иметь div в центре изображения, и это позволит мне это.

Carpk
источник
9

Существует чистое решение CSS, которое пропустили другие ответы.

Свойство «content:» в основном используется для вставки текстового содержимого в элемент, но также может использоваться для вставки содержимого изображения.

.my-div:before {
    content: url("image.png");
}

Это заставит div изменить его высоту до фактического размера пикселя изображения. Чтобы изменить ширину тоже, добавьте:

.my-div {
    display: inline-block;
}
Берни Сампшон
источник
1
Мне нравится это решение, но когда браузер становится меньше, под заголовком изображения остается много пустого пространства, которое настроено на адаптивность.
MG1
6

Вы можете сделать это на стороне сервера: измерив изображение, а затем установив размер div, ИЛИ загрузив изображение в JS, прочитайте его атрибуты и затем установите размер DIV.

И вот идея, поместите то же изображение внутри элемента div, что и тег IMG, но сделайте его видимым: скрытый + игра с относительной позицией + этот элемент в качестве фона.

Итай Моав -Малимовка
источник
лол, зачем нужна серверная сторона? Это должно уметь быть реализовано с помощью CSS.
GTHell
1
@ GTHell хахаха - проверь год, на который я ответил
Итай Моав -Малимовка
@ ItayMoav-Malimovka хе-хе, этого не заметил.
GTHell
5

У меня возникла эта проблема, и я нашел ответ Хасанави, но у меня возникла небольшая ошибка при отображении фонового изображения на широком экране - фоновое изображение не распространялось на всю ширину экрана.

Итак, вот мое решение - на основе кода Хасанави, но лучше ... и оно должно работать как на сверхширокых, так и на мобильных экранах.

/*WIDE SCREEN SUPPORT*/
@media screen and (min-width: 769px) { 
    div {
        background-image: url('http://www.pets4homes.co.uk/images/articles/1111/large/feline-influenza-all-about-cat-flu-5239fffd61ddf.jpg');
        background-size: cover;
        background-repeat: no-repeat;
        width: 100%;
        height: 0;
        padding-top: 66.64%; /* (img-height / img-width * container-width) */
                    /* (853 / 1280 * 100) */
    }
}

/*MOBILE SUPPORT*/
@media screen and (max-width: 768px) {
    div {
        background-image: url('http://www.pets4homes.co.uk/images/articles/1111/large/feline-influenza-all-about-cat-flu-5239fffd61ddf.jpg');
        background-size: contain;
        background-repeat: no-repeat;
        width: 100%;
        height: 0;
        padding-top: 66.64%; /* (img-height / img-width * container-width) */
                    /* (853 / 1280 * 100) */
    }
}

Как вы могли заметить, background-size: contain;свойство не очень хорошо вписывается в очень широкие экраны, а background-size: cover;свойство не очень хорошо вписывается в мобильные экраны, поэтому я использовал этот @mediaатрибут, чтобы поэкспериментировать с размерами экрана и решить эту проблему.

Мартин Шварц
источник
3

Как насчет этого :)

.fixed-centered-covers-entire-page{
    margin:auto;
    background-image: url('https://i.imgur.com/Ljd0YBi.jpg');
    background-repeat: no-repeat;background-size:cover;
    background-position: 50%;
    background-color: #fff;
    left:0;
    right:0;
    top:0;
    bottom:0;
    z-index:-1;
    position:fixed;
}
<div class="fixed-centered-covers-entire-page"></div>

Демо: http://jsfiddle.net/josephmcasey/KhPaF/

Джозеф Кейси
источник
3

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

Допустим, вы хотите, чтобы соотношение сторон составляло 4/1, а ширина div составляла 32%:

div {
  width: 32%; 
  padding-bottom: 8%; 
}

Это объясняется тем, что отступ рассчитывается на основе ширины содержащего элемента.

Головная боль
источник
1

Может быть, это может помочь, это не совсем фон, но вы получите простую идею

    <style>
div {
    float: left;
    position: relative;
}
div img {
    position: relative;
}

div div {
    position: absolute;
    top:0;
    left:0;
}
</style>

<div>
    <img src="http://www.planwallpaper.com/static/images/recycled_texture_background_by_sandeep_m-d6aeau9_PZ9chud.jpg" />
    <div>Hello</div>
</div>
Энгр
источник
1

Вы можете сделать что-то подобное

<div style="background-image: url(http://your-image.jpg); position:relative;">
 <img src="http://your-image.jpg" style="opacity: 0;" />
<div style="position: absolute;top: 0;width: 100%;height: 100%;">my content goes here</div>
</div>
Mas
источник
1

Если вы знаете соотношение изображения во время сборки, хотите, чтобы высота была основана на высоте окна, и вы хорошо ориентируетесь на современные браузеры (IE9 +) , тогда вы можете использовать единицы просмотра для этого:

.width-ratio-of-height {
  overflow-x: scroll;
  height: 100vh;
  width: 500vh; /* width here is 5x height */
  background-image: url("http://placehold.it/5000x1000");
  background-size: cover;
}

Не совсем то, о чем спрашивал ОП, но, вероятно, хорошо подходит для многих, кто просматривает этот вопрос, поэтому хотел дать здесь еще один вариант.

Скрипка: https://jsfiddle.net/6Lkzdnge/

fredrivett
источник
1

Я посмотрел на некоторые решения, и они великолепны, но я думаю, что нашел удивительно простой способ.

Во-первых, нам нужно получить соотношение из фонового изображения. Мы просто делим одно измерение на другое. Тогда мы получаем что-то вроде, например, 66,4%

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

height: calc(0.664 * 100vw);

Для меня это работает, правильно устанавливает высоту div и изменяет его при изменении размера окна.

Landeeyo
источник
1

Предположим, у вас есть что-то вроде этого:

<div class="content">
    ... // inner HTML
</div>

и вы хотите добавить фон, но вы не знаете размер изображения.

У меня была похожая проблема, и я решил ее с помощью сетки:

HTML

<div class="outer">
    <div class="content">
        ... // inner HTML
    </div>
    <img class="background" />
</div>

CSS

.outer{
    display: grid;
    grid-template: auto / auto;
    // or you can assign a name for this block
}
.content{
    grid-area: 1 / 1 / 2 / 2;
    z-index: 2;
}
.background{
    grid-area: 1 / 1 / 2 / 2;
    z-index: 1;
}

z-indexпросто для размещения изображения на самом деле на фоне, вы можете, конечно, разместить img.backgroundнад div.content.

ПРИМЕЧАНИЕ : это может привести к тому div.content, что картинка имеет одинаковую высоту, поэтому если у div.contentвас есть дочерние элементы, расположенные в соответствии с ее высотой, вы можете установить число, отличное от 'auto'.

魏 一 元
источник
0

Возникла эта проблема с Umbraco CMS, и в этом сценарии вы можете добавить изображение в div, используя что-то вроде этого для атрибута 'style' div:

style="background: url('@(image.mediaItem.Image.umbracoFile)') no-repeat scroll 0 0 transparent; height: @(image.mediaItem.Image.umbracoHeight)px"
Крис Хэлкроу
источник
0

Я какое-то время занимался этой проблемой и решил написать плагин jquery для решения этой проблемы. Этот плагин найдет все элементы с классом "show-bg" (или вы можете передать его своему собственному селектору) и вычислит их размеры фонового изображения. все, что вам нужно сделать, это включить этот код, пометить нужные элементы с помощью class = "show

Наслаждайтесь!

https://bitbucket.org/tomeralmog/jquery.heightfrombg

Томер Альмог
источник
0

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

Для примера. у тебя есть

<br/>
<div> . //This you set the width percent to %100
    <div> //This you set the width percent to any amount . if you put it by 50% , it will be half
    </div>
 </div>

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

Надеюсь это поможет :)

FaridAvesko
источник
-1

на самом деле это довольно легко, когда вы знаете, как это сделать:

<section data-speed='.618' data-type='background' style='background: url(someUrl) 
top center no-repeat fixed;  width: 100%; height: 40vw;'>
<div style='width: 100%; height: 40vw;'>
</div>
</section>

хитрость заключается в том, чтобы просто установить вложенный div как обычный div с размерными значениями, такими же, как фоновые размерные значения (в этом примере, 100% и 40vw).

с. Schaefer
источник
Вы устанавливаете высоту, чтобы быть пропорцией ширины окна. Это не сработает во всех случаях - и часть вашего контента, например скорость передачи данных, не имеет ничего общего с вашим ответом.
Полидакс
Разве большинство вещей не "довольно легко, когда вы знаете, как это сделать"?
Скотт Маркус
-2

Я решил это с помощью jQuery. Пока новые правила CSS не допускают такого типа поведения, я считаю, что это лучший способ сделать это.

Настройте свои дивы

Ниже у вас есть div, на котором вы хотите, чтобы фон отображался («герой»), а затем внутренний контент / текст, который вы хотите наложить поверх фонового изображения («внутренний»). Вы можете (и должны) перемещать встроенные стили в класс вашего героя. Я оставил их здесь, чтобы было легко и быстро увидеть, какие стили применяются к нему.

<div class="hero" style="background-image: url('your-image.png'); background-size: 100%; background-repeat: no-repeat; width: 100%;">
    <div class="inner">overlay content</div>
</div>

Рассчитать соотношение сторон изображения

Затем рассчитайте соотношение сторон для вашего изображения, разделив высоту вашего изображения на ширину. Например, если высота вашего изображения составляет 660, а ширина - 1280, соотношение сторон составляет 0,5156.

Установите событие изменения размера окна jQuery для настройки высоты

Наконец, добавьте прослушиватель событий jQuery для изменения размера окна, а затем рассчитайте высоту вашего героя в зависимости от соотношения сторон и обновите его. Это решение обычно оставляет дополнительный пиксель внизу из-за несовершенных вычислений с использованием соотношения сторон, поэтому мы добавляем -1 к результирующему размеру.

$(window).on("resize", function ()
{
    var aspect_ratio = .5156; /* or whatever yours is */
    var new_hero_height = ($(window).width()*aspect_ratio) - 1;
    $(".hero").height(new_hero_height);
}

Убедитесь, что он работает при загрузке страницы

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

function updateHeroDiv()
{
    var aspect_ratio = .5156; /* or whatever yours is */
    var new_hero_height = ($(window).width()*aspect_ratio) - 1;
    $(".hero").height(new_hero_height);
}

$(document).ready(function() 
{       
    // calls the function on page load
    updateHeroDiv(); 

    // calls the function on window resize
    $(window).on("resize", function ()
    {
        updateHeroDiv();        
    }
});
Арт Гайгель
источник
-2

Если вы можете сделать изображение в Photoshop, где непрозрачность основного слоя равна 1 или около того и в основном прозрачна, поместите это изображение в div, а затем сделайте реальное изображение фоновым. ПОТОМ установите непрозрачность img в 1 и добавьте нужные размеры.

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

Томми Николас
источник
-4

просто добавь к div

style="overflow:hidden;"
Тевфик Акташ
источник