是否可以将 CSS 应用于字符的一半?

IT技术 javascript html css
2021-02-05 14:55:05

我在找什么:

一种为角色的一半设置样式的方法(在这种情况下,一半的字母是透明的)

我目前搜索和尝试的内容(运气不好):

  • 为字符/字母的一半设置样式的方法
  • 使用 CSS 或 JavaScript 对字符的一部分进行样式设置
  • 将 CSS 应用于字符的 50%

下面是我试图获得的一个例子。

X

是否存在 CSS 或 JavaScript 解决方案,或者我将不得不求助于图像?我不想走图像路线,因为此文本最终会动态生成。


更新:

由于许多人问我为什么要为角色的一半设置样式,这就是原因。我所在的城市最近花了 25 万美元为自己定义了一个新的“品牌”。这个标志是他们想出来的。许多人抱怨简单和缺乏创造力,并继续这样做。我的目标是把这个网站当作一个笑话。输入“哈利法克斯”,您就会明白我的意思。

6个回答

现在作为插件在 GitHub 上!

在此处输入图片说明 随意分叉和改进。

演示| 下载 Zip | Half-Style.com(重定向到 GitHub)


  • 单个字符的纯 CSS
  • JavaScript 用于跨文本或多个字符的自动化
  • 为盲人或视障人士的屏幕阅读器保留文本可访问性

第 1 部分:基本解决方案

文本上的半样式

演示: http : //jsfiddle.net/arbel/pd9yB/1694/


这适用于任何动态文本或单个字符,并且都是自动化的。您需要做的就是在目标文本上添加一个类,剩下的就都搞定了。

此外,为盲人或视障人士的屏幕阅读器保留了原始文本的可访问性。

单字解释:

纯 CSS。您需要做的就是将.halfStyleclass 应用于包含您想要半样式的字符的每个元素。

对于包含字符的每个 span 元素,您可以创建一个数据属性,例如 here data-content="X",并在伪元素上使用,content: attr(data-content);因此.halfStyle:before该类将是动态的,您无需为每个实例对其进行硬编码。

对任何文本的解释:

只需将textToHalfStyle添加到包含文本的元素。


// jQuery for automated mode
jQuery(function($) {
    var text, chars, $el, i, output;

    // Iterate over all class occurences
    $('.textToHalfStyle').each(function(idx, el) {
    $el = $(el);
    text = $el.text();
    chars = text.split('');

    // Set the screen-reader text
    $el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + text + '</span>');

    // Reset output for appending
    output = '';

    // Iterate over all chars in the text
    for (i = 0; i < chars.length; i++) {
        // Create a styled element for each character and append to container
        output += '<span aria-hidden="true" class="halfStyle" data-content="' + chars[i] + '">' + chars[i] + '</span>';
    }

    // Write to DOM only once
    $el.append(output);
  });
});
.halfStyle {
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    color: black; /* or transparent, any color */
    overflow: hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
}

