Расширение абсолютного деления от центра, чтобы показать ребенка - PullRequest
3 голосов
/ 30 октября 2019

Я хочу иметь (n абсолютно позиционированную) прямоугольную маску, которая расширяется при наведении курсора на раскрытие дочерних элементов (переменной высоты). Прямо сейчас я достигаю этого с помощью абсолютно позиционированного div, который меняет значения left , width и max-height . Тем не менее, я хотел бы, чтобы это выглядело так, будто оно расширяется из середины, а не раскрывается сверху слева - и все одновременно.

<div id="container">
 <div id="mask">
  <div id="background"></div>
 </div>
</div>

    #container {
     width: 300px;
     height: 300px;
     background-color: black;
    }

    #mask {
     width: 50px;
     max-height: 50px;
     position: absolute;
     top: 125px;
     left: 125px;
     overflow: hidden;

     transition: width 1s, max-height 1s, left 1s, top 1s;
    }

    #background {
     background-image: url(https://www.pngfind.com/pngs/m/299-2991041_memes-para-stickers-png-png-download-surprised-pikachu.png);
     background-size: contain;
     width: 150px;
     height: 125px;
    }

    #mask:hover {
     width: 150px;
     max-height: 1000px;
     left: 75px;
     top: 75px;
    }

Вот кодекс: https://codepen.io/jraynolds/pen/OJJxpOm

Ответы [ 2 ]

2 голосов
/ 30 октября 2019

# 1 - Использование clip-path

Совместимость: Все современные браузеры, кроме Edge. IE10 / 11 и Edge предоставляют ограниченные возможностиподдержка только url().

Пример с клип-траекторией

Чтобы обрезать изображение, используйте clip-path: inset(). В этом примере у нас есть 120-пиксельное поле, которое при наведении уменьшается до 0.

.reveal {
  background: url(https://i.stack.imgur.com/3v1Kz.jpg) no-repeat;
  background-size: 150px;
  background-position: center;
  height: 300px;
  width: 300px;
  clip-path: inset(120px 120px 120px 120px);
  transition: clip-path 0.5s;
}

.reveal:hover {
  clip-path: inset(0 0 0 0);
}

/*for example*/
body {
  background: linear-gradient(to bottom right, black 0%, white 100%);
  height: 100vh;
}
<div class="reveal"></div>

Пример с url () (не работает в Edge или IE)

Была попытка!

СоздатьSVG примерно так:

<svg>
    <clipPath id="square">
         <rect />
    </clipPath>
</svg>

и поместите это в контейнер. Div задается clip-path: url(#square), а координаты ширины, высоты, x и y предоставляются в CSS и изменяются при наведении курсора.

.reveal-url {
  background: url(https://www.pngfind.com/pngs/m/299-2991041_memes-para-stickers-png-png-download-surprised-pikachu.png)
    no-repeat;
  background-size: 150px;
  background-position: center;
  height: 300px;
  width: 300px;
  clip-path: url(#square);
  position: relative;
}

svg {
  width: 100%;
  height: 100%;
}

.reveal-url rect {
  transition: all 0.5s;
  x: 120px;
  y: 120px;
  width: 60px;
  height: 60px;
}


.reveal-url:hover rect {
  width: 100%; 
  height: 100%;
  x: 0;
  y: 0;
}

/*for example*/
body {
  background: linear-gradient(to bottom right, black 0%, white 100%);
  height: 100vh;
}

h1 {
  font-size: 30px;
  color: white;
}
<h1>This only works in Chrome and Firefox.</h1>

<div class="reveal-url">
  <svg>
      <clipPath id="square">
			  <rect />
      </clipPath>
  </svg>
</div>

# 2 - Использование Box-shadow

Если вы работаете со сплошными фоновыми цветами, простой способ - использовать вставку box-shadowчтобы замаскировать содержимое контейнера, а затем уменьшить тень при наведении курсора.

.reveal {
  background: #000 url(https://www.pngfind.com/pngs/m/299-2991041_memes-para-stickers-png-png-download-surprised-pikachu.png) no-repeat;
  background-size: 150px;
  background-position: center;
  height: 300px;
  width: 300px;
  box-shadow: inset 0 0 0 120px #000;
  transition: box-shadow 1s;
}

.reveal:hover {
  box-shadow: inset 0 0 0 70px #000;
}


/*for example*/

body {
  background: #000;
}
<div class="reveal"></div>
2 голосов
/ 30 октября 2019

Это решение работает, однако оно использует элемент маски как дочерний элемент фона, а не наоборот.

<div id="container">
  <div id="background">
    <div id="mask"></div>
  </div>
</div>

Вы просто задаете маску 100% границы и нулевые измерения и переходдо нулевой границы и 100% размерности (прозрачный). Маска должна иметь повышенный Z-Indez. Вот так:

#container 
{
  width: 300px;
  height: 300px;
  background-color: black;
  position: relative;
}
#mask
{
  position: absolute;
  left: 0;
  top: 0;
  z-indez: 10;
  height: 0;
  width: 0;
  transition: 0.4s ease;
  border: 150px solid black;
}
#background 
{
  background-image: url(https://www.pngfind.com/pngs/m/299-2991041_memes-para-stickers-png-png-download-surprised-pikachu.png);
  background-size: contain;
  width: 300px;
  height: 300px;
  display: block;
  margin: 1rem auto;
}
#background:hover #mask
{
  border: 0 solid black;
  width: 100%;
  height: 100%;
}

Вот ручка: https://codepen.io/jaycodist/full/MWWEpMx

...