Вертикально вирівняйте зображення всередині діапазону з чуйною висотою


135

У мене є наступний код, який встановлює контейнер, який має висоту, яка змінюється з шириною, коли браузер змінить розмір (для підтримки квадратного співвідношення сторін).

HTML

<div class="responsive-container">
    <div class="dummy"></div>
    <div class="img-container">
        <IMG HERE>
    </div>
</div>

CSS

.responsive-container {
    position: relative;
    width: 100%;
    border: 1px solid black;
}

.dummy {
    padding-top: 100%; /* forces 1:1 aspect ratio */
}

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

Як я можу вертикально вирівняти IMG всередині контейнера? Усі мої зображення мають різну висоту, і контейнер не може мати фіксовану висоту / висоту лінії, тому що він чутливий ... Будь ласка, допоможіть!


1
Ось просте рішення Flexbox: stackoverflow.com/a/31977476/3597276
Michael Benjamin

Відповіді:


381

Ось методика вирівнювання вбудованих елементів всередині батьків , горизонтальної та вертикальної одночасно:

Вертикальне вирівнювання

1) У такому підході ми створюємо inline-block(псевдо-) елемент як першу (або останню) дитину батьків і встановлюємо його heightвластивість 100%приймати всю висоту свого батьківського .

2) Крім того, додавання vertical-align: middleзберігає вбудовані (-блокові) елементи в середині простору рядка. Отже, ми додаємо, що CSS-декларація для першої дитини та наш елемент ( зображення ) і те, і інше.

3) Нарешті, для того, щоб видалити символ пробілу між вбудованими (-блоковими) елементами, ми могли встановити розмір шрифту батьківського на нуль на font-size: 0;.

Примітка. Я використав методику заміни зображення Ніколя Галлахера в наступному.

Які переваги?

  • Контейнер ( батьківський ) може мати динамічні розміри.
  • Не потрібно чітко вказувати розміри елемента зображення.

  • Ми можемо легко використовувати цей підхід для вирівнювання <div>елемента також по вертикалі ; який може мати динамічний зміст (висота та / або ширина). Але зауважте, що вам потрібно заново встановити font-sizeвластивість divдля відображення внутрішнього тексту. Демо - версія .

<div class="container">
    <div id="element"> ... </div>
</div>
.container {
    height: 300px;
    text-align: center;  /* align the inline(-block) elements horizontally */
    font: 0/0 a;         /* remove the gap between inline(-block) elements */
}

.container:before {    /* create a full-height inline block pseudo=element */
    content: ' ';
    display: inline-block;
    vertical-align: middle;  /* vertical alignment of the inline element */
    height: 100%;
}

#element {
    display: inline-block;
    vertical-align: middle;  /* vertical alignment of the inline element */
    font: 16px/1 Arial sans-serif;        /* <-- reset the font property */
}

Вихід

По вертикалі вирівняйте елемент у своїй ємності

Чуйний контейнер

Цей розділ не збирається відповісти на питання, оскільки ОП вже знає, як створити контейнер, що реагує. Однак я поясню, як це працює.

Для того щоб змінити висоту елемента контейнера з його шириною (з урахуванням співвідношення сторін), ми могли б використовувати значення відсотка для paddingвластивості верхній / нижній .

Процентне значення на верхній / нижній прокладкою або краями є відносно ширини містить блоку.

Наприклад:

.responsive-container {
  width: 60%;

  padding-top: 60%;    /* 1:1 Height is the same as the width */
  padding-top: 100%;   /* width:height = 60:100 or 3:5        */
  padding-top: 45%;    /* = 60% * 3/4 , width:height =  4:3   */
  padding-top: 33.75%; /* = 60% * 9/16, width:height = 16:9   */
}

Ось онлайн демонстрація . Прокоментуйте рядки знизу та змініть розмір панелі, щоб побачити ефект.

Також ми можемо застосувати paddingвластивість до макетної дитини або :before/ :afterпсевдоелементу для досягнення того ж результату. Але до відома , що в цьому випадку процентне значення на paddingце по відношенню до ширині від .responsive-containerсебе.

<div class="responsive-container">
  <div class="dummy"></div>
</div>
.responsive-container { width: 60%; }

.responsive-container .dummy {
  padding-top: 100%;    /*  1:1 square */
  padding-top: 75%;     /*  w:h =  4:3 */
  padding-top: 56.25%;  /*  w:h = 16:9 */
}

Демонстрація №1 .
Демонстрація №2 (Використання :afterпсевдоелемента)

Додавання вмісту

Використання padding-topвластивості викликає величезний простір у верхній або нижній частині вмісту, всередині контейнера .

Для того , щоб виправити це, ми повинні обернути вміст з допомогою елемента - оболонки, видаліть цей елемент з документа нормального потоку, використовуючи абсолютне позиціонування , і , нарешті , розгорнути обгортку (бушель , використовуючи top, right, bottomі leftвластивість) , щоб заповнити весь простір свого батька, контейнер .

Ось і ми:

.responsive-container {
  width: 60%;
  position: relative;
}

.responsive-container .wrapper {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
}

