Принудительное соотношение сторон изображения также на мобильных устройствах с помощью CSS (подгонка объекта: обложка не работает)

#css

#css — код

Вопрос:

Фон:

У меня есть изображение эскиза круга (.x-card-img), которое также обрезает прямоугольные изображения на рабочем столе.

Проблема:

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

Попытки:

Широко распространенным решением является установка object-fit: cover и либо установка height: auto, либо поиграйте с width / height и max-width / max-height. Я чувствую, что перепробовал все, но, кажется, ничего не помогает.

  1. ОБНОВЛЕНИЕ 1 В соответствии с приведенным ниже ответом я добавил следующее, чтобы заменить радиус границы:

    контур клипа: круг (50% на 50% 50%);

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

    введите описание изображения здесь

  2. ОБНОВЛЕНИЕ 2

    Второе (и принятое) решение, приведенное ниже, работает!! Большое спасибо


Для рабочего стола

введите описание изображения здесь

Мобильный

введите описание изображения здесь

Исходное изображение 1

введите описание изображения здесь

Исходное изображение 2

введите описание изображения здесь

 .x-card-box {
    border: 0;
    border-radius: 9px;
    background-color: white;
    box-shadow: rgba(0,0,0,0.2) 0px 0px 15px;
    border: 2px solid white;
    padding: 1.5625rem !important;
    transition-duration: 0.2s;
    transition-timing-function: ease-in-out;
    transition-delay: initial;
    transition-property: initial;
    max-width: 275px !important;
}    
.x-card-name {
    font-size: 20px;
    color: #646464;
    padding-top: 30px;

}

.x-card-img {
    border-radius: 50%;
    border: 1px solid #b1b1b1;
    width: 100%;
    height: auto;
    max-width: 125px !important;
    max-height: 125px !important;
    margin-top: 15px;
    object-fit: cover;
} 
 <div class="container x-card-box">
  <div class="row">

    <div class="x-card-featured col-12 d-flex justify-content-center">
  
</div>
  <div class="x-card-name col-12 d-flex justify-content-center">
     
<span class="job_listing-title">Betti</span>
                            
  </div>

  <div class="x-card-photo col-12 d-flex justify-content-center">
        
                    
<img class="x-card-img" src="https://i.stack.imgur.com/aEW8l.png" alt="Betti">
                    
            
                
            </div>
  <div class="x-card-rating col-12 d-flex justify-content-center">
        
            
<div class="listing-stars">
                        
<span class="listing-star listing-star--empty"></span>
<span class="listing-star listing-star--empty"></span>
<span class="listing-star listing-star--empty"></span>      
<span class="listing-star listing-star--empty"></span>
<span class="listing-star listing-star--empty"></span>
                        
                    
                </div>
            
   </div>
  <div class="x-card-more col-12 d-flex justify-content-center">
    <button class="x-card-btn">amp;nbsp;</button></div>
  </div>
</div>


<!-- ************* NEXT CARD **************** -->


<div class="container x-card-box">
  <div class="row">

    <div class="x-card-featured col-12 d-flex justify-content-center">
  
</div>

<div class="x-card-name col-12 d-flex justify-content-center">
     
<span class="job_listing-title">Betti</span>
                            
  </div>

  <div class="x-card-photo col-12 d-flex justify-content-center">
        
                    
<img class="x-card-img" src="https://i.stack.imgur.com/Y667l.jpg" alt="Betti">
                    
            
                
            </div>
  <div class="x-card-rating col-12 d-flex justify-content-center">
        
            
<div class="listing-stars">
                    
<span class="listing-star listing-star--empty"></span>
<span class="listing-star listing-star--empty"></span>
<span class="listing-star listing-star--empty"></span>      
<span class="listing-star listing-star--empty"></span>
<span class="listing-star listing-star--empty"></span>
                    
                </div>
            
   </div>
  <div class="x-card-more col-12 d-flex justify-content-center">
    <button class="x-card-btn">amp;nbsp;</button></div>
  </div>
