CSS реализует полую маску

CSS

Мне задали этот вопрос некоторое время назад в интервью, и я был внезапно ошеломлен, и мой разум стал пустым. Я знал этот эффект раньше, например,что стоит купитьОбновленная загрузочная страница:

В то время, как бы вы ни нервничали, вы должны придумать метод реализации, то есть что стоит покупать?

Он начинается с добавления полупрозрачной черной маски (background-color: rgba(0,0,0,.8)), а затем добавьте готовое изображение в качестве подэлемента, а затем определите позиционирование так, чтобы позиционирование изображения и закрытой части было одинаковым, чтобы создать искусственный эффект пустоты.

Хотя у этого способа обработки позиционирования есть некоторые проблемы, и он не подходит для ситуации, когда на странице есть прокрутка, при прокрутке может быть несовпадение.

Но я должен был ответить так в то время, но я очень нервничал, как только я брал интервью, и мой разум не мог повернуться, поэтому я хотел добавить псевдоэлемент, но я не знал, как проникнуть.

Я вернулся, проверил некоторую информацию и нашел несколько способов добиться этого.

Сначала подготовьте структуру DOM для маскирования:

<div class="outer">
  <div class="content">
    <p>这是要露出来的字</p>
    <p>这是要露出来的字</p>
    <p>这是要露出来的字</p>
  </div>
  <div class="inner"></div>
</div>

и стиль:

.outer {
  position: relative;
  margin: 20px 0;
  height: 500px;
  background: darksalmon;
  overflow: hidden;
}

.content {
  width: 200px;
  height: 80px;
  color: #FFF;
  line-height: 1.5;
  background: #5b8b7b;
  margin: 100px 0 0 100px;
}

Эффект на данный момент:

Достигаемый эффект:

прозрачная граница

Полая часть в середине является фактическойwidthа такжеheight, для полностью прозрачного фона, а вокруг него используется полупрозрачная маскаrgbaизborderреализовать

.inner {
  position: absolute;
  left: 0;
  top: 0;
  box-sizing: content-box;
  width: 200px;
  height: 80px;
  border-color: rgba(0, 0, 0, 0.5);
  border-style: solid;
  border-width: 100px 1500px 1500px 100px;
  background: transparent;
}

прозрачный контур

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

.inner2 {
  position: absolute;
  left: 100px;
  top: 100px;
  box-sizing: content-box;
  width: 200px;
  height: 80px;
  outline: rgba(0, 0, 0, 0.5) 1500px solid;
  background: transparent;
}

прозрачная тень

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

.inner3 {
  position: absolute;
  left: 100px;
  top: 100px;
  box-sizing: content-box;
  width: 200px;
  height: 80px;
  box-shadow: rgba(0, 0, 0, 0.5) 0 0 0 1500px;
  background: transparent;
}

Реализовано с помощью Canvas

Это может быть реализовано с помощью мощного Canvas.Конечно, использование Cavnas требует написания сценариев.Хотя это немного сложно, оно гибкое в использовании и может адаптироваться к различным требованиям, таким как одновременное выдолбление нескольких.

Есть также два способа использования Canvas, первый способ — использоватьclearRectМетод относительно прост:

const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';

ctx.fillRect(0, 0, 1500, 1500);
ctx.clearRect(100, 100, 200, 80);

Другой способ - пройтиpathНарисуйте такую ​​форму непосредственно, здесь вам нужно ввестиненулевое правило упаковки

Поэтому при рисовании внешнего полупрозрачного прямоугольника по часовой стрелке полый прямоугольник внутри должен быть против часовой стрелки:

const canvas = document.querySelector('#canvas2');
const ctx = canvas.getContext('2d');

// 外围
ctx.moveTo(0, 0);
ctx.lineTo(1500, 0);
ctx.lineTo(1500, 1500);
ctx.lineTo(0, 1500);
ctx.closePath();

// 内层
ctx.moveTo(300, 100);
ctx.lineTo(100, 100);
ctx.lineTo(100, 180);
ctx.lineTo(300, 180);
ctx.closePath();

ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
ctx.fill();

Реализовано с использованием SVG

Я в основном мало знаю о SVG, поэтому я скопировал и изменил кусок кода напрямую

<svg class="svg" width="1500" height="500">
  <defs>
    <mask id="myMask">
      <rect x="0" y="0" width="100%" height="100%" style="stroke:none; fill: #ccc"></rect>
      <rect width="200" height="80" x="100" y="100" style="fill: #000"></rect>
    </mask>
  </defs>
  <rect x="0" y="0" width="100%" height="100%" style="stroke: none; fill: rgba(0, 0, 0, 0.6); mask: url(#myMask)"></rect>
</svg>

Это тоже не очень сложно.

Суммировать

  • Если размер макета страницы фиксирован, вы можете использовать три метода CSS для достижения
  • Если эффект более сложный, вы можете использовать Canvas или SVG для достижения
  • Если вы хотите быть ленивым, вы можете позволить пользовательскому интерфейсу создавать изображение для достижения

Ссылаться на