Невелике зображення в центрі Div


175

Я намагався розібратися, як централізувати негабаритний образ у div лише за допомогою css.

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

Саме зображення було розміщене для заповнення навколишнього діва за найширшим можливим значенням (дизайн має max-widthзначення).

Це зробити досить просто, якщо зображення менше, ніж навколишній div:

margin-left: auto;
margin-right: auto;
display: block; 

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

Ми можемо призначити width=100%, але веб-переглядачі виконують велику роботу щодо зміни розмірів зображень та веб-дизайну навколо високоякісних зображень.

Будь-які ідеї щодо центрування зображення, щоб overflow:hiddenрівномірно відрізати обидва краї?


2
Ви коли-небудь вирішували цю проблему @Tom? На даний момент я стикаюся з тим же питанням. :)
— ctrlplusb

Я припускаю, що ширина вашого зображення змінюється.
— іншеДеві

Відповіді:


365

Спробуйте щось подібне. Це повинно зосереджувати будь-який величезний елемент посередині вертикально та горизонтально щодо його материнської точки зору, незалежно від їх розмірів.

.parent {
    position: relative;
    overflow: hidden;
    //optionally set height and width, it will depend on the rest of the styling used
}

.child {
    position: absolute;
    top: -9999px;
    bottom: -9999px;
    left: -9999px;
    right: -9999px;
    margin: auto;

}

4
чудово: це працює з будь-яким елементом. навіть з html 5 відео ... спасибі!
— taseenb

3
Як я розумію це: він працює, тому що створює елемент (сподіваємось) більший за зображення (2 * 9999px x 2 * 9999px) і центрує зображення всередині цього елемента (поле: авто). Тому поки зображення не перевищує 2 * 9999px, воно повинно працювати.
— Майкл Крупп

16
Чому б не використовувати -100%верхній / правий / нижній / лівий? При цьому контейнер може мати буквально будь-яку ширину.
— Саймон,

15
Так, я також відчував цю -100%проблему ^^. Btw: якщо ви додаєте min-widthі min-heightз 100%вас в основному отримати background-size: cover;поведінку з тегами зображення -> jsfiddle
— Simon

3
@HarrisonPowers Добре, що батько повинен мати висоту курсу, будь то фіксований чи динамічний. Він також спрацює, якщо якийсь інший вміст заповнює div, що спричиняє його висоту (наприклад, текст).
— hyounis

162

Це давнє питання Q, але сучасне рішення без флексбоксу або абсолютного положення працює так.

margin-left: 50%;
transform: translateX(-50%);

То чому це працює?
На перший погляд здається, що ми переміщуємо 50% вправо, а потім знову 50% вліво. Це призвело б до зміни нуля, і що?
Але 50% не однакові, тому що важливий контекст. Якщо ви використовуєте відносні одиниці, запас буде обчислюватися як відсоток від ширини батьківського елемента, тоді як перетворення буде 50% відносно того ж елемента.

У нас така ситуація, перш ніж додати CSS

       +-------------------------------------------+
       | Parent element P of E                     |
       |                                           |
       +-----------------------------------------------------------+
       | Element E                                                 |
       +-----------------------------------------------------------+
       |                                           |
       +-------------------------------------------+

З доданим стилем, який margin-left: 50%ми маємо

       +-------------------------------------------+
       | Parent element P of E                     |
       |                                           |
       |                     +-----------------------------------------------------------+
       |                     | Element E                                                 |
       |                     +-----------------------------------------------------------+
       |                     |                     |
       +---------------------|---------------------+
       |========= a ========>|

       a is 50% width of P

І transform: translateX(-50%)зрушення назад вліво

       +-------------------------------------------+
       | Parent element P of E                     |
       |                                           |
+-----------------------------------------------------------+
| Element E                 |                               |
+-----------------------------------------------------------+
|<============ b ===========|                      |
       |                    |                      |
       +--------------------|----------------------+
       |========= a =======>|

       a is 50% width of P
       b is 50% width of E

