目錄
解决方案
首頁 web前端 html教學 CSS秘密花园: 环形文本_html/css_WEB-ITnose

CSS秘密花园: 环形文本_html/css_WEB-ITnose

Jun 24, 2016 am 11:22 AM

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

尽管这不是一个常见的文本效果,有时候有一些比较短的文本需要遵循环形路径显示。这种时候,CSS就弃我们而去了。没有任何CSS属性或功能可以完成这个效果,我们唯一想到的CSS解决方案都非常麻烦,所以我们也就只是想想而已。真的没有什么办法可以实现这样的样式吗?除了使用图像,除了不影响我们文本的整体美观?

在 juliancheal.co.uk 上使用环形文本作为左边的按钮(知道我指的是哪里吗?);注意那里的环形文本是避免打破按钮的唯一办法,按钮形状的中间位置是由孔和螺纹组成的

解决方案

有一些脚本可以完成这个效果。它们通过将每个字母包裹在单独的 元素中,然后旋转到合适的角度来把它们一个一个组合成圆。这个方案不仅非常麻烦,而且还给页面的DOM元素添加了很多不必要的臃肿的标记。

尽管目前没有办法通过纯CSS来完成这个效果,但是我们可以通过一点内联SVG来很简单地完成。SVG本身就支持文本以任何路径显示,环形只不过是路径的一个特殊情况。我们来试一下!

SVG中文本按路径显示的基本方案是通过一个 元素来包裹我们的文本,把它放到一个 元素中。 元素通过 id 引用我们的路径中定义的 元素。在内联SVG中的文本还继承了我们的字体样式(除了 line-height ,因为这是SVG中默认的样式),所以我们不需要担心这个问题,就像我们引入一个外部的SVG图像一样。

可惜, 只可以存在于 元素中,这就是我们为什么不可以使用可读性更好的 元素作为我们的路径圆的原因。

假设我们要把“circular reasoning works because”这句话做成环形文本,占据一个圆圈的整个圆周,如图所示。

我们需要在HTML中添加一个内联SVG,并定义一个圆形路径:

<div class="circular">    <svg viewBox="0 0 100 100">        <path d="M 0,50 a 50,50 0 1,1 0,1 z" id="circle" />    </svg></div>
登入後複製

注意我们是通过 viewBox ,而不是 width 和 height 来定义它的单位。这可以让我们设置坐标系统和长宽比,而不是一个固定的大小。这不仅是因为它更紧凑,还因为它帮我们节省了几行CSS,因为我们不再需要为 元素应用值为 100% 的 width 和 height 值——它会自动调整为其容器的大小。

如果你不清楚 path 的语法,别担心。大家都是一样的,甚至是那些已经了解了SVG path语法的人,还是会忘记语法。如果你好奇,下面这三个命令已经非常好地概括了下面这些语法:

  • M 0,50 : 移动到点 (0,50)
  • a 50,50 0 1,1 0,1 : 从你当前点的位置,画一条圆弧,到一个新的点,新点的位置距原点往右 0 ,往下 1 。圆弧的半径为 50 ,水平和垂直方向都是。除了两种可能的角度,选择两条可能的弧形里边最大的,选择两个点中在右边的,而不是左边那个。
  • z : 通过直线段闭合路径。

为什么SVG路径的语法这么隐蔽?它当初被设计出来的时候,大家觉得没有人会手动编写SVG,所以SVG工作小组尽可能地用了最紧凑的语法,来减少文件大小。

目前,我们的路径只是一个黑色的圆。

我们需要通过 元素添加文本,并通过 xlink:href 属性把它链到我们的圆上,如下:

<div class="circular">    <svg viewBox="0 0 100 100">        <path d="M 0,50 a 50,50 0 1,1 0,1 z" id="circle" />        <text>            <textPath xlink:href="#circle">            circular reasoning works because            </textPath>        </text>    </svg></div>
登入後複製

如上图所示,尽管我们还需要做很多东西,来让它更像样更有可读性,我们已经取得了我们想要的效果,这是CSS很多年内都无法完成的!

下一步是移除我们的圆形路径上的黑色填充。我们并不希望圆形以任何方式显示出来;我们只是想要它作为我们文本的一个引导。有很多方式可以完成,比如把它加入到一个 中(这是专门为此而设计的)。但是,这里我们希望能够尽量较少SVG标签,所以我们直接通过CSS应用一个 fill: none 。

.circular path { fill: none; }
登入後複製

现在黑色的圆已经消失了

我们可以仔细研究其它问题了。下一步最大的问题是,我们大多数的文本是在SVG元素之外的,还被裁剪了。为了解决这个问题,我们需要让我们的容器元素更小一些,然后为SVG元素应用 overflow: visible ,这样它就不会裁剪它的视窗之外的任何内容了:

.circular {    width: 30em;    height: 30em;}.circular svg {    display: block;    overflow: visible;}
登入後複製

