Typically, a single favicon is used across a whole domain. But there are times you wanna step it up with different favicons depending on context. A website might change the favicon to match the content being viewed. Or a site might allow users to personalize their theme colors, and those preferences are reflected in the favicon. Maybe you’ve seen favicons that attempt to alert the user of some event.
Multiple favicons can technically be managed by hand — Chris has shown us how he uses two different favicons for development and production. But when you reach the scale of dozens or hundreds of variations, it’s time to dynamically generate them.
This was the situation I encountered on a recent WordPress project for a directory of colleges and universities. (I previously wrote about querying nearby locations for the same project.) When viewing a school’s profile, we wanted the favicon to use a school’s colors rather than our default blue, to give it that extra touch.
With over 200 schools in the directory and climbing, we needed to go dynamic. Fortunately, we already had custom meta fields storing data on each school’s visual identity. This included school colors, which were being used in the stylesheet. We just needed a way to apply these custom meta colors to a dynamic favicon.
In this article, I’ll walk you through our approach and some things to watch out for. You can see the results in action by viewing different schools.
SVG is key
Thanks to improved browser support for SVG favicons, implementing dynamic favicons is much easier than days past. In contrast to PNG (or the antiquated ICO format), SVG relies on markup to define vector shapes. This makes them lightweight, scaleable, and best of all, receptive to all kinds of fun.
The first step is to create your favicon in SVG format. It doesn’t hurt to also run it through an SVG optimizer to get rid of the cruft afterwards. This is what we used in the school directory:
Hooking into WordPress
Next, we want to add the favicon link markup in the HTML head. How to do this is totally up to you. In the case of WordPress, it could be added it to the header template of a child theme or echo’d through a wp_head() action.
function ca_favicon() { if ( is_singular( 'school' ) ) { $post_id = get_the_ID(); $color = get_post_meta( $post_id, 'color', true ); if ( isset( $color ) ) { $color = ltrim( $color, '#' ); // remove the hash echo '<link rel="icon" href="'%20.%20plugins_url(%20'images/favicon.php?color='%20.%20%24color,%20__FILE__%20)%20.%20'" type="image/svg+xml" sizes="any">'; } } } add_filter( 'wp_head' , 'ca_favicon' );
Here we’re checking that the post type is school, and grabbing the school’s color metadata we’ve previously stored using get_post_meta(). If we do have a color, we pass it intofavicon.phpthrough the query string.
From PHP to SVG
In a favicon.php file, we start by setting the content type to SVG. Next, we save the color value that’s been passed in, or use the default color if there isn’t one.
Then we echo the large, multiline chunk of SVG markup using PHP’s heredoc syntax (useful for templating). Variables such as $color are expanded when using this syntax.
Finally, we make a couple modifications to the SVG markup. First, classes are assigned to the color-changing elements. Second, a style element is added just inside the SVG element, declaring the appropriate CSS rules and echo-ing the $color.
Instead of a
<?php header( 'Content-Type: image/svg+xml' ); $color = $_GET[ 'color' ] ?? '065281'; $color = sanitize_hex_color_no_hash( $color ); echo <<<EOL <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000"> <style type="text/css"> <![CDATA[ .primary { fill: #$color; } .shield { stroke: #$color; } ]]> </style> <defs> <path d="M0 34L318 0l316 34v417.196a97 97 0 01-14.433 50.909C483.553 722.702 382.697 833 317 833S150.447 722.702 14.433 502.105A97 97 0 010 451.196V34z"></path> </defs> <g fill="none" fill-rule="evenodd"> <g transform="translate(183 65)"> <mask fill="#fff"> <use xlink:href="#a"></use> </mask> <use fill="#FFF" xlink:href="#a"></use> <path mask="url(#b)" d="M317-37h317v871H317z"></path> <path mask="url(#b)" d="M0 480l317 30 317-30v157l-317-90L0 517z"></path> <path fill="#FFF" mask="url(#b)" d="M317 510l317-30v37l-317 30z"></path> </g> <g fill-rule="nonzero"> <path d="M358.2 455.2c11.9 0 22.633-.992 32.2-2.975 9.567-1.983 18.375-4.9 26.425-8.75 8.05-3.85 15.458-8.458 22.225-13.825 6.767-5.367 13.3-11.433 19.6-18.2l-34.3-34.65c-9.567 8.867-19.192 15.867-28.875 21-9.683 5.133-21.525 7.7-35.525 7.7-10.5 0-20.125-2.042-28.875-6.125s-16.217-9.625-22.4-16.625-11.025-15.167-14.525-24.5-5.25-19.25-5.25-29.75v-.7c0-10.5 1.75-20.358 5.25-29.575 3.5-9.217 8.4-17.325 14.7-24.325 6.3-7 13.825-12.483 22.575-16.45 8.75-3.967 18.258-5.95 28.525-5.95 12.367 0 23.508 2.45 33.425 7.35 9.917 4.9 19.658 11.667 29.225 20.3l34.3-39.55a144.285 144.285 0 00-18.2-15.4c-6.533-4.667-13.65-8.633-21.35-11.9-7.7-3.267-16.275-5.833-25.725-7.7-9.45-1.867-19.892-2.8-31.325-2.8-18.9 0-36.167 3.325-51.8 9.975-15.633 6.65-29.05 15.75-40.25 27.3s-19.95 24.967-26.25 40.25c-6.3 15.283-9.45 31.675-9.45 49.175v.7c0 17.5 3.15 33.95 9.45 49.35 6.3 15.4 15.05 28.758 26.25 40.075 11.2 11.317 24.5 20.242 39.9 26.775 15.4 6.533 32.083 9.8 50.05 9.8z"></path> <path fill="#FFF" d="M582.35 451l22.4-54.95h103.6l22.4 54.95h56.35l-105-246.75h-49.7L527.4 451h54.95zM689.1 348.45H624L656.55 269l32.55 79.45z"></path> </g> <path stroke-width="30" d="M183 99l318-34 316 34v417.196a97 97 0 01-14.433 50.909C666.553 787.702 565.697 898 500 898S333.447 787.702 197.433 567.105A97 97 0 01183 516.196V99h0z"></path> </g> EOL; ?>
With that, you’ve got a dynamic favicon working on your site.
Security considerations
Of course, blindly echo-ing URL parameters opens you up to hacks. To mitigate these, we should sanitize all of our inputs.
In this case, we‘re only interested in values that match the 3-digit or 6-digit hex color format. We can include a function like WordPress’s own sanitize_hex_color_no_hash() to ensure only colors are passed in.
function sanitize_hex_color( $color ) { if ( '' === $color ) { return ''; } // 3 or 6 hex digits, or the empty string. if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) { return $color; } } function sanitize_hex_color_no_hash( $color ) { $color = ltrim( $color, '#' ); if ( '' === $color ) { return ''; } return sanitize_hex_color( '#' . $color ) ? $color : null; }
You’ll want to add your own checks based on the values you want passed in.
Caching for better performance
Browsers cache SVGs, but this benefit is lost for PHP files by default. This means each time the favicon is loaded, your server’s being hit.
To reduce server strain and improve performance, it’s essential that you explicitly cache this file. You can configure your server, set up a page rule through your CDN, or add a cache control header to the very top of favicon.php like so:
header( 'Cache-Control: public, max-age=604800' ); // 604,800 seconds or 1 week
In our tests, with no caching, our 1.5 KB SVG file took about 300 milliseconds to process on the first load, and about 100 milliseconds on subsequent loads. That’s pretty lousy. But with caching, we brought this down to 25 ms from CDN on first load, and 1 ms from browser cache on later loads — as good as a plain old SVG.
Browser support
If we were done there, this wouldn’t be web development. We still have to talk browser support.
As mentioned before, modern browser support for SVG favicons is solid, and fully-supported in current versions of Chrome, Firefox, and Edge.
One caveat is that Firefox requires the attribute type="image/svg+xml" in the favicon declaration for it to work. The other browsers are more forgiving, but it‘s just good practice. You should include sizes="any" while you’re at it.
<link rel="icon" href="path/to/favicon.svg" type="image/svg+xml" sizes="any">
Safari
Safari doesn‘t support SVG favicons as of yet, outside of the mask icon feature intended for pinned tabs. In my experimentation, this was buggy and inconsistent. It didn’t handle complex shapes or colors well, and cached the same icon across the whole domain. Ultimately we decided not to bother and just use a fallback with the default blue fill until Safari improves support.
Fallbacks
As solid as SVG favicon support is, it‘s still not 100%. So be sure to add fallbacks. We can set an additional favicon for when SVG icons aren’t supported with the rel="alternative icon" attribute:
<link rel="icon" href="path/to/favicon.svg" type="image/svg+xml" sizes="any">
To make the site even more bulletproof, you can also drop the eternal favicon.ico in your root.
Going further
We took a relatively simple favicon and swapped one color for another. But taking this dynamic approach opens the door to so much more: modifying multiple colors, other properties like position, entirely different shapes, and animations.
For instance, here’s a demo I’ve dubbed Favicoin. It plots cryptocurrency prices in the favicon as a sparkline.
Implementing dynamic favicons like this isn’t limited to WordPress or PHP; whatever your stack, the same principles apply. Heck, you could even achieve this client-side with data URLs and JavaScript… not that I recommend it for production.
But one thing‘s for sure: we’re bound to see creative applications of SVG favicons in the future. Have you seen or created your own dynamic favicons? Do you have any tips or tricks to share?
以上がWordPress用のダイナミックファビコンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

Goofontsは、開発者妻とデザイナーの夫によって署名されたサイドプロジェクトであり、どちらもタイポグラフィの大ファンです。 Googleにタグを付けています

Pavithra Kodmadは、彼らが変化したWeb開発に関する最も時代を超越した記事のいくつかであると考えていることについて、人々に推奨事項を求めました

GraphQL APIの構築方法を学ぶことは非常に挑戦的です。ただし、10分でGraphQL APIを使用する方法を学ぶことができます!そして、それは私が完璧になったことがあります

ここでは、Yuanchuanからの合法的なCSSの策略があります。このCSSプロパティオフセットパスがあります。むかしむかし、それはモーションパスと呼ばれ、その後改名されました。私


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

WebStorm Mac版
便利なJavaScript開発ツール

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境