.halfStyle:before {
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow: hidden;
    color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>Single Characters:</p>
<span class="halfStyle" data-content="X">X</span>
<span class="halfStyle" data-content="Y">Y</span>
<span class="halfStyle" data-content="Z">Z</span>
<span class="halfStyle" data-content="A">A</span>

<hr/>
<p>Automated:</p>

<span class="textToHalfStyle">Half-style, please.</span>

( JSFiddle 演示)


第 2 部分:高级解决方案 - 独立的左右部分

文本上的半样式 - 高级 - 带有文本阴影

使用此解决方案,您可以单独和独立地设置左右部分的样式

一切都一样,只有更高级的 CSS 才能发挥作用。

( JSFiddle 演示)



第 3 部分:混合搭配和改进

现在我们知道什么是可能的,让我们创造一些变化。


-水平半零件

  • 没有文字阴影:

    水平半部分 - 无文字阴影

  • 每个半部分独立的文本阴影的可能性:

    halfStyle - 水平半部分 - 带有文字阴影

( JSFiddle 演示)



-垂直 1/3 零件

  • 没有文字阴影:

    halfStyle - 垂直 1/3 部分 - 无文字阴影

  • 每个 1/3 部分的文本阴影的可能性独立:

    halfStyle - 垂直 1/3 部分 - 带有文字阴影

( JSFiddle 演示)



-水平 1/3 零件

  • 没有文字阴影:

    halfStyle - 水平 1/3 部分 - 无文字阴影

  • 每个 1/3 部分的文本阴影的可能性独立:

    halfStyle - 水平 1/3 部分 - 带有文字阴影

( JSFiddle 演示)



-@KevinGranger的HalfStyle改进

halfStyle - 凯文格兰杰

( JSFiddle 演示)



-@SamTremaine 对 HalfStyle 的PeelingStyle改进

halfStyle - SamTremaine

JSFiddle 演示samtremaine.co.uk



第 4 部分:准备生产

可以在同一页面上的所需元素上使用自定义的不同 Half-Style 样式集。您可以定义多个样式集并告诉插件使用哪一个。

该插件使用data-halfstyle="[-CustomClassName-]"目标.textToHalfStyle元素上的数据属性并自动进行所有必要的更改。

因此,只需在包含文本的元素上添加textToHalfStyleclass 和 data 属性data-halfstyle="[-CustomClassName-]"该插件将完成其余的工作。

halfStyle - 同一页面上的多个

此外,CSS 样式集的类定义与[-CustomClassName-]上面提到部分匹配并链接到.halfStyle,因此我们将有.halfStyle.[-CustomClassName-]

jQuery(function($) {
    var halfstyle_text, halfstyle_chars, $halfstyle_el, halfstyle_i, halfstyle_output, halfstyle_style;

    // Iterate over all class occurrences
    $('.textToHalfStyle').each(function(idx, halfstyle_el) {
        $halfstyle_el = $(halfstyle_el);
        halfstyle_style = $halfstyle_el.data('halfstyle') || 'hs-base';
        halfstyle_text = $halfstyle_el.text();
        halfstyle_chars = halfstyle_text.split('');

        // Set the screen-reader text
        $halfstyle_el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + halfstyle_text + '</span>');

        // Reset output for appending
        halfstyle_output = '';

        // Iterate over all chars in the text
        for (halfstyle_i = 0; halfstyle_i < halfstyle_chars.length; halfstyle_i++) {
            // Create a styled element for each character and append to container
            halfstyle_output += '<span aria-hidden="true" class="halfStyle ' + halfstyle_style + '" data-content="' + halfstyle_chars[halfstyle_i] + '">' + halfstyle_chars[halfstyle_i] + '</span>';
        }

        // Write to DOM only once
        $halfstyle_el.append(halfstyle_output);
    });
});
/* start half-style hs-base */

.halfStyle.hs-base {
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    overflow: hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
    color: #000; /* for demo purposes */
}

.halfStyle.hs-base:before {
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    pointer-events: none; /* so the base char is selectable by mouse */
    overflow: hidden;
    color: #f00; /* for demo purposes */
}

/* end half-style hs-base */


/* start half-style hs-horizontal-third */

.halfStyle.hs-horizontal-third { /* base char and also the bottom 1/3 */
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    color: transparent;
    overflow: hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
    color: #f0f;
    text-shadow: 2px 2px 0px #0af; /* for demo purposes */
}

.halfStyle.hs-horizontal-third:before { /* creates the top 1/3 */
    display: block;
    z-index: 2;
    position: absolute;
    top: 0;
    height: 33.33%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow: hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #f00; /* for demo purposes */
    text-shadow: 2px -2px 0px #fa0; /* for demo purposes */
}

.halfStyle.hs-horizontal-third:after { /* creates the middle 1/3 */
    display: block;
    position: absolute;
    z-index: 1;
    top: 0;
    height: 66.66%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow: hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #000; /* for demo purposes */
    text-shadow: 2px 2px 0px #af0; /* for demo purposes */
}

/* end half-style hs-horizontal-third */


/* start half-style hs-PeelingStyle, by user SamTremaine on Stackoverflow.com */

.halfStyle.hs-PeelingStyle {
  position: relative;
  display: inline-block;
  font-size: 68px;
  color: rgba(0, 0, 0, 0.8);
  overflow: hidden;
  white-space: pre;
  transform: rotate(4deg);
  text-shadow: 2px 1px 3px rgba(0, 0, 0, 0.3);
}