Ось онлайн демонстрація .


Збираються всі разом

<div class="responsive-container">
  <div class="dummy"></div>

  <div class="img-container">
    <img src="http://placehold.it/150x150" alt="">
  </div>
</div>
.img-container {
  text-align:center; /* Align center inline elements */
  font: 0/0 a;       /* Hide the characters like spaces */
}

.img-container:before {
  content: ' ';
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.img-container img {
  vertical-align: middle;
  display: inline-block;
}

Ось РОБОТА ДЕМО .

Очевидно, ви можете уникнути використання ::beforeпсевдоелементу для сумісності браузера та створити елемент як перший дочірник із .img-container:

<div class="img-container">
    <div class="centerer"></div>
    <img src="http://placehold.it/150x150" alt="">
</div>
.img-container .centerer {
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

ОНОВЛЕНО ДЕМО .

Використання max-* властивостей

Щоб зберегти зображення всередині коробки на меншій ширині, ви можете встановити max-heightта max-widthвластивість зображення:

.img-container img {
    vertical-align: middle;
    display: inline-block;
    max-height: 100%;  /* <-- Set maximum height to 100% of its parent */
    max-width: 100%;   /* <-- Set maximum width to 100% of its parent */
}

Ось ОНОВЛЕНО ДЕМО .


1
Привіт Хашем, дякую за вашу відповідь - це працювало як магія для браузерів настільних ПК, навіть при повторному розмірі на менші ширини. Але, на жаль, зображення з’являються поза місцем, розташованим під дією контейнера, на мобільному пристрої (Android v2.3.5). Будь-яка ідея виправити це?
користувач1794295

3
@ user1794295 Я перевірив цю скрипку на трьох пристроях Android з android v2.3 (Galaxy S II, Galaxy Note, Motorola Droid 4) через browserstack.com, Все працює як я очікував. Результат можна знайти тут: browserstack.com/screenshots /… . Надайте скріншот або зробіть певний тест своєї проблеми. Я допоможу, наскільки це можливо.
Hashem Qolami

1
Привіт ось кілька скріншотів: browserstack.com/screenshots/… - як ви бачите з меншими пристроями (наприклад, Xperia, LG Nexus 4), зображення з’являються під контейнерами ... що відбувається ?!
користувач1794295

3
@HashemQolami Це найдивовижніша річ CSS, оскільки я почав створювати веб-сайти :).
Олександр Солоник

1
Дякую за font-size: 0;!
Йоганнес Ліберманн

47

З флексом це легко:

ПІДМОГА

Просто додайте в контейнер із зображеннями наступне:

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex; /* add */
    justify-content: center; /* add to align horizontal */
    align-items: center; /* add to align vertical */
}

2
Це рішення працює і в моєму випадку набагато елегантніше. CSS3 Flex - приголомшливий!
Даніель Боннелл

2
Це не працює в Safari :( Я думаю, проблема в гнучкості
yennefer

1
@yennefer для safari використовуйте -webkit-префікс або спробуйте бібліотеку типу prefixfree.js :)
QUB3X

Це не працює, коли висота контейнера відповідає (у відсотках).
jenlampton

1
Ідеальне рішення!
Нірус

16

Використовуйте цей css, оскільки для нього вже є розмітка:

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
}

.img-container > img {
  margin-top:-50%;
  margin-left:-50%;  
}

Ось робочий JsBin: http://jsbin.com/ihilUnI/1/edit

Це рішення працює лише для квадратних зображень (оскільки значення відсоткового значення вгорі залежить від ширини контейнера, а не від висоти). Для зображень у довільному розмірі ви можете зробити наступне:

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%); /* add browser-prefixes */
}

Робоче рішення JsBin: http://jsbin.com/ihilUnI/2/edit


Вибачте, для мене це не працює - це просто зменшення розміру зображень до половини ширини контейнера.
користувач1794295

2
Я не бачу, як це може статися із згаданого я CSS. Надайте, будь ласка, робочий зразок, який я бачу, щоб я міг покращити свою відповідь. PS: Я також запропонував інше рішення :)
Tibos

11

Можна центрувати зображення як горизонтально, так і вертикально, використовуючи margin: autoта абсолютне позиціонування. Також:

  1. Додаткова розмітка можлива за допомогою псевдоелементів.
  2. Середню частину ВЕЛИЧИХ зображень можна відображати за допомогою мінус-лівого, верхнього, правого та нижнього значень.

.responsive-container {
  margin: 1em auto;
  min-width: 200px;       /* cap container min width */
  max-width: 500px;       /* cap container max width */
  position: relative;     
  overflow: hidden;       /* crop if image is larger than container */
  background-color: #CCC; 
}
.responsive-container:before {
  content: "";            /* using pseudo element for 1:1 ratio */
  display: block;
  padding-top: 100%;
}
.responsive-container img {
  position: absolute;
  top: -999px;            /* use sufficiently large number */
  bottom: -999px;
  left: -999px;
  right: -999px;
  margin: auto;           /* center horizontally and vertically */
}
<p>Note: images are center-cropped on &lt;400px screen width.
  <br>Open full page demo and resize browser.</p>
