CSS:文本转换对于土耳其语字符无法正常工作

发布于 2024-09-25 05:50:59 字数 815 浏览 8 评论 0原文

主要浏览器的实现似乎在使用土耳其字符的 text-transform: uppercase 方面存在问题。据我所知(我不是土耳其语。)有四个不同的 i 字符: ı i I ï 其中最后两个是前两个的大写表示。

然而,将 text-transform:uppercase 应用于 ı i 时,浏览器(检查了 IE、Firefox、Chrome 和 Safari)会导致 I I ,而这不是正确,并且可能会极大地改变单词的含义,以致它们变成侮辱。 (这就是我被告知的)

由于我对解决方案的研究没有揭示任何问题,我的问题是:这个问题有解决方法吗?第一个解决方法可能是完全删除 text-transform: uppercase 但这是最​​后的手段。

有趣的是,W3C 在其网站上对此问题进行了测试,但缺乏有关此问题的进一步信息。 http://www.w3 .org/International/tests/tests-html-css/tests-text-transform/generate?test=5

我感谢任何帮助并期待您的答案:-)

这是一个 codepen

The implementations of the major browsers seem to have problems with text-transform: uppercase with Turkish characters. As far as I know (I'm not Turkish.) there are four different i characters: ı i I İ where the last two are the uppercase representations of the former two.

However applying text-transform:uppercase to ı i, the browsers (checked IE, Firefox, Chrome and Safari) results in I I which is not correct and may change the meaning of the words so much so that they become insults. (That's what I've been told)

As my research for solutions did not reveal any my question is: Are there workarounds for this issue? The first workaround might be to remove text-transform: uppercase entirely but that's some sort of last resort.

Funny thing, the W3C has tests for this problem on their site, but lack of further information about this issue. http://www.w3.org/International/tests/tests-html-css/tests-text-transform/generate?test=5

I appreciate any help and looking forward to your answers :-)

Here's a codepen

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

唔猫 2024-10-02 05:50:59

您可以添加 lang 属性并将其值设置为 tr 来解决此问题:

这是工作示例。

You can add lang attribute and set its value to tr to solve this:

<html lang="tr"> or <div lang="tr">

Here is working example.

耳根太软 2024-10-02 05:50:59

这是一个快速而肮脏的解决方法示例 - 它比我想象的要快(在具有 2400 个标签的文档中进行测试 -> 无延迟)。但我发现 js 解决方法并不是最好的解决方案

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-3">
</head>
<body>
<div style="text-transform:uppercase">a b c ç d e f g ğ h ı i j k l m n o ö p r s ş t u ü v y z (source)</div> <div>A B C Ç D E F G Ğ H I İ J K L M N O Ö P R S Ş T U Ü V Y Z (should be like this)</div>

<script>
    function getStyle(element, style) {
        var result;

        if (document.defaultView && document.defaultView.getComputedStyle) {
            result = document.defaultView.getComputedStyle(element, '').getPropertyValue(style);
        } else if(element.currentStyle) {
            style = style.replace(/\-(\w)/g, function (strMatch, p1) {
                return p1.toUpperCase();
            });
            result = element.currentStyle[style];
        }
        return result;
    }

    function replaceRecursive(element) {
        if (element && element.style && getStyle(element, 'text-transform') == 'uppercase') {
            element.innerHTML = element.innerHTML.replace(/ı/g, 'I');
            element.innerHTML = element.innerHTML.replace(/i/g, 'İ');    // replaces 'i' in tags too, regular expression should be extended if necessary
        }

        if (!element.childNodes || element.childNodes.length == 0) return;

        for (var n in element.childNodes) {
            replaceRecursive(element.childNodes[n]);
        }
    }

    window.onload = function() {    // as appropriate 'ondomready'
        alert('before...');
        replaceRecursive(document.getElementsByTagName('body')[0]);
        alert('...after');
    }
</script>

</body>
</html>

Here's a quick and dirty workaround example - it's faster than I thought (tested in a document with 2400 tags -> no delay). But I see that js workarounds are not the very best solution

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-3">
</head>
<body>
<div style="text-transform:uppercase">a b c ç d e f g ğ h ı i j k l m n o ö p r s ş t u ü v y z (source)</div> <div>A B C Ç D E F G Ğ H I İ J K L M N O Ö P R S Ş T U Ü V Y Z (should be like this)</div>

