Добавить функцию наведения на изображение продукта

Я пытаюсь добавить функцию отображения альтернативного изображения продукта при наведении курсора на изображение продукта в представлении коллекции.

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

Что я могу исправить, чтобы изображения оставались в исходном положении и работал только эффект наведения?

Спасибо!

Вот что у меня сейчас есть в product-card-grid.liquid -

<div id="{{ wrapper_id }}" class="grid-view-item__image-wrapper js">
    <div style="padding-top:{% unless product.featured_image == blank %}{{ 1 | divided_by: product.featured_image.aspect_ratio | times: 100}}%{% else %}100%{% endunless %};">
     <div class="reveal">
      <img id="{{ img_id }}"
            class="grid-view-item__image lazyload"
            src="{{ product.featured_image | img_url: '300x300' }}"
            data-src="{{ img_url }}"
            data-widths="[180, 360, 540, 720, 900, 1080, 1296, 1512, 1728, 2048]"
            data-aspectratio="{{ product.featured_image.aspect_ratio }}"
            data-sizes="auto"
            alt="">
      <img id="{{img_id}}"
           class="hidden" 
           src="{{ product.images.last }}"
           data-src="{{ img_url }} "
           data-widths="[180, 360, 540, 720, 900, 1080, 1296, 1512, 1728, 2048]"
           data-aspectratio="{{ product.featured_image.aspect_ratio }}"
           data-sizes="auto"
           alt="{{ product.images.last.alt | escape }}">
      </div>
    </div>
  </div>

CSS для "Reveal" приведен ниже:

  /* ===============================================
// Reveal module
// =============================================== */

.reveal .hidden { display: block !important; visibility: visible !important;}
.product:hover .reveal img { opacity: 1; }
.reveal { position: relative; }
.reveal .hidden { 
  position: absolute; 
  z-index: -1;
  top: 0; 
  width: 100%; 
  height: 100%;  
  opacity: 0;
  -webkit-transition: opacity 0.3s ease-in-out;
  -moz-transition: opacity 0.3s ease-in-out;
  -o-transition: opacity 0.3s ease-in-out;
  transition: opacity 0.3s ease-in-out;  
}
.reveal:hover .hidden { 
  z-index: 100000;
  opacity: 1;    
}
.reveal .caption {
  position: absolute;
  top: 0;  
  display: table;
  width: 100%;
  height: 100%;
  background-color: white; /* fallback for IE8 */
  background-color: rgba(255, 255, 255, 0.7);
  font: 13px/1.6 sans-serif;
  text-transform: uppercase;
  color: #333;
  letter-spacing: 1px;
  text-align: center;
  text-rendering: optimizeLegibility;
}
.reveal .hidden .caption .centered {
  display: table-cell;
  vertical-align: middle;
}

@media (min-width: 480px) and (max-width: 979px) {
  .reveal .caption { 
    font-size: 11px; 
  }
}

person Hayden    schedule 22.06.2018    source источник
comment
Вы уверены, что проблема не в width: 100%; height: 100%;, указанном для .reveal .hidden? Просто прочитав это, вы, кажется, растянете открывающееся изображение.   -  person PIIANTOM    schedule 23.06.2018


Ответы (2)


В вашем CSS много чего происходит, но если я правильно понимаю ситуацию, вы хотите добиться эффекта, подобного тому, который показан в этот Codepen, верно?

В вашем CSS абсолютно разместите два изображения внутри div (с top: 0px и left: 0px) и измените непрозрачность верхнего изображения в стеке, наведя курсор на родителя.

HTML:

<div class='reveal'>
  <img src='image_src' class='bottom'>
  <img src='image_src' class='top'>
</div>

CSS:

.top, .bottom {
  position: absolute;
  opacity: 1;
  top: 0px;
  left: 0px;
}

.frame:hover .top {
  opacity: 0;
}

РЕДАКТИРОВАТЬ: Реализация с сеткой, как и требовалось.

HTML:

<div class='grid'>
    <div class='reveal'>
      <img src='image_src' class='bottom'>
      <img src='image_src' class='top'>
    </div>
    <div class='reveal'>
      <img src='image_src' class='bottom'>
      <img src='image_src' class='top'>
    </div>