<div class="responsive-container">
  <img src="http://lorempixel.com/400/400/sports/9/">
</div>
<div class="responsive-container">
  <img src="http://lorempixel.com/400/200/sports/8/">
</div>
<div class="responsive-container">
  <img src="http://lorempixel.com/200/400/sports/7/">
</div>
<div class="responsive-container">
  <img src="http://lorempixel.com/200/200/sports/6/">
</div>


Дякую! ваш. Response-контейнер img css був єдиним, хто працював на мене.
Діого Гарсія

4

Спробуйте це

  .responsive-container{
          display:table;
  }
  .img-container{
          display:table-cell;
          vertical-align: middle;
   }

Вибачте, це не працює, я думаю, тому що моя .img-containerабсолютно розміщена - це необхідно для збереження квадратного співвідношення сторін / динамічної висоти.
користувач1794295

2

Ось методика, яка дозволяє центрувати будь-який вміст як вертикально, так і горизонтально!

В основному вам потрібні два контейнери і переконайтеся, що ваші елементи відповідають наступним критеріям.

Контейнер:

  • повинні мати display: table;

Внутрішній контейнер:

  • повинні мати display: table-cell;
  • повинні мати vertical-align: middle;
  • повинні мати text-align: center;

Вікно вмісту:

  • повинні мати display: inline-block;

Якщо ви використовуєте цю техніку, просто додайте своє зображення (разом із будь-яким іншим вмістом, який ви хочете разом із ним) у вікно вмісту.

Демонстрація:

body {
    margin : 0;
}

.outer-container {
    position : absolute;
    display: table;
    width: 100%;
    height: 100%;
    background: #ccc;
}

.inner-container {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

.centered-content {
    display: inline-block;
    background: #fff;
    padding : 12px;
    border : 1px solid #000;
}

img {
   max-width : 120px;
}
<div class="outer-container">
   <div class="inner-container">
     <div class="centered-content">
        <img src="https://i.stack.imgur.com/mRsBv.png" />
     </div>
   </div>
</div>

Дивіться також цю скрипку !


2

Я натрапив на цю нитку в пошуках рішення, яке:

  • використовує 100% ширини заданого зображення
  • зберігає співвідношення сторін зображення
  • зберігає зображення вертикально вирівняним до середини
  • працює в браузерах, які не повністю підтримують flex

Перевіряючи деякі рішення, розміщені вище, я не знайшов такого, щоб відповідати всім цим критеріям, тому я зібрав цей простий, який може бути корисним для інших людей, які повинні зробити те саме:

.container {
  width: 30%;
  float: left;
  border: 1px solid turquoise;
  margin-right: 3px;
  margin-top: 3px;
}

.container:last-of-kind {
  margin-right: 0px;
}

.image-container {
  position: relative;
  overflow: hidden;
  padding-bottom: 70%;
  /* this is the desired aspect ratio */
  width: 100%;
}

.image-container img {
  position: absolute;
  /* the following 3 properties center the image on the vertical axis */
  top: 0;
  bottom: 0;
  margin: auto;
  /* uses image at 100% width (also meaning it's horizontally center) */
  width: 100%;
}
<div class="container">
  <div class="image-container">
    <img src="http://placehold.it/800x800" class="img-responsive">
  </div>
</div>

<div class="container">
  <div class="image-container">
    <img src="http://placehold.it/800x800" class="img-responsive">
  </div>
</div>

<div class="container">
  <div class="image-container">
    <img src="http://placehold.it/800x800" class="img-responsive">
  </div>
</div>

Робочий приклад на JSFiddle


0

Спробуйте

Html

<div class="responsive-container">
     <div class="img-container">
         <IMG HERE>
     </div>
</div>

CSS

.img-container {
    position: absolute;
    top: 0;
    left: 0;
height:0;
padding-bottom:100%;
}
.img-container img {
width:100%;
}

0

html-код

<div class="image-container"> <img src=""/> </div>

код css

img
{
  position: relative;
  top: 50%;
  transform: translateY(-50%);
 }

Хоча цей фрагмент коду вітається і може надати деяку допомогу, він би значно покращився, якби він включив пояснення того, як він вирішує питання. Без цього ваша відповідь має набагато меншу освітянську цінність - пам’ятайте, що ви відповідаєте на запитання читачів у майбутньому, а не лише про людину, яка зараз запитує! Будь ласка, відредагуйте свою відповідь, щоб додати пояснення та вказати, які обмеження та припущення застосовуються.
Toby Speight

0

Створіть ще один div і додайте до нього і "dummy", і "img-container"

Зробіть HTML та CSS, як описано нижче

html , body {height:100%;}
.responsive-container { height:100%; display:table; text-align:center; width:100%;}
.inner-container {display:table-cell; vertical-align:middle;}
<div class="responsive-container">
    <div class="inner-container">
		<div class="dummy">Sample</div>
		<div class="img-container">
			Image tag
		</div>
	</div>	
</div>

Замість 100% для "контейнера, що реагує", ви можете надати потрібну висоту.,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.