CSS сцинтилляция с переходом радиус-фон - PullRequest
2 голосов
/ 07 апреля 2020

Я создаю скрипт, который фокусирует HTML элементов. Одна проблема заключалась в том, чтобы сопоставить сфокусированный элемент border-radius, который я решил с помощью радиального градиента (см. Внутренний радиус границы в ячейке таблицы ).

Однако при переходе между двумя элементами на элементе фокуса появляется своего рода белая рамка (между элементом «hello» и его тенью в мой пример [переходы запускаются автоматически]).

const hello = document.getElementById('hello');
var target = 'blue';
var radius = '';
var left = '';
var width = '';
var y = '';

focus();
setInterval(() => focus(), 3000);

function focus() {
	if (target === 'blue') {
  	radius = '5px';
    left = '50px';
    width = '100px';
    y = '50px';
  } else {
  	radius = '25px';
    left = '300px';
    width = '200px';
    y = '100px';
  }
  hello.style.top = y;
  hello.style.left = left;
  hello.style.width = width;
hello.style.background =
           `radial-gradient(farthest-side at bottom left, transparent 98%, #000000bb 100%) top right,
            radial-gradient(farthest-side at bottom right,transparent 98%, #000000bb 100%) top left,
            radial-gradient(farthest-side at top    left, transparent 98%, #000000bb 100%) bottom right,
            radial-gradient(farthest-side at top    right,transparent 98%, #000000bb 100%) bottom left`;
            hello.style.backgroundSize = `${radius} ${radius}`;
                hello.style.backgroundRepeat = 'no-repeat';
                
                target = (target === 'blue') ? 'red' : 'blue';
}
#uno {
  position: absolute;
  width: 100px;
  height: 100px;
  border-radius: 5px;
  background-color: blue;
  left: 50px;
  top: 50px;
}

#dos {
  position: absolute;
  width: 200px;
  height: 100px;
  border-radius: 25px;
  background-color: red;
  left: 300px;
  top: 100px;
}

#hello {
  position: fixed;
  width: 200px;
  height: 100px;
  left: 60px;
  top: 50px;
  box-shadow: 0px 0px 0px 2050px #000000bb;
  
  transition: all 2s ease;
}
<div id="uno"></div>
<div id="dos"></div>
<div id="hello"></div>

Вот стиль для элемента фокусировки "hello":

/* shadow that hides rest of the page */
box-shadow: 0px 0px 0px 2050px #000000bb;
/* having a smooth transition on width, height and background */
transition: all 2s ease;

Сверкающий эффект кажется не появится на Firefox, так что, возможно, это проблема, связанная с хромом.

Если у вас есть только Firefox, вот скриншот скрипты: enter image description here

Есть идеи, откуда может возникнуть проблема?

1 Ответ

1 голос
/ 07 апреля 2020

Это связано с переходом background-size в сочетании с background-position, когда вы используете процентные значения (да, ключевые слова right, bottom, et c эквивалентны процентам). Вы также можете заметить, что это не происходит в верхнем / левом углу, потому что там положение не меняется.

Один из способов избежать этого - рассмотреть значение пикселя для позиционирования фона вместо процентных значений.

Вот пример, где я упросту ваш код, используя CSS переменные и переключаемые классы:

const hello = document.getElementById('hello');

focus();
setInterval(() => focus(), 3000);

function focus() {
  hello.classList.toggle('red');
  hello.classList.toggle('blue');
}
#uno {
  position: absolute;
  width: 100px;
  height: 100px;
  border-radius: 5px;
  background-color: blue;
  left: 50px;
  top: 50px;
}

#dos {
  position: absolute;
  width: 200px;
  height: 100px;
  border-radius: 25px;
  background-color: red;
  left: 300px;
  top: 100px;
}

#hello {
  position: fixed;
  height: 100px;
  box-shadow: 0px 0px 0px 2050px #000000bb;
  background:
     radial-gradient(farthest-side at bottom left, transparent 98%, #000000bb 100%) var(--l) 0,
     radial-gradient(farthest-side at bottom right,transparent 98%, #000000bb 100%) 0 0,
     radial-gradient(farthest-side at top    left, transparent 98%, #000000bb 100%) var(--l) var(--t),
     radial-gradient(farthest-side at top    right,transparent 98%, #000000bb 100%) 0 var(--t);
  background-size:var(--s) var(--s);
  border-radius:var(--s);
  background-repeat:no-repeat;
  transition: all 2s ease;
}

.blue {
  left:50px;
  top:50px;
  width: 100px;
  --s:5px;
  --t:95px; /* height - border-radius */
  --l:95px; /* width  - border-radius */
}
.red {
  left:300px;
  top:100px;
  width: 200px;
  --s:25px;
  --t:75px;  /* height - border-radius */
  --l:175px; /* width  - border-radius */
}
<div id="uno"></div>
<div id="dos"></div>
<div id="hello" class="red"></div>
...