<script>
    function getStyle(element, style) {
        var result;

        if (document.defaultView && document.defaultView.getComputedStyle) {
            result = document.defaultView.getComputedStyle(element, '').getPropertyValue(style);
        } else if(element.currentStyle) {
            style = style.replace(/\-(\w)/g, function (strMatch, p1) {
                return p1.toUpperCase();
            });
            result = element.currentStyle[style];
        }
        return result;
    }

    function replaceRecursive(element) {
        if (element && element.style && getStyle(element, 'text-transform') == 'uppercase') {
            element.innerHTML = element.innerHTML.replace(/ı/g, 'I');
            element.innerHTML = element.innerHTML.replace(/i/g, 'İ');    // replaces 'i' in tags too, regular expression should be extended if necessary
        }

        if (!element.childNodes || element.childNodes.length == 0) return;

        for (var n in element.childNodes) {
            replaceRecursive(element.childNodes[n]);
        }
    }

    window.onload = function() {    // as appropriate 'ondomready'
        alert('before...');
        replaceRecursive(document.getElementsByTagName('body')[0]);
        alert('...after');
    }
</script>

</body>
</html>
空城之時有危險 2024-10-02 05:50:59

这是我在生产中使用的 alex 代码的增强版本:

(function($) {
  function getStyle(element, style) {
    var result;

    if (document.defaultView && document.defaultView.getComputedStyle) {
      result = document.defaultView.getComputedStyle(element, '').getPropertyValue(style);
    } else if(element.currentStyle) {
      style = style.replace(/\-(\w)/g, function (strMatch, p1) {
        return p1.toUpperCase();
      });
      result = element.currentStyle[style];
    }
    return result;
  }

  function replaceRecursive(element, lang) {
    if(element.lang) {
      lang = element.lang; // Maintain language context
    }

    if (element && element.style && getStyle(element, 'text-transform') == 'uppercase') {
      if (lang == 'tr' && element.value) {
        element.value = element.value.replace(/ı/g, 'I');
        element.value = element.value.replace(/i/g, 'İ');
      }

      for (var i = 0; i < element.childNodes.length; ++i) {
        if (lang == 'tr' && element.childNodes[i].nodeType == Node.TEXT_NODE) {
          element.childNodes[i].textContent = element.childNodes[i].textContent.replace(/ı/g, 'I');
          element.childNodes[i].textContent = element.childNodes[i].textContent.replace(/i/g, 'İ');
        } else {
          replaceRecursive(element.childNodes[i], lang);
        }
      }
    } else {
      if (!element.childNodes || element.childNodes.length == 0) return;

      for (var i = 0; i < element.childNodes.length; ++i) {
        replaceRecursive(element.childNodes[i], lang);
      }
    }
  }

  $(document).ready(function(){ replaceRecursive(document.getElementsByTagName('html')[0], ''); })
})(jQuery);

请注意,我在这里仅将 jQuery 用于 ready() 函数。 jQuery 兼容性包装器也是命名函数的便捷方法。除此之外,这两个函数根本不依赖 jQuery,因此您可以将它们拉出来。

与 alex 的原始版本相比,这个版本解决了几个问题:

  • 它在递归时跟踪 lang 属性,因为如果您混合了土耳其语和其他拉丁语内容,那么在没有它的情况下,您将在非土耳其语内容上得到不正确的转换。据此,我传入基本 html 元素,而不是 body。您可以将 lang="en" 粘贴在任何非土耳其语标签上,以防止大小写不正确。

  • 它仅将转换应用于 TEXT_NODES,因为之前的 innerHTML 方法不适用于混合文本/元素节点,例如其中包含文本和复选框的标签。

虽然与服务器端解决方案相比有一些显着的缺陷,但它也有一些主要优点,其中最主要的是保证覆盖范围,而服务器端不必知道什么样式应用于什么内容。如果任何内容正在被索引并显示在 Google 摘要中(例如),那么在提供时保持小写会更好。

Here's my enhanced version of alex's code that I am using in production:

(function($) {
  function getStyle(element, style) {
    var result;

    if (document.defaultView && document.defaultView.getComputedStyle) {
      result = document.defaultView.getComputedStyle(element, '').getPropertyValue(style);
    } else if(element.currentStyle) {
      style = style.replace(/\-(\w)/g, function (strMatch, p1) {
        return p1.toUpperCase();
      });
      result = element.currentStyle[style];
    }
    return result;
  }

  function replaceRecursive(element, lang) {
    if(element.lang) {
      lang = element.lang; // Maintain language context
    }

    if (element && element.style && getStyle(element, 'text-transform') == 'uppercase') {
      if (lang == 'tr' && element.value) {
        element.value = element.value.replace(/ı/g, 'I');
        element.value = element.value.replace(/i/g, 'İ');
      }

      for (var i = 0; i < element.childNodes.length; ++i) {
        if (lang == 'tr' && element.childNodes[i].nodeType == Node.TEXT_NODE) {
          element.childNodes[i].textContent = element.childNodes[i].textContent.replace(/ı/g, 'I');
          element.childNodes[i].textContent = element.childNodes[i].textContent.replace(/i/g, 'İ');
        } else {
          replaceRecursive(element.childNodes[i], lang);
        }
      }
    } else {
      if (!element.childNodes || element.childNodes.length == 0) return;

      for (var i = 0; i < element.childNodes.length; ++i) {
        replaceRecursive(element.childNodes[i], lang);
      }
    }
  }

  $(document).ready(function(){ replaceRecursive(document.getElementsByTagName('html')[0], ''); })
})(jQuery);

