이 부분은 매우 지루하고 마법 숫자에 의존하지 않는 일반적인 솔루션을 찾는 데 어려움을 겪고 있습니다. 나는 하나의 의사 요소 만 사용하는 매우 복잡한 솔루션으로 끝났지 만 코드는 혼란스럽고 특정 상황 만 포함합니다. 이 길을 탐색 할 가치가 없다고 생각합니다.
코드를 단순화하기 위해 추가 요소를 삽입하기로 결정했습니다. 다음은 마크입니다 :
나는 외부 CSS와의 잠재적 충돌을 피하기 위해 사용자 정의 요소
를 사용합니다. <code>.box {
position: relative;
}
.box::before {
content: "";
position: absolute;
inset: -5px; /* 控制扩散 */
transform: translate(10px, 8px); /* 控制偏移量 */
z-index: -1; /* 将元素置于后面 */
background: /* 你的渐变色在这里 */;
filter: blur(10px); /* 控制模糊 */
}</code>
를 사용할 수 있지만 일반적인 요소이기 때문에 다른 곳에서 다른 CSS 규칙에 의해 쉽게 배치되기 쉽습니다. 첫 번째 단계는 요소를 찾아 의도적으로 오버플로를 만드는 것입니다.
코드는 조금 이상하게 보일 수 있지만 단계적으로 뒤에있는 논리를 설명 할 것입니다. 다음으로, 우리는 의 의사 요소를 사용하여 그라디언트 그림자를 만듭니다.
보시다시피, 의사 요소는 이전의 모든 예와 동일한 코드를 사용합니다. 유일한 차이점은 3D 변환이 의사 요소가 아닌 요소에 정의된다는 것입니다. 현재 투명성 기능이없는 그라디언트 그림자가 있습니다.
요소의 면적은 검은 색 개요로 정의됩니다. 왜 이렇게합니까? 이 때문에 마스크를 바르고 녹색 영역 내부의 부품을 숨기고 그림자를 볼 필요가있는 곳에 넘쳐나는 부분을 유지할 수 있습니다. <code>box-shadow: 10px 8px 10px 5px orange;</code>
나는 이것이 약간 까다 롭다는 것을 알고 있지만 클립 경로와 달리 마스크 속성은 내용을 보여주고 숨기려면 외부 의 영역을 고려하지 않습니다. 그렇기 때문에 "외부"영역을 시뮬레이션하기 위해 추가 요소를 소개해야했습니다.
또한, 해당 지역을 정의하기 위해 경계와 삽입물의 조합을 사용하고 있습니다. 이를 통해 여분의 요소의 패딩 박스를 기본 요소와 동일하게 유지하여 의사 요소에 추가 계산이 필요하지 않습니다.
추가 요소를 사용하여 얻는 또 다른 유용한 것은 요소가 고정되어 있고 유사 요소 만 움직이고 있다는 것입니다 (번역 사용). 이를 통해 마스크를 쉽게 정의 할 수 있습니다. 이는이 트릭의 마지막 단계입니다. <code>.box {
position: relative;
transform-style: preserve-3d;
}
.box::before {
content: "";
position: absolute;
inset: -5px;
transform: translate3d(10px, 8px, -1px); /* (X, Y, Z) */
background: /* .. */;
filter: blur(10px);
}</code>
완료! 우리는 그라디언트 그림자를 가지고 있으며, 국경 래디 우스를 지원합니다! 내부에 많은 그라디언트가있는 복잡한 마스크 값을 기대할 수 있지만 그렇지 않습니다! 마법을 완성하려면 두 개의 간단한 그라디언트와 마스크 복합이 필요합니다.
거기에서 무슨 일이 일어나고 있는지 이해하기 위해
요소를 분리합시다 :
다음은 우리가 얻은 결과입니다 :
내부 반경이 기본 요소의 경계선과 일치하는 방법에 주목하십시오. 나는 큰 경계 (150px)와 경계 라디우스가 큰 경계 주 요소 반경을 정의했습니다. 외부 적으로는 150px와 같은 반경이 있습니다. 내부적으로 150px r -150px = R이 있습니다.
내부 (파란색) 부분을 숨기고 테두리 (빨간색) 부분이 여전히 보이도록해야합니다. 이를 위해, 나는 두 개의 마스크 레이어를 정의했다-하나는 컨텐츠 박스 영역 만 덮고 다른 하나는 테두리 박스 영역 (기본값)을 덮었다. 그런 다음 다른 하나를 제외하여 국경을 보여줍니다.
<code>.box {
position: relative;
}
.box::before {
content: "";
position: absolute;
inset: -5px; /* 控制扩散 */
transform: translate(10px, 8px); /* 控制偏移量 */
z-index: -1; /* 将元素置于后面 */
background: /* 你的渐变色在这里 */;
filter: blur(10px); /* 控制模糊 */
}</code>
나는 동일한 기술을 사용하여 그라디언트와 경계-라디우스를 지원하는 경계를 만듭니다. Ana Tudor는 또한 마스크 컴파운드에 관한 좋은 기사를 가지고 있으며, 나는 당신이 그것을 읽도록 초대합니다.
이 방법의 단점이 있습니까?
예, 이것은 확실히 완벽하지 않습니다. 당신이 직면 할 수있는 첫 번째 문제는 기본 요소의 경계 사용과 관련이 있습니다. 당신이 그것을 고려하지 않으면, 이것은 반경의 약간의 오정렬로 이어질 수 있습니다. 이 예제에는이 문제가 존재하지만 알아 차리는 데 어려움이있을 수 있습니다.
는 비교적 쉽게 고정되었습니다 :
요소의 삽입물에 테두리 너비를 추가하십시오.
또 다른 단점은 우리가 경계에 사용하는 큰 값입니다 (예에서 150px). 이 값은 그림자를 포함하기에 충분히 크지 만 오버플로 및 스크롤바 문제를 피하기에는 너무 크지 않아야합니다. 다행히 온라인 생성기는 모든 매개 변수를 고려하여 최적 값을 계산합니다.
마지막 단점은 당신이 복잡한 국경-라디우스를 사용할 때입니다. 예를 들어, 각 모서리에 다른 반경을 적용하려면 각 측면의 변수를 정의해야합니다. 이것은 실제 단점이 아니지만 코드를 유지하기가 조금 더 어려워 질 수 있다고 생각합니다.
단순화를 위해 온라인 생성기는 균일 반경 만 고려하지만 이제 복잡한 반경 구성을 고려하려면 코드를 수정하는 방법을 알고 있습니다.
<code>box-shadow: 10px 8px 10px 5px orange;</code>
요약
우리는 끝에 도달했습니다! 그라디언트 그림자 뒤에있는 마법은 더 이상 미스터리가 아닙니다. 나는 당신이 가질 수있는 모든 가능성과 모든 문제를 다루려고 노력하고 있습니다. 내가 뭔가를 놓치거나 문제를 발견했다면, 의견 섹션에서 자유롭게보고 해 주시면 확인하겠습니다.
다시, 사실상의 솔루션이 대부분의 사용 사례를 다루게 될 것이라는 점을 고려하면, 이들 중 다수는 중복 될 수 있습니다. 그러나이 기술의 배후에있는“왜”와“어떻게”를 이해하고 그 한계를 극복하는 방법을 이해하는 것이 좋습니다. 또한 CSS 편집 및 무광택을 재생하는 데 훌륭한 연습을했습니다.
물론 항상 온라인 생성기를 사용하여 문제를 피할 수 있습니다.
<code>.box {
position: relative;
transform-style: preserve-3d;
}
.box::before {
content: "";
position: absolute;
inset: -5px;
transform: translate3d(10px, 8px, -1px); /* (X, Y, Z) */
background: /* .. */;
filter: blur(10px);
}</code>