你可以在上图中看到效果。注意到我们已经差不多完成了,但是有一些文本还是被裁剪了。原因是SVG元素是根据它的尺寸浮动的,而不是溢出。因此,事实上,溢出盒子边界的 元素不会让整个SVG元素往下浮动。我们需要手动添加一个外边距来完成:

.circular {    width: 30em;    height: 30em;    margin: 3em auto 0;}.circular svg {    display: block;    overflow: visible;}
登入後複製

就是它了!我们的示例现在看起来和下图非常相像

文本也是可访问的。如果我们的圆形文本只有一个实例(如,一个网站的logo),那我们到这里就完成了。但是,如果我们关于这种类型的文本有不止一个实例,我们不希望每次都重复这些SVG标签,可以写一个简短的脚本来自动生成所需的SVG元素,如类似这样的标签:

<div class="circular">    circular reasoning works because</div>
登入後複製

该代码可以通过一个“circular”类遍历所有元素,移除它们的文本并把它存储在一个变量中,并添加必要的SVG元素:

$$('.circular').forEach(function(el) {    var NS = "http://www.w3.org/2000/svg";    var xlinkNS = "http://www.w3.org/1999/xlink";    var svg = document.createElementNS(NS, "svg");    var circle = document.createElementNS(NS, "path");    var text = document.createElementNS(NS, "text");    var textPath = document.createElementNS(NS, "textPath");    svg.setAttribute("viewBox", "0 0 100 100");    circle.setAttribute("d", "M0,50 a50,50 0 1,1 0,1z");    circle.setAttribute("id", "circle");    textPath.textContent = el.textContent;    textPath.setAttributeNS(xlinkNS, "xlink:href", "#circle");    text.appendChild(textPath);    svg.appendChild(circle);    svg.appendChild(text);    el.textContent = '';    el.appendChild(svg);});
登入後複製
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

HTML5中跨瀏覽器兼容性的最佳實踐是什麼? HTML5中跨瀏覽器兼容性的最佳實踐是什麼? Mar 17, 2025 pm 12:20 PM

文章討論了確保HTML5跨瀏覽器兼容性的最佳實踐,重點是特徵檢測,進行性增強和測試方法。

&gt; gt;的目的是什麼 元素? &gt; gt;的目的是什麼 元素? Mar 21, 2025 pm 12:34 PM

本文討論了HTML&lt; Progress&gt;元素,其目的,樣式和與&lt; meter&gt;元素。主要重點是使用&lt; progress&gt;為了完成任務和LT;儀表&gt;對於stati

&lt; datalist&gt;的目的是什麼。 元素? &lt; datalist&gt;的目的是什麼。 元素? Mar 21, 2025 pm 12:33 PM

本文討論了html&lt; datalist&gt;元素,通過提供自動完整建議,改善用戶體驗並減少錯誤來增強表格。Character計數:159

如何使用HTML5表單驗證屬性來驗證用戶輸入? 如何使用HTML5表單驗證屬性來驗證用戶輸入? Mar 17, 2025 pm 12:27 PM

本文討論了使用HTML5表單驗證屬性,例如必需的,圖案,最小,最大和長度限制,以直接在瀏覽器中驗證用戶輸入。

&lt; meter&gt;的目的是什麼。 元素? &lt; meter&gt;的目的是什麼。 元素? Mar 21, 2025 pm 12:35 PM

本文討論了HTML&lt; meter&gt;元素,用於在一個範圍內顯示標量或分數值及其在Web開發中的常見應用。它區分了&lt; meter&gt;從&lt; progress&gt;和前

視口元標籤是什麼?為什麼對響應式設計很重要? 視口元標籤是什麼?為什麼對響應式設計很重要? Mar 20, 2025 pm 05:56 PM

本文討論了視口元標籤,這對於移動設備上的響應式Web設計至關重要。它解釋瞭如何正確使用確保最佳的內容縮放和用戶交互,而濫用可能會導致設計和可訪問性問題。

&lt; iframe&gt;的目的是什麼。 標籤?使用時的安全考慮是什麼? &lt; iframe&gt;的目的是什麼。 標籤?使用時的安全考慮是什麼? Mar 20, 2025 pm 06:05 PM

本文討論了&lt; iframe&gt;將外部內容嵌入網頁,其常見用途,安全風險以及諸如對象標籤和API等替代方案的目的。

HTML容易為初學者學習嗎? HTML容易為初學者學習嗎? Apr 07, 2025 am 12:11 AM

HTML適合初學者學習,因為它簡單易學且能快速看到成果。 1)HTML的學習曲線平緩,易於上手。 2)只需掌握基本標籤即可開始創建網頁。 3)靈活性高,可與CSS和JavaScript結合使用。 4)豐富的學習資源和現代工具支持學習過程。

See all articles