Note that I am using jQuery here only for the ready() function. The jQuery compatibility wrapper is also as a convenient way to namespace the functions. Other than that, the two functions do not rely on jQuery at all, so you could pull them out.

Compared to alex's original version this one solves a couple problems:

  • It keeps track of the lang attribute as it recurses through, since if you have mixed Turkish and other latin content you will get improper transforms on the non-Turkish without it. Pursuant to this I pass in the base html element, not the body. You can stick lang="en" on any tag that is not Turkish to prevent improper capitalization.

  • It applies the transformation only to TEXT_NODES because the previous innerHTML method did not work with mixed text/element nodes such as labels with text and checkboxes inside them.

While having some notable deficiencies compared to a server side solution, it also has some major advantages, the chief of which is guaranteed coverage without the server-side having to be aware of what styles are applied to what content. If any of the content is being indexed and shown in Google summaries (for example) it is much better if it stays lowercase when served.

猫性小仙女 2024-10-02 05:50:59

Firefox Nightly 的下一个版本(应该成为 Firefox 14)修复了这个问题,并且应该可以在不进行任何破解的情况下处理此情况(按照 CSS3 规范的要求)。

血淋淋的细节可以在该错误中找到:https://bugzilla.mozilla.org/show_bug。 cgi?id=231162

我认为他们还解决了 font-variant 的问题(对于那些不知道 font-variant 的作用的人,请参阅 https://developer.mozilla.org/en/CSS/font-variant ,尚未更新,但该文档与浏览器无关还有维基百科,所以...)

The next version of Firefox Nightly (which should become Firefox 14) has a fix for this problem and should handle the case without any hack (as the CSS3 specs request it).

The gory details are available in that bug : https://bugzilla.mozilla.org/show_bug.cgi?id=231162

They also fixed the problem for font-variant I think (For those not knowing what font-variant does, see https://developer.mozilla.org/en/CSS/font-variant , not yet up-to-date with the change but the doc is browser-agnostic and a wiki, so...)

往日情怀 2024-10-02 05:50:59

此问题的根本原因一定是所有这些浏览器中使用的 unicode 库对这些土耳其字符的处理不正确。所以我怀疑前端是否有解决这个问题的方法。

必须有人向这些 un​​icode 库的开发人员报告这个问题,并且它将在几周/几个月内修复。

The root cause of this problem must be incorrect handling of these turkish characters by unicode library used in all these browsers. So I doubt there is an front-end-side fix for that.

Someone has to report this issue to the developers of these unicode libs, and it would be fixed in few weeks/months.

虫児飞 2024-10-02 05:50:59

如果您不能依赖文本转换和浏览器,您将不得不在服务器上自己以大写形式呈现文本(希望您在用户键入文本时不要将文本大写)。
你应该在那里得到更好的国际化支持。

If you can't rely on text-transform and browsers you will have to render your text in uppercase yourself on the server (hope you're not uppercasing the text as the user types it).
You should have a better support for internationalisation there.

对你的占有欲 2024-10-02 05:50:59

此解决方法需要一些 JavaScript。如果您不想这样做,但有一些服务器端可以预处理文本,那么这个想法也可以在那里工作(我认为)。

首先,检测您是否以土耳其语运行。如果是,则扫描您要大写的任何内容,看看它是否包含有问题的字符。如果是,请将所有这些字符替换为它们的大写版本。然后应用大写 CSS。由于问题字符已经是大写,这应该是一个完全好的(贫民窟)解决方法。对于 Javascript,我设想必须处理受影响元素上的一些 .innerHTML。

如果您需要任何实现细节,请告诉我,我很清楚如何使用 Javascript 字符串操作方法在 Javascript 中执行此操作。这个总体想法应该能让你顺利完成任务(并希望能给我一份赏金!)

-Brian J. Stinar-

This work-around requires some Javascript. If you don't want to do that, but have something server side that can preprocess the text, this idea will work there too (I think).

First, detect if you are running in Turkish. If you are, then scan whatever you are going to uppercase to see if it contains the problem characters. If they do, replace all of those characters with the uppercase version of them. Then apply the uppercase CSS. Since the problem characters are already uppercase, that should be a totally fine (ghetto) work around. For Javascript, I envision having to deal with some .innerHTML on your impacted elements.

Let me know if you need any implementation details, I have a good idea of how to do this in Javascript using Javascript string manipulation methods. This general idea should get you most of the way there (and hopefully get me a bounty!)

-Brian J. Stinar-

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文