На жаль, це працює лише для горизонтального центрування, оскільки розрахунок відсоткового запасу завжди відносно ширини. Тобто не тільки margin-leftі margin-right, але margin-topі margin-bottomтакож обчислюються по ширині.

Сумісність браузера не повинна бути проблемою: https://caniuse.com/#feat=transforms2d


Він не працює для вертикального вирівнювання (коли .inner має більшу висоту, ніж.)
— cronfy

1
@cronfy No. вертикально це не спрацює, бо margin-top: 50%буде 50% ширини . не висота за бажанням.
— юнзен

2
Це, безумовно, найелегантніше рішення
— Сухаїб Бесбес

деякий час шукати рішення, найкраще, найпростіше; Ура
— lauWM

2
Це чиста магія чарівника. Дякую! Відмінно працює в Safari та Chrome (з -webkit-transform: translateX(-50%);хорошою мірою)
— Нік Шнебл

22

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

Це центрує його горизонтально:

HTML:

<div class="imageContainer">
  <div class="imageCenterer">
    <img src="http://placekitten.com/200/200" />
  </div>
</div>

CSS:

.imageContainer {
  width: 100px;
  height: 100px;
  overflow: hidden;
  position: relative;
}
.imageCenterer {
  width: 1000px;
  position: absolute;
  left: 50%;
  top: 0;
  margin-left: -500px;
}
.imageCenterer img {
  display: block;
  margin: 0 auto;
}

Демонстрація: http://jsfiddle.net/Guffa/L9BnL/

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


Це закінчилося, щоб лівий край зображення був по центру в "imageContainer". Як я коментував вище, наш контейнер із зображеннями контейнера для зображень має ширину рідини та фіксовану висоту.
— Том

1
@Tom: Якщо я видаляю widthналаштування на контейнері, він буде шириною батьківського, і зображення буде по центру, навіть якщо сторінка вужча, ніж зображення, тобто стільки лівого краю, скільки правий край буде приховано : jsfiddle.net/Guffa/L9BnL/2
— Guffa

Дякую за натхнення Я використовую позицію: відносно для .imageCenter. Таким чином, мені не потрібна позиція: відносна для батьківського контейнера.
— user3153298

У цьому питанні є багато хитромудрих хитрощів, і всі вони мають свої недоліки. Деякі працюють «краще», але їх зовсім не легко зрозуміти. Це рішення має ідеальний сенс, зображення зазвичай зосереджується в більш широкому розділі, який обрізається. Він почуває себе неправильно, але, безумовно, працює, не порушуючи законів веб-фізики. Я вибрав цей варіант через кілька інших дуже важких для розуміння хитрощів, навіть якщо він відчуває себе трохи брудним.
— Radley Sustaire

9

Пізно до гри, але я знайшов цей метод надзвичайно інтуїтивним. https://codepen.io/adamchenwei/pen/BRNxJr

CSS

.imageContainer {
  border: 1px black solid;

  width: 450px;
  height: 200px;
  overflow: hidden;
}
.imageHolder {
  border: 1px red dotted;

  height: 100%;
  display:flex;
  align-items: center;
}
.imageItself {
  height: auto;
  width: 100%;
  align-self: center;

}

HTML

<div class="imageContainer">
  <div class="imageHolder">
    <img class="imageItself" src="http://www.fiorieconfetti.com/sites/default/files/styles/product_thumbnail__300x360_/public/fiore_viola%20-%202.jpg" />
  </div>
</div>

3
Приємно! Це також можна спростити. Трюк виконується display: flexна батьківському контейнері та align-self: centerна зображенні. Ось оптимізована версія: codepen.io/anon/pen/dWKyey
— caiosm1005

5

Не використовуйте фіксовану або явну ширину чи висоту для тегу зображення. Замість цього кодуйте його:

      max-width:100%;
      max-height:100%;

напр .: http://jsfiddle.net/xwrvxser/1/


1
Потім це залишає простір навколо зображення, якого, я вважаю, вони намагаються уникати.
— Eoin

3