.halfStyle.hs-PeelingStyle:before { /* creates the left part */
  display: block;
  z-index: 1;
  position: absolute;
  top: -0.5px;
  left: -3px;
  width: 100%;
  content: attr(data-content);
  overflow: hidden;
  pointer-events: none;
  color: #FFF;
  transform: rotate(-4deg);
  text-shadow: 0px 0px 1px #000;
}

/* end half-style hs-PeelingStyle */


/* start half-style hs-KevinGranger, by user KevinGranger on StackOverflow.com*/

.textToHalfStyle.hs-KevinGranger {
  display: block;
  margin: 200px 0 0 0;
  text-align: center;
}

.halfStyle.hs-KevinGranger {
  font-family: 'Libre Baskerville', serif;
  position: relative;
  display: inline-block;
  width: 1;
  font-size: 70px;
  color: black;
  overflow: hidden;
  white-space: pre;
  text-shadow: 1px 2px 0 white;
}

.halfStyle.hs-KevinGranger:before {
  display: block;
  z-index: 1;
  position: absolute;
  top: 0;
  width: 50%;
  content: attr(data-content); /* dynamic content for the pseudo element */
  overflow: hidden;
  color: white;
}

/* end half-style hs-KevinGranger
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-base">Half-style, please.</span>
</p>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-horizontal-third">Half-style, please.</span>
</p>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-PeelingStyle">Half-style, please.</span>
</p>
<p style="background-color:#000;">
    <span class="textToHalfStyle" data-halfstyle="hs-KevinGranger">Half-style, please.</span>
</p>

( JSFiddle 演示)

评论不用于扩展讨论;此对话已移至聊天
2021-03-29 14:55:05
这很酷。值得注意的是,这种技术打破了自动换行、空白和字符间距 CSS。
2021-04-08 14:55:05

在此处输入图片说明


我刚刚完成了插件的开发,供大家使用!希望你会喜欢它。

GitHub 上查看项目 - 查看项目网站(所以你可以看到所有的拆分样式)

用法

首先,请确保您已jQuery包含库。获取最新 jQuery 版本的最佳方法是使用以下内容更新您的 head 标签:

<script src="http://code.jquery.com/jquery-latest.min.js"></script>

下载文件后,请确保将它们包含在您的项目中:

<link rel="stylesheet" type="text/css" href="css/splitchar.css">
<script type="text/javascript" src="js/splitchar.js"></script>

标记

您所要做的就是分配 class splitchar,然后将所需的样式分配给包装文本的元素。例如

<h1 class="splitchar horizontal">Splitchar</h1>

完成所有这些后,只需确保在文档就绪文件中调用 jQuery 函数,如下所示:

$(".splitchar").splitchar();

定制

为了使文本看起来完全符合您的要求,您所要做的就是像这样应用您的设计:

.horizontal { /* Base CSS - e.g font-size */ }
.horizontal:before { /* CSS for the left half */ }
.horizontal:after { /* CSS for the right half */ }


而已!现在你已经Splitchar设置好插件。有关它的更多信息,请访问http://razvanbalosin.com/Splitchar.js/

@MathewMacLean emisfera 必须有答案,对吗?
2021-03-15 14:55:05
截至目前,您的解决方案是最容易为多个字符实现的,但仍然不是 100%。
2021-04-02 14:55:05
您可能想要编辑您的答案以不建议使用 jquery-latest.js。正如@NielsBom 提到的,过去它在更新时可能会破坏您的网站。自 2014 年 7 月以来,它不会这样做,但那是因为它被锁定在 1.11.1 版本并且永远不会再次更新。
2021-04-02 14:55:05
不要依赖 jquery-latest.min.js,如果 jQuery 更新并且该插件不能与较新的插件一起使用,它会使您的网站毫无预警地中断。相反:使用特定版本并在更新时检查兼容性。
2021-04-07 14:55:05
即使在最新的小提琴中,这也存在文本换行问题。当一个字符换行时,它基本上分成两个。不过,应该是一个微不足道的修复。
2021-04-08 14:55:05