</div>

CSS:

.grid {
  display: flex;
  flex-wrap: wrap; /*makes the grid "responsive"*/
}

.reveal {
  display: flex;
  flex: 1 1 200px; /*last value must be picture width*/
  height:200px; /* picture height*/
  margin: 20px; /*aesthetic only*/
  position: relative;
}

.top, .bottom {
  position: absolute;
  opacity: 1;
  top: 0px;
  left: 50%; /*centers pictures inside flex children (.reveal divs)*/
  transform: translate(-50%, 0); /*see above*/
}

.reveal:hover .top {
  opacity: 0;
}

Демонстрация на Codepen

В приведенном выше примере используется flexbox для создания простой сетки, которая будет работать с (слегка измененными) .reveal div из моего исходного сообщения. Если вы не знакомы с синтаксисом flexbox, я настоятельно рекомендую отличный бесплатный видеокурс от Уэса Боса.

P.S. Обратите внимание, что сетка будет работать «из коробки» только в том случае, если изображения имеют заданную ширину в пикселях, хотя вы можете легко поддерживать изображения разных размеров с помощью небольшой магии медиа-запросов.

person A. Lamansky    schedule 23.06.2018
comment
Это близко к тому, что мне нужно, но из-за этого сетка портится. - person Hayden; 24.06.2018
comment
Я обновил свой пост, включив в него пример того, как эту технику можно использовать в контексте сетки. Однако он сильно зависит от flexbox, поэтому убедитесь, что вы знакомы с синтаксисом, если планируете его использовать. :) - person A. Lamansky; 24.06.2018
comment
Это прекрасно! Большое спасибо! - person Hayden; 25.06.2018

Получил, чтобы работать со следующими

В CSS у меня был @media (hover: hover) {}, чтобы пользователям не приходилось дважды щелкать изображение на мобильном устройстве, чтобы перейти на страницу продукта.

CSS:

/* ===============================================
// Reveal module
// =============================================== */
@media (hover:hover) {
.has-secondary.grid-view-item__link img.secondary{
 display:none;
}
}

@media (hover:hover) {
.has-secondary.grid-view-item__link:hover img.secondary{
 display:block;
}
}

@media (hover:hover) {
.has-secondary.grid-view-item__link:hover img.grid-view-item__image{
 display:none;
}
}

@media screen and (min-width:767px){
.has-secondary.grid-view-item__link img.secondary{
 display:none;
}

.has-secondary.grid-view-item__link:hover img.secondary{
 display:block;
}

.has-secondary.grid-view-item__link:hover img.grid-view-item__image{
 display:none;
}
}

@media screen and (max-width:767px){
.has-secondary.grid-view-item__link img.secondary{
 display:none;
}
}

Изменен HTML / Liquid product-card-grid.liquid на следующее:

{% unless grid_image_width %}
  {%- assign grid_image_width = '600x600' -%}
{% endunless %}
<div class="grid-view-item{% unless product.available %} product-price--sold-out grid-view-item--sold-out{% endunless %}">
  <a class="grid-view-item__link {% if product.images.size > 1 %} has-secondary{% endif %}" href="{{ product.url | within: collection }}">
    <img class="grid-view-item__image" src="{{ product.featured_image.src | img_url: grid_image_width }}" alt="{{ product.featured_image.alt }}">
    {% if product.images.size > 1 %}
     <img class="secondary" src="{{ product.images.last | img_url: grid_image_width }}" alt="{{ product.images.last.alt | escape }}">
    {% endif %}
  </a>
</div>

<div class="h4 grid-view-item__title">
     <a href="{{ product.url | within: collection }}"> {{ product.title }} </a>
</div>   
{% if section.settings.show_vendor %}
      <div class="grid-view-item__vendor">{{ product.vendor }}</div>
    {% endif %}
 <div class="grid-view-item__meta">
   <a href="{{ product.url | within: collection }}"> {% include 'product-price', variant: product %} </a>
    </div> 
person Hayden    schedule 23.06.2018