</div> 

Ответ №1:

Есть трюк CSS, который вы можете использовать для создания элемента, который сохраняет любые пропорции после изменения размера. Хитрость заключается в том, что процентное значение заполнения всегда зависит от ширины родительского элемента (даже от заполнения -сверху / снизу).

Вот как это работает:

  1. Создайте родительский контейнер ( .x-card-photo в вашем случае) и присвоите ему position: relative; желаемую ширину ( max-width: 125px; ).
  2. Добавьте псевдоэлемент для этого контейнера ( .x-card-photo::after ) и установите его ‘ padding-bottom: 100%; . Таким образом, заполнение снизу будет подстраиваться под изменения его родительского элемента (задается max-width: 125px; ). Всякий раз, когда родительский width элемент сжимается, padding-bottom он тоже сжимается!
  3. Положите внутрь все, что вам нравится .x-card-photo , подайте это position: absolute; width: 100%; height: 100%; так, чтобы оно заполнило все доступное пространство.

И ваш код:

 .x-card-box {
  border: 0;
  border-radius: 9px;
  background-color: white;
  box-shadow: rgba(0,0,0,0.2) 0px 0px 15px;
  border: 2px solid white;
  padding: 1.5625rem !important;
  transition-duration: 0.2s;
  transition-timing-function: ease-in-out;
  transition-delay: initial;
  transition-property: initial;
  max-width: 275px !important;
}
 
.x-card-photo {
  position: relative;
  max-width: 125px;
  margin: 15px 0;
}

.x-card-photo::after {
  content: "";
  display: block;
  padding-bottom: 100%;  /* Edge Fix */
  padding-bottom: min(125px, 100%);
}

.x-card-img {
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 1px solid #b1b1b1;
  object-position: center;
  object-fit: cover;
}
 

РЕДАКТИРОВАТЬ: дальнейшее объяснение:

Родительский CSS указывает только свой собственный width , но не height тот, который по умолчанию равен 0. Псевдоэлемент, который находится внутри родительского элемента, не имеет width , но он косвенно указывает свой собственный height с помощью padding-bottom: 100% — который равен родительскому width из-за внутренней работы CSS (как ни странно, если вы укажете padding в процентах, оно будет относительно родительского width ). Таким образом, родительский height элемент теперь растягивается, чтобы вместить пространство для его псевдоэлементов padding-bottom . Затем, если вы поместите что-либо внутри родительского элемента, скажем, an <img> , и укажите его собственное height: 100% , и width: 100% оно заполнит все доступное пространство. Примечание: псевдоэлемент имеет position: absolute , который помещает его «поверх» родительского элемента (который имеет position: relative ).

Также обратите внимание: padding-bottom: 100% в псевдоэлементе сохраняется соотношение сторон 1: 1, но вы можете рассчитать другие соотношения, например, 50% равно 2: 1, 150% равно 1: 2, 56.25% равно 16: 9 и т.д.

Комментарии:

1. @AlphaX Конечно, я обновил свой ответ и дайте мне знать, если он работает!

2. @AlphaX Эффект, который вы описали выше и в ОБНОВЛЕНИИ 2 , может быть вызван отсутствием поддержки object-fit свойства. Какой мобильный браузер вы используете (поставщик и версия)?

3. @AlphaX Добро пожаловать! Я также добавил еще немного информации в нижней части моего ответа.

4. @AlphaX Похоже, что Edge не понимает min() функцию в padding-bottom .x-card-photo::after определении within. Я отредактировал свой ответ выше, где я удвоил padding-bottom определение, чтобы исправить макет в Edge. Ищите /* Edge Fix */ строку 🙂

5. Да, это была проблема, отлично — большое спасибо! Следующей проблемой снова было пустое пространство, которое создается путем установки padding-bottom на 100%, однако, подумав об этом дальше, это заполнение снизу определяется шириной, т. Е. Просто установите максимальную ширину в 125 пикселей, и теперь она работает хорошо. Еще раз большое спасибо — действительно ценю это!!