英文:
Symbols inline with text (emojis) in html
问题
目标
我想要创建一个用于模板化卡片和桌面桌面棋盘游戏中使用的其他对象的网页。许多游戏包括一种“符号字体”,即一组在游戏上下文中具有含义的符号,这些符号与文本一起内联使用。因此,我的最终目标是能够在背景图像上定位多个文本字段,并包含带有该文本的多彩自定义符号。
我想象我所尝试的内容需要类似于支持表情符号的技术。
我已成功在<span>
的内部HTML中呈现了自定义符号。但是,我想要将这些符号与可以定位在图像上的文本内联呈现。如何做到这一点?
我尝试过的方法
-
我在Inkscape中绘制了一个自定义符号,并保存为32x32的
svg
文件。它是一个半黄半蓝的圆圈。 -
我将符号上传到icomoon并下载了一个字体包。Icomoon生成
.tff
、.svg
和.woff
字体文件。它还生成了一些示例HTML和CSS。 -
我将HTML和CSS精简到了一个相当简化的(不)工作示例中:
demo.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Symbol font demo</title> <link rel="stylesheet" href="style.css"> </head> <body> <p>This code</p> <xmp> <div> <span class="my-fontcircle"><span class="path1"></span><span class="path2"></span></span> </div> </xmp> <p>Produces this</p> <div> <span class="my-fontcircle"><span class="path1"></span><span class="path2"></span></span> </div> <p>This code</p> <xmp> <div font-family: "my-font">Let's use our symbol in line: </div> </xmp> <p>Produces this</p> <div font-family: "my-font">Let's use our symbol in line: </div> </body> </html>
style.css
@font-face { font-family: 'my-font'; src: url('fonts/my-font.ttf?81gy7') format('truetype'), url('fonts/my-font.woff?81gy7') format('woff'), url('fonts/my-font.svg?81gy7#my-font') format('svg'); font-weight: normal; font-style: normal; font-display: block; } [class^="my-font"], [class*=" my-font"] { /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'my-font' !important; speak: never; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; /* Better Font Rendering ========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .my-fontcircle .path1:before { content: "\e900"; color: rgb(251, 236, 0); } .my-fontcircle .path2:before { content: "\e901"; margin-left: -1em; color: rgb(0, 129, 255); }
结果如下图所示:
如我们所见,当我们使用CSS类方法时,符号显示出来,但不会在文本中呈现。如何使符号在文本中内联显示?
英文:
Goal
I would like to create a web page for templating cards and other objects used in table top board games.
Many games include a sort of "symbol font", i.e. a set of symbols with meaning in the context of the game, which are used inline with text.
Therefore, my end goal is to be able to position several text fields over a background image and include multi-colored custom symbols with that text.
I imagine that what I am attempting requires techniques somewhat similar to whatever is done to support emojis.
I have succeeded in rendering custom symbols in the inner HTML of a <span>
.
However, I would like to render the symbols inline with text that can be positioned over an image.
How can this be done?
What I've tried
-
I drew a custom symbol in Inkscape, saved as a 32x32
svg
file. It is a half-yellow half-blue circle. -
I uploaded the symbol to icomoon and downloaded a font package. Icomoon produces
.tff
,.svg
, and.woff
font files. It also produces some example html and css. -
I pared down the html and css to a pretty minimal (not)working example:
demo.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Symbol font demo</title> <link rel="stylesheet" href="style.css"> </head> <body> <p>This code</p> <xmp> <div> <span class="my-fontcircle"><span class="path1"></span><span class="path2"></span></span> </div> </xmp> <p>Produces this</p> <div> <span class="my-fontcircle"><span class="path1"></span><span class="path2"></span></span> </div> <p>This code</p> <xmp> <div font-family: "my-font">Let's use our symbol in line: &#xe900;</div> </xmp> <p>Produces this</p> <div font-family: "my-font">Let's use our symbol in line: &#xe900;</div> </body> </html>
style.css
@font-face { font-family: 'my-font'; src: url('fonts/my-font.ttf?81gy7') format('truetype'), url('fonts/my-font.woff?81gy7') format('woff'), url('fonts/my-font.svg?81gy7#my-font') format('svg'); font-weight: normal; font-style: normal; font-display: block; } [class^="my-font"], [class*=" my-font"] { /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'my-font' !important; speak: never; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .my-fontcircle .path1:before { content: "\e900"; color: rgb(251, 236, 0); } .my-fontcircle .path2:before { content: "\e901"; margin-left: -1em; color: rgb(0, 129, 255); }
The result looks like this:
As we can see, the symbol shows up when we use the css class method, but it doesn't render in text.
How can we make the symbol show up inline with text?
答案1
得分: 2
如果您不需要替换常见的表情符号Unicode字符(例如 😀
=> 笑脸),您可以编写一个简单的图标注入脚本。
/**
* 定义您的图标
* 作为对象
*/
let icons = {
'screaming': "https://camo.githubusercontent.com/26d09c4725b30d28f1d4b28ae161b685fa87d432912f0b7b6dd1e4fbe3cfe2bc/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f6e706d2f407376676d6f6a692f6e6f746f40302e322e302f7376672f31463633312e737667",
'pleading': "https://camo.githubusercontent.com/dbb026248af889b4cfd2c8bfde4252958b18db090e30ae0e832bbf17cef35216/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f6n706d2f407376676d6f6a692f7477656d6f6a6940322e302e302f7376672f31463937412e737667"
}
/**
* 查询图标占位符
* 并根据对象中定义的图像注入图像
*/
let iconsInline = document.querySelectorAll('[data-icon]')
iconsInline.forEach(icn => {
let type = icn.dataset.icon;
let img = document.createElement('img');
let src = icons[type];
img.src = src;
img.classList.add('img-emoji', `img-emoji-${type}`)
icn.append(img)
})
body{
font-size:8vmin;
}
[data-icon]{
display:inline-block;
height:1em;
width:1em;
/** 调整基线对齐 */
transform: translateY(0.13em);
}
<p><span data-icon="pleading"></span> 一天早上,格里高尔·萨姆萨从<span data-icon="pleading"></span> 不安的梦中醒来,发现自己变成了床上的<span data-icon="screaming"></span> 可怕的昆虫。</p>
工作原理
您正在定义一个包含所有符号源和它们的标识符的对象:
let icons = {
'screaming': "icon1.svg",
'laughing': "icon2.svg",
}
与fontAwesome和其他图标库API类似,您可以通过为占位符元素设置可读性和自解释的标识符来指定图标类型:
<span data-icon="screaming"></span>
在这种情况下,我使用了数据属性而不是类名,以避免类名冲突和前缀的需要(例如 fa-icon-mame
)。
现在,我们可以用实际图标替换占位符:
let iconsInline = document.querySelectorAll('[data-icon]')
iconsInline.forEach(icn => {
let type = icn.dataset.icon;
let img = document.createElement('img');
let src = icons[type];
img.src = src;
img.classList.add('img-emoji', `img-emoji-${type}`)
icn.append(img)
})
您还可以调整此方法以注入内联SVG。但是,如果您的图标包含渐变、蒙版或剪切路径等内容,您可能会遇到问题。为了避免这些问题,您可以使用Danny '365CSI' Engelman的<load-file>
本机Web组件将您的图标附加为阴影DOM元素。
英文:
If you don't need to replace common emoji unicode characters (e.g &#x1f600
=> smiley) you could write a simple icon injection script.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
/**
* define your icons
* as object
*/
let icons = {
'screaming': "https://camo.githubusercontent.com/26d09c4725b30d28f1d4b28ae161b685fa87d432912f0b7b6dd1e4fbe3cfe2bc/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f6e706d2f407376676d6f6a692f6e6f746f40302e322e302f7376672f31463633312e737667",
"pleading": "https://camo.githubusercontent.com/dbb026248af889b4cfd2c8bfde4252958b18db090e30ae0e832bbf17cef35216/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f6e706d2f407376676d6f6a692f7477656d6f6a6940322e302e302f7376672f31463937412e737667"
}
/**
* query icon placeholders
* and inject images as defined in object
*/
let iconsInline= document.querySelectorAll('[data-icon]')
iconsInline.forEach(icn=>{
let type = icn.dataset.icon;
let img = document.createElement('img');
let src = icons[type];
img.src = src;
img.classList.add('img-emoji', `img-emoji-${type}`)
icn.append(img)
})
<!-- language: lang-css -->
body{
font-size:8vmin;
}
[data-icon]{
display:inline-block;
height:1em;
width:1em;
/** adjust baseline alignment */
transform: translateY(0.13em);
}
<!-- language: lang-html -->
<p><span data-icon="pleading"></span> One morning, when Gregor Samsa woke from <span data-icon="pleading"></span> troubled dreams, he found himself transformed in his bed into a <span data-icon="screaming"></span> horrible vermin.</p>
<!-- end snippet -->
How it works
You're defining an object containing all symbol sources and their identifier:
let icons = {
'screaming': "icon1.svg",
'laughing': "icon2.svg",
}
Similar to fontAwesome and other icon libray APIs you can specify the icon type by setting a readable/self-explanatory identifier for the placeholder element.
<span data-icon="screaming"></span>
In this case I'm using a data attribute instead of a class name to avoid class name conflicts and the need of prefixing (e.g. fa-icon-mame
).
Now we can replace the placeholders with the actual icons:
let iconsInline= document.querySelectorAll('[data-icon]')
iconsInline.forEach(icn=>{
let type = icn.dataset.icon;
let img = document.createElement('img');
let src = icons[type];
img.src = src;
img.classList.add('img-emoji', `img-emoji-${type}`)
icn.append(img)
})
You could also adapt this approach to inject inline SVGs.
However you might run into troubles if your icons contain gradients, masks or clip-paths.
To circumvent these problems you could use
Danny '365CSI' Engelman's <load-file>
native web component to append your icons as shadow DOM elements.
答案2
得分: 1
首先,我不确定为什么您无法在背景图上放置文本并在文本中包含多彩的自定义符号,除非有一些限制,比如HTML转义,您希望在其中使用图标。
<span>
是一个内联元素,通过一些对齐样式(尝试使用 inline-flex
和 justify-content: center;
开始),它应该可以正常工作。有很多资源可以帮助您居中元素。
我已经准备了一个示例,使用了不同的图标库:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.background {
background-image: url(http://www.nasa.gov/sites/default/files/thumbnails/image/northseabloom_oli2_2023165_lrg.jpg);
background-repeat: no-repeat;
background-position: center;
display: flex;
flex-direction: column;
height: 200px;
width: 200px;
}
.background .text {
color: white;
}
.background .icon {
color: red;
}
.background .bottom-text {
margin-top: auto;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"/>
<div class="background">
<p class="text">Hello icons <span class="icon"><i class="fa-solid fa-icons"></i></span>, inline on a background no less!</p>
<p class="text bottom-text">Hello icons <span class="icon"><i class="fa-solid fa-icons"></i></span>, inline on a background no less!</p>
</div>
<!-- end snippet -->
您的主要问题似乎是您正在使用自定义HTML实体,例如您的示例中的 
。我是否正确地认为您希望基于您的CSS content: "\e900"
来实现这个效果?我的简要研究表明,为了使这个工作,您需要扩展XHTML,但我在您的示例中并没有看到这一点。这可能是为什么您的图标未按预期呈现的原因。
英文:
First off, I'm not sure why you wouldn't be able to position text over a background image and include multi-colored custom symbols with that text with your initial implementation unless there are some limitations such as HTML escaping where you'd like to use your icons.
<span>
is an inline element, and with a few alignment styles (try inline-flex
with justify-content: center;
to start) it should work fine. There are loads of resources for centering elements.
I've put together an example with a different icon library:.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.background {
background-image: url(http://www.nasa.gov/sites/default/files/thumbnails/image/northseabloom_oli2_2023165_lrg.jpg);
background-repeat: no-repeat;
background-position: center;
display: flex;
flex-direction: column;
height: 200px;
width: 200px;
}
.background .text {
color: white;
}
.background .icon {
color: red;
}
.background .bottom-text {
margin-top: auto;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"/>
<div class="background">
<p class="text">Hello icons <span class="icon"><i class="fa-solid fa-icons"></i></span>, inline on a background no less!</p>
<p class="text bottom-text">Hello icons <span class="icon"><i class="fa-solid fa-icons"></i></span>, inline on a background no less!</p>
</div>
<!-- end snippet -->
Your primary issue appears to be that you are using a custom HTML entity, in your example &#xe900;
. Am I correct to assume that you expect this to work based on your CSS content: "\e900";
? My brief research indicates that you need to extend XHTML in order for this to work, which I don't see in your example. This could be why your icon is not rendering as expected.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论