CSS:text-transform对土耳其语字符不起作用

时间:2010-09-23 10:31:03

标签: html css internationalization uppercase lang

主要浏览器的实现似乎与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

8 个答案:

答案 0 :(得分:73)

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

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

Here is working example.

答案 1 :(得分:15)

这是一个快速而肮脏的解决方法示例 - 它比我想象的要快(在带有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>

答案 2 :(得分:7)

这是我在制作中使用的增强版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方法不适用于混合文本/元素节点,例如带有文本和复选框的标签。

    < / LI>

虽然与服务器端解决方案相比存在一些明显的缺陷,但它也有一些主要优点,其主要部分是保证覆盖,而服务器端不必知道哪些样式应用于哪些内容。如果任何内容被编入索引并在Google摘要中显示(例如),则在服务时保持小写会更好。

答案 3 :(得分:4)

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,还没有更新,但文档与浏览器无关,维基,所以...)

答案 4 :(得分:0)

此问题的根本原因必须是通过所有这些浏览器中使用的unicode库错误地处理这些土耳其语字符。所以我怀疑是否有一个前端方面的解决方案。

有人必须向这些unicode库的开发人员报告此问题,并且会在几周/几个月内修复。

答案 5 :(得分:0)

如果您不能依赖文本转换和浏览器,则必须在服务器上自己以大写形式呈现文本(希望您不会在用户输入文本时对文本进行大写)。 你应该对那里的国际化有更好的支持。

答案 6 :(得分:0)

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

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

如果您需要任何实现细节,请告诉我,我很清楚如何使用Javascript字符串操作方法在Javascript中执行此操作。这个一般的想法应该让你大部分的方式(并希望得到我的赏金!)

-Brian J. Stinar -

答案 7 :(得分:-1)

您可以使用原生javascript解决此问题:

Here is also its gist.

&#13;
&#13;
String.prototype.turkishToLower = function(){
  var string = this;
  var letters = { "İ": "i", "I": "ı", "Ş": "ş", "Ğ": "ğ", "Ü": "ü", "Ö": "ö", "Ç": "ç" };
  string = string.replace(/(([İIŞĞÜÇÖ]))/g, function(letter){ return letters[letter]; })
  return string.toLowerCase();
}

String.prototype.turkishToUpper = function(){
  var string = this;
  var letters = { "i": "İ", "ş": "Ş", "ğ": "Ğ", "ü": "Ü", "ö": "Ö", "ç": "Ç", "ı": "I" };
  string = string.replace(/(([iışğüçö]))/g, function(letter){ return letters[letter]; })
  return string.toUpperCase();
}

var text = 'iii';
text = text.turkishToUpper();
console.log(text);
&#13;
&#13;
&#13;