Я величезний шанувальник створення зображення фоном діва / вузла - тоді ви можете просто використовувати background-position: centerатрибут, щоб відцентрувати його незалежно від розміру екрана


9
Це не доступний спосіб використання зображень. Це може спрацювати для декоративних зображень, але будь-яке інформаційне зображення потребує введення тексту.
— користувач2532030

0

Ширина та висота є лише для прикладу:

parentDiv{
    width: 100px;
    height: 100px;
    position:relative; 
}
innerDiv{
    width: 200px;
    height: 200px;
    position:absolute; 
    margin: auto;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
}

Це повинно працювати для вас, якщо ліворуч і верхній частині вашої батьківської діви не у верхній і лівій частині вікна вашого екрана. Це працює для мене.


Здавалося, нічого не змінило. Не впевнений, чи це пов’язано з тим, що ширина є текучою, тоді як висота визначається тим, що було б батьківським ділом.
— Том

2
Ця методика працює, якщо зображення менше, ніж контейнер.
— іншеДеві

0

Я вважав це більш елегантним рішенням, без гнучкості:

.wrapper {
    overflow: hidden;
}
.wrapper img {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* height: 100%; */ /* optional */
}

0

Спираючись на чудову відповідь @ yunzen:

Я здогадуюсь, що багато людей, які шукають цю тему, намагаються використовувати велике зображення як фонове зображення "героя", наприклад на домашній сторінці. У такому випадку вони часто хочуть, щоб текст відображався над зображенням і щоб він міг зменшуватися на мобільних пристроях.

Ось ідеальний CSS для такого фонового зображення (використовуйте його на <img>тезі):

/* Set left edge of inner element to 50% of the parent element */
margin-left: 50%;

/* Move to the left by 50% of own width */
transform: translateX(-50%);

/* Scale image...(101% - instead of 100% - avoids possible 1px white border on left of image due to rounding error */
width: 101%;

/* ...but don't scale it too small on mobile devices - adjust this as needed */
min-width: 1086px;

/* allow content below image to appear on top of image */
position: absolute;
z-index: -1;

/* OPTIONAL - try with/without based on your needs */
top: 0;

/* OPTIONAL - use if your outer element containing the img has "text-align: center" */
left: 0;

-1

Один з варіантів, який ви можете використати - object-fit: coverце поводиться трохи схоже background-size: cover. Детальніше про об'єкт-придатність .

ігноруйте всі JS нижче, це лише для демонстрації.

Ключовим тут є те, що вам потрібно встановити зображення всередині обгортки і надати йому такі властивості.

.wrapper img {
  height: 100%;
  width: 100%;
  object-fit: cover;
}

Я створив демонстрацію нижче, де ви змінюєте висоту / ширину обгортки і бачите в грі. Зображення завжди буде по центру вертикально та горизонтально. Це займе 100% від його батьківської ширини та висоти, і не буде розтягуватися / стискатися. Це означає, що співвідношення сторін зображення зберігається. Зміни застосовуються шляхом збільшення / зменшення масштабу.

Єдиним недоліком object-fitє те, що він не працює на IE11.

// for demo only
const wrapper = document.querySelector('.wrapper');
const button = document.querySelector('button');
const widthInput = document.querySelector('.width-input');
const heightInput = document.querySelector('.height-input');


const resizeWrapper = () => {
  wrapper.style.width = widthInput.value + "px";
  wrapper.style.height = heightInput.value + "px";
}

button.addEventListener("click", resizeWrapper);
.wrapper {
  overflow: hidden;
  max-width: 100%;
  margin-bottom: 2em;
  border: 1px solid red;
}

.wrapper img {
  display: block;
  height: 100%;
  width: 100%;
  object-fit: cover;
}
<div class="wrapper">
  <img src="https://i.imgur.com/DrzMS8i.png">
</div>


<!-- demo only -->
<lable for="width">
  Width: <input name="width" class='width-input'>
</lable>
<lable for="height">
  height: <input name="height" class='height-input'>
</lable>
<button>change size!</button>

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