찾다
웹 프론트엔드HTML 튜토리얼CSS秘密花园:折角效果_html/css_WEB-ITnose

《 CSS Secrets 》是 @Lea Verou 最新著作,这本书讲解了有关于CSS中一些小秘密。是一本CSSer值得一读的一本书,经过一段时间的阅读,我、@南北和@彦子一起将在W3cplus发布一系列相关的读后感,与大家一起分享。

问题

为元素的一个角落添加样式,让它看起来像是折起来的(通常是右上角或是左下角),有不同程度的逼真效果,是这几年来一个非常受欢迎的效果。

近来,有几个纯CSS的解决方案,第一个是在2010年的时候由伪元素大师—— Nicolas Gallagher 发布的。它们通常是通过添加两个三角形在左上角:一个用于翻页,一个用于模糊主元素的角。这些三角形通常是通过旧的 border 技巧来创建的。

图注:几个早期的 csstricks.com 上的折角效果的设计,在每篇文章的右上角都可以看到

这些解决方案在当时是令人印象深刻的,现在它们却在下面这几种情况下有非常多的限制以及不足:

  • 当我们的元素的背景不是纯色,而是一个图案、纹理、照片、渐变,或其它任何这样的背景图像
  • 当我们想要一个不同于 45° 的角,或是一个旋转折叠

有没有一种方法可以用CSS直接创建一个更灵活的折叠角效果,而且在这些情况下也不会失效的?

针对45°角的解决方案

我们从一个右上角带有斜角的元素开始,在 第三章第四小节中提到的基于渐变的解决方案 上创建。为了用这种技术创建一个 1em 的右上斜切角,代码如下:

background: #58a; /* Fallback */background:linear-gradient(-135deg, transparent 2em, #58a 0);

效果如下:

图注:我们的起点:一个右上角带有斜切角的元素,通过一个渐变完成

在这时候,我们已经完成了一半的工作:我们需要做的是添加一个暗色的三角形用于翻页效果。我们需要通过添加另一个渐变来创建三角形,因此我们将根据需求重新调整 background-size 的值和右上角的 position 。

要创建三角形,我们需要做一个倾斜的线性渐变:

background:linear-gradient(to left bottom,transparent 50%, rgba(0,0,0,.4) 0) no-repeat 100% 0 / 2em 2em;

图注:我们为了折叠三角形的完成的第二个渐变,此处的文本显示的是淡淡的灰色而不是白色,这样你就能大概看到文本所处的位置

你可以在上图中看到只有这个渐变背景的效果。最后一步是把它们结合起来,这个我们会做,对吧?我们来试试,确保三角形翻页是在我们的缺角渐变上的:

background: #58a; /* Fallback */background:    linear-gradient(to left bottom,transparent 50%, rgba(0,0,0,.4) 0) no-repeat 100% 0 / 2em 2em,    linear-gradient(-135deg, transparent 2em, #58a 0);

正如你在下图中看到的,结果和我们预期的并不一样。为什么大小不匹配呢?都是 2em 呀!

图注:把两个渐变结合起来,并没有产生我们所期待的结果

原因是(如我们在第三章第四小节中讨论过的), 2em 的斜角尺寸在我们的第二个渐变中是颜色结点,并由此沿着渐变线测量,也就是斜角方向上的。另一方面, 2em 长度在 background-size 是背景平铺的宽度和高度,是在水平方向和垂直方向测量的。

为了让两个对齐,我们可以采用下列操作中的一种,这取决于这两个尺寸中我们想要保留哪个:

  • 要保留对角方向 2em 的尺寸,我们可以把 background-size 乘以根号二。
  • 要保留水平和垂直方向 2em 的尺寸,我们可以把切口斜角渐变颜色结点的位置除以根号二。

因为 background-size 重复两次,大多数其他的CSS尺寸不是以对角线测量的,所以通常保留水平方向的 2em 是更好的选择。这样颜色结点的位置将变成 2 除以根号二等于根号二,约等于 1.414213562 ,也就是最后会变成 1.5em 。

background: #58a; /* Fallback */background:    linear-gradient(to left bottom,    transparent 50%, rgba(0,0,0,.4) 0)    no-repeat 100% 0 / 2em 2em,    linear-gradient(-135deg,    transparent 1.5em, #58a 0);

如下图所示,最后我们会得到一个漂亮的、灵活的、简单的圆角。

图注:在改变蓝色渐变颜色结点的位置之后,我们的折叠角终于完成了