是的,你可以只用一个字符和 CSS 来做到这一点:

http://jsbin.com/rexoyice/1/

h1 {
  display: inline-block;
  margin: 0; /* for demo snippet */
  line-height: 1em; /* for demo snippet */
  font-family: helvetica, arial, sans-serif;
  font-weight: bold;
  font-size: 300px;
  background: linear-gradient(to right, #7db9e8 50%,#1e5799 50%);
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
<h1>X</h1>

从视觉上看,所有使用两个字符的示例(无论是通过 JS、CSS 伪元素还是 HTML)看起来都不错,但请注意,所有这些都向 DOM 添加了内容,这可能会导致可访问性——以及文本选择/剪切/粘贴问题。

@MathewMacLean 如果只有 IE 消失并且 Firefox 开始使用 Webkit,我们的工作就会容易得多。:)
2021-03-16 14:55:05
是的,如果blink/webkit 死了,而现代IE+FF 渲染引擎能幸存下来,我会更高兴。这并不是说 chrome 的其余部分不好,只是它的渲染现在几乎是最糟糕的。
2021-03-24 14:55:05
话虽如此,background-clip: text非常棒,他们应该考虑将它(或类似的东西text-decoration-background)用于 4 级module。
2021-03-25 14:55:05
WebKit 有过渲染错误的历史,这些错误几乎是 IE6/IE7 级别的怪异(您甚至可以说 Safari 和 Chrome 是现代网络的 IE6),并且行为方式无缘无故偏离标准。IE 自从版本 9 以来已经好多了,所以虽然古老的版本应该已经死了,但我看不出有任何理由讨厌它的最新版本。而且我当然不明白为什么人们支持 WebKit/Blink 单一文化的想法(这里的评论可能是在开玩笑,但我听说有人认真地相信它)。
2021-04-01 14:55:05
@马特哈里森哈。好吧,我想it't不是唯一的WebKit!:)
2021-04-04 14:55:05

例子


JSFiddle演示

我们将仅使用 CSS 伪选择器来完成!

此技术适用于动态生成的内容以及不同的字体大小和宽度。

HTML:

<div class='split-color'>Two is better than one.</div>

CSS:

.split-color > span {
    white-space: pre-line;
    position: relative;
    color: #409FBF;
}

.split-color > span:before {
    content: attr(data-content);
    pointer-events: none;  /* Prevents events from targeting pseudo-element */
    position: absolute;
    overflow: hidden;
    color: #264A73;
    width: 50%;
    z-index: 1;
}

要包装动态生成的字符串,您可以使用这样的函数:

// Wrap each letter in a span tag and return an HTML string
// that can be used to replace the original text
function wrapString(str) {
  var output = [];
  str.split('').forEach(function(letter) {
    var wrapper = document.createElement('span');
    wrapper.dataset.content = wrapper.innerHTML = letter;

    output.push(wrapper.outerHTML);
  });

  return output.join('');
}

// Replace the original text with the split-color text
window.onload = function() {
    var el  = document.querySelector('.split-color'),
        txt = el.innerHTML;
    
    el.innerHTML = wrapString(txt);
}

它可能无关紧要,也可能无关紧要,但前段时间,我创建了一个 jQuery 函数,它可以做同样的事情,但水平不同。

我称它为“Strippex”对于'stripe'+'text',演示:http ://cdpn.io/FcIBg

我不是说这是任何问题的解决方案,但我已经尝试将 css 应用于一半字符,但水平,所以想法是相同的,实现可能很糟糕,但它有效。

啊,最重要的是,我在创造它时玩得很开心!

在此处输入图片说明

为答案本身添加一个最小的可重复示例,而不是链接到第 3 方站点。当该链接失效时,答案将失去它的value。目前,这在技术上是“NAA”(不是答案)。
2021-03-18 14:55:05
@LukyVj 我通过添加pointer-events:none&:nth-child(2)-更新了您的功能&:nth-child(5)这使得文本只能突出显示一次,并且您只能获得一份副本。你可以在这里看到它:codepen.io/anon/pen/upLaj
2021-04-02 14:55:05