请确保有足够多的 padding ,至少能大于折叠角的尺寸,否则文本将覆盖在角上(因为它只是一个背景),破坏了折叠角的视觉效果。

其它角度的解决方案

现实生活中的折叠角很少有正好是 45° 的。如果我们想要它更加逼真一点,我们可以使用一个稍微不同的角度,比如使用 -150deg 来完成一个 30° 的角。如果我们只改变斜角的角度,但是,代表翻页效果的三角形不会自己调整,会导致两角分裂,如图所示。

图注:改变切口的角度会导致分离

但是,我们不能直接调整它的尺寸。三角形的大小不是通过角度定义的,而是通过它的 width 和 height 值确定的。那我们要怎样才能找到我们需要的 width 和 height 值呢?Well,三角函数的知识是时候派上用场了!

目前的代码是长这样的:

background: #58a; /* Fallback */background:    linear-gradient(to left bottom,    transparent 50%, rgba(0,0,0,.4) 0)    no-repeat 100% 0 / 2em 2em,    linear-gradient(-150deg,    transparent 1.5em, #58a 0);

你可以在下图中看到,如果我们需要计算两个 30-60-90 直角三角形斜边的长度,我们需要知道它们其中一条边的长度。

图注:我们的切角,放大(灰色标记的角为 30° )

下图所示的极坐标中的三角函数提醒我们,如果我们知道角度和三角形一条边的长度,我们可以通过使用正弦、余弦、和勾股定理计算它的另外两条边的长度。

图注:正弦和余弦根据一个角和斜边,帮我们计算出了直角三角形的边长

通过数学知识(或计算器),我们知道 cos 30° 等于根号三除以 2 和 sin 30° 等于二分之一。我们还知道,在我们的示例中,根据三角函数, sin 30° = 1.5 / x 以及 cos 30° = 1.5 / y ,因此:

在这里,根据勾股定理,我们可以计算出 z 的值:

现在我们可以调整三角形的大小了:

background: #58a; /* Fallback */background:    linear-gradient(to left bottom,    transparent 50%, rgba(0,0,0,.4) 0)    no-repeat 100% 0 / 3em 1.73em,    linear-gradient(-150deg,    transparent 1.5em, #58a 0);

现在,我们的折叠角如图所示。

图注:尽管我们确实达到了我们想要的结果,事实却证明,它看起来非常不真实

你可以看到,现在的三角形虽然和我们的切口相匹配,但是效果看起来并不逼真!虽然我们可能还不能很快找出原因,我们前面已经看到过很多折叠角了,所以我们一眼就能看出它和我们的视觉习惯严重偏离了。你可以通过给一个实际的纸片折一个这样角度的角,来帮助弄明白为什么这个效果看起来这么假。在纸上我们找不出能够折叠出隐约如上图这样效果的角的方法。

你可以拿张纸折一个角看看,如图所示

图注:模拟折叠角效果(Leonie and Phoebe Verou的可爱纸片)

我们想要的三角形是稍微旋转的,并且和我们“剪”掉的三角形的尺寸是一样的。因为我们不能旋转背景,所以是时候用伪元素来移动效果了:

.note {    position: relative;    background: #58a; /* Fallback */    background:    linear-gradient(-150deg,    transparent 1.5em, #58a 0);}.note::before {    content: '';    position: absolute;    top: 0; right: 0;    background: linear-gradient(to left bottom,    transparent 50%, rgba(0,0,0,.4) 0)    100% 0 no-repeat;    width: 3em;    height: 1.73em;}

这里,我们复制了刚刚下图中的效果,放到伪元素中。

我们的下一步是通过交换其 width 和 height 来让它变成我们切掉的角的对称角,改变三角形的方向,而不是互补。然后我们将其按照 30° ( (90° – 30°) – 30° ) 的方向逆时针旋转。使其斜边平行于我们的切口角:

.note::before {    content: '';    position: absolute;    top: 0; right: 0;    background: linear-gradient(to left bottom,    transparent 50%, rgba(0,0,0,.4) 0)    100% 0 no-repeat;    width: 1.73em;    height: 3em;    transform: rotate(-30deg);}

你可以在下图中看到我们改变后的效果。

图注:我们差不多完成了,但是我们需要移动三角形

正如你看到的,我们现在只需要移动三角形,使我们的两个三角形(黑色的和切开的那个)的斜边重合。就目前看,我们需要在水平和垂直方向移动三角形,所以比较难确定要怎么移动。我们可以通过把 transform-origin 设置为 bottom right ,让事情变得简单一点,这样三角形的右下角就会变成旋转中心,然后,保持固定在同一个地方:

.note::before {    /* [Rest of styling] */    transform: rotate(-30deg);    transform-origin: bottom right;}

确保把 translateY() 变换放在旋转之前,否则我们的三角形将沿它的 30° 角移动,因为每个变换都将让元素的整个坐标系统一起变换,而不仅仅是元素本身!

如下图所示:

图注:添加 transform-origin: bottom right; 可以让事情变得简单很多:现在我们只需要在垂直方向移动我们的三角形就ok了。

现在我们只需要向上垂直移动我们的三角形。为了找到确切的值,我们可以再次使用几何来解决问题。如下图所示

图注:知道我们的三角形要移动多少并不像看起来那么难

我们的三角形需要的垂直偏移量是 x-y=3-(根号三) 1.267949192 ,结果约为 1.3em :

.note::before {    /* [Rest of styling] */    transform: translateY(-1.3em) rotate(-30deg);    transform-origin: bottom right;}

下图中的效果,终于给了我们想要的效果。

图注:我们的三角形终于对上了~~好感动有木有

呼~真是不容易!此外,现在我们的三角形是通过伪元素生成的,我们可以让它变得更加逼真,通过添加圆角,(实际的)渐变,还有 box-shadow s!最后的代码如下所示:

.note {    position: relative;    background: #58a; /* Fallback */    background:    linear-gradient(-150deg,    transparent 1.5em, #58a 0);    border-radius: .5em;}.note::before {    content: '';    position: absolute;    top: 0; right: 0;    background: linear-gradient(to left bottom,    transparent 50%, rgba(0,0,0,.2) 0, rgba(0,0,0,.4))    100% 0 no-repeat;    width: 1.73em;    height: 3em;    transform: translateY(-1.3em) rotate(-30deg);    transform-origin: bottom right;    border-bottom-left-radius: inherit;    box-shadow: -.2em .2em .3em -.1em rgba(0,0,0,.15);}

你可以在下图中欣赏我们的劳动成果。

效果看起来不错,但是代码重用的情况如何呢?我们来想一些常见的修改和变化:

  • 只需要一次编辑就可以改变元素尺寸或其它参数(如 padding )。
  • 只需要编辑两次就可以改变背景颜色(没有降级的情况下)。
  • 需要四次编辑和几个普通的计算,就可以改变折叠角的大小。
  • 只需要五次编辑和几个甚至更少的琐碎的计算来改变折叠角的角度。

最后两个是比较难的。可能需要使用预处理器的 @mixin :

@mixin folded-corner($background, $size,$angle: 30deg){    position: relative;    background: $background; /* Fallback */    background:        linear-gradient($angle - 180deg,        transparent $size, $background 0);    border-radius: .5em;    $x: $size / sin($angle);    $y: $size / cos($angle);    &::before {        content: '';        position: absolute;        top: 0; right: 0;        background: linear-gradient(to left bottom,        transparent 50%, rgba(0,0,0,.2) 0,        rgba(0,0,0,.4)) 100% 0 no-repeat;        width: $y; height: $x;        transform: translateY($y - $x)        rotate(2*$angle - 90deg);        transform-origin: bottom right;        border-bottom-left-radius: inherit;        box-shadow: -.2em .2em .3em -.1em rgba(0,0,0,.2);    }}/* used as... */.note {    @include folded-corner(#58a, 2em, 40deg);}

注意:在本书写作期间,SCSS还没有原生支持三角函数。要启用支持,你可以使用 Compass框架 ,相对于其它库。你甚至可以自己写,使用泰勒展开函数!LESS,同样可以调用它们。

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
공식 계정 웹 페이지의 캐싱 업데이트에 어려움 : 버전 업데이트 후 사용자 경험에 영향을 미치는 이전 캐시를 피하는 방법은 무엇입니까?공식 계정 웹 페이지의 캐싱 업데이트에 어려움 : 버전 업데이트 후 사용자 경험에 영향을 미치는 이전 캐시를 피하는 방법은 무엇입니까?Mar 04, 2025 pm 12:32 PM

공식 계정 웹 페이지 업데이트 캐시, 이것은 간단하고 간단하며 냄비를 마시기에 충분히 복잡합니다. 공식 계정 기사를 업데이트하기 위해 열심히 노력했지만 사용자는 여전히 기존 버전을 열었습니까? 이 기사에서는이 뒤에있는 비틀기와 회전을 살펴 보고이 문제를 우아하게 해결하는 방법을 살펴 보겠습니다. 읽은 후에는 다양한 캐싱 문제를 쉽게 처리 할 수있어 사용자가 항상 가장 신선한 콘텐츠를 경험할 수 있습니다. 기본 사항에 대해 먼저 이야기 해 봅시다. 액세스 속도를 향상시키기 위해 브라우저 또는 서버는 일부 정적 리소스 (예 : 그림, CSS, JS) 또는 페이지 컨텐츠를 저장합니다. 다음에 액세스 할 때 다시 다운로드하지 않고도 캐시에서 직접 검색 할 수 있으며 자연스럽게 빠릅니다. 그러나 이것은 또한 양날의 검입니다. 새 버전은 온라인입니다.

웹 페이지의 PNG 이미지에 뇌졸중 효과를 효율적으로 추가하는 방법은 무엇입니까?웹 페이지의 PNG 이미지에 뇌졸중 효과를 효율적으로 추가하는 방법은 무엇입니까?Mar 04, 2025 pm 02:39 PM

이 기사는 CSS를 사용한 웹 페이지에 효율적인 PNG 테두리 추가를 보여줍니다. CSS는 JavaScript 또는 라이브러리에 비해 우수한 성능을 제공하며, 미묘하거나 눈에 띄는 효과를 위해 테두리 너비, 스타일 및 색상 조정 방법을 자세히 설명합니다.

HTML5 양식 유효성 검사 속성을 사용하여 사용자 입력을 유효성있게하려면 어떻게합니까?HTML5 양식 유효성 검사 속성을 사용하여 사용자 입력을 유효성있게하려면 어떻게합니까?Mar 17, 2025 pm 12:27 PM

이 기사에서는 브라우저에서 직접 사용자 입력을 검증하기 위해 필요한, Pattern, Min, Max 및 Length 한계와 같은 HTML5 양식 검증 속성을 사용하는 것에 대해 설명합니다.

& lt; datalist & gt의 목적은 무엇입니까? 요소?& lt; datalist & gt의 목적은 무엇입니까? 요소?Mar 21, 2025 pm 12:33 PM

이 기사는 HTML & LT; Datalist & GT에 대해 논의합니다. 자동 완성 제안을 제공하고, 사용자 경험을 향상시키고, 오류를 줄임으로써 양식을 향상시키는 요소. 문자 수 : 159

HTML5의 크로스 브라우저 호환성에 대한 모범 사례는 무엇입니까?HTML5의 크로스 브라우저 호환성에 대한 모범 사례는 무엇입니까?Mar 17, 2025 pm 12:20 PM

기사는 HTML5 크로스 브라우저 호환성을 보장하기위한 모범 사례에 대해 논의하고 기능 감지, 점진적 향상 및 테스트 방법에 중점을 둡니다.

& lt; meter & gt의 목적은 무엇입니까? 요소?& lt; meter & gt의 목적은 무엇입니까? 요소?Mar 21, 2025 pm 12:35 PM

이 기사는 HTML & lt; meter & gt에 대해 설명합니다. 범위 내에 스칼라 또는 분수 값을 표시하는 데 사용되는 요소 및 웹 개발의 일반적인 응용 프로그램. & lt; meter & gt; & lt; Progress & Gt; 그리고 Ex

& lt; Progress & Gt의 목적은 무엇입니까? 요소?& lt; Progress & Gt의 목적은 무엇입니까? 요소?Mar 21, 2025 pm 12:34 PM

이 기사는 HTML & lt; Progress & Gt에 대해 설명합니다. 요소, 그 목적, 스타일 및 & lt; meter & gt의 차이; 요소. 주요 초점은 & lt; progress & gt; 작업 완료 및 & lt; meter & gt; Stati의 경우

html5 & lt; time & gt; 의미 적으로 날짜와 시간을 나타내는 요소?html5 & lt; time & gt; 의미 적으로 날짜와 시간을 나타내는 요소?Mar 12, 2025 pm 04:05 PM

이 기사는 html5 & lt; time & gt; 시맨틱 날짜/시간 표현 요소. 인간이 읽을 수있는 텍스트와 함께 기계 가독성 (ISO 8601 형식)에 대한 DateTime 속성의 중요성을 강조하여 Accessibilit를 향상시킵니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는