asamuzaK.jp

IE9で(ついでにIE7、IE8でも)text-shadow

MSIE(7~9)に、CSSのtext-shadow(擬き)を適用させるJavaScriptを新たに作ってみた。
サンプル・デモ(MSIEとそれ以外のブラウザで見比べてみて下さい)

English summary also available.

jQueryプラグインっぽいのも作成。

適用方法とソース

効能
  • JavaScriptを使って、MSIEにもCSSのtext-shadowのような装飾を施します
  • JavaScript内で必要な設定は1ヶ所 { sel : 'h1', shadow : '1px 1px 1px gray' } といった具合に、CSSライクな書式としています。
    また、外部スクリプト化を前提として設計してるので、CSSと同様、1つのファイルでサイト丸ごと適用できます
  • オプションでCSSからの自動読み込みもできます(ただし、注意事項あり)
  • style属性によるインライン指定については、自動読み込みします
  • 対応セレクタは「E(要素)」「#id(ID)」「.class(クラス)」「:hover(ホバー疑似クラス)」「[attr](属性セレクタ、他に[attr=val][attr~=val][attr|=val][attr^=val][attr$=val][attr*=val]にも対応)」「E F(子孫)」「E > F(親子)」「E + F(隣接)」「E ~ F(間接)」。
  • #id.class:hover[attr]などは、CSSと同様、要素名の省略が可能です。
  • セレクタは「E.class:hover」といった具合に、ある程度自由に組み合わせて指定できます
    複数クラス(.classA.classB)や、「E > F > G」「E F + G」など多層的なセレクタにも対応
  • 複数のセレクタへのまとめ指定にも対応しています。 例えば、h1要素とh2要素へのまとめ指定の場合は { sel : 'h1, h2', shadow : '1px 1px 1px gray' }
  • 色の値は「colorname」「#nnnnnn」「#nnn」「rgb()」「rgba()」のいずれもOK(ただし、一部に制限あり)
  • 影のずらし幅やぼかし幅の値の単位は「px」のほかにも「em」「ex」「cm」「mm」「in」「pt」「pc」に対応
    また、rgb()rgba()では「%指定」もOK
  • CSSと同様、カスケードします(下に書かれた値で上書きして適用)
    また、親要素と子要素(や子孫要素)とで影を入れ子にもできます
  • CSSと同様、「ぼかし」と「」は省略可能(色を省略した場合は文字色を適用)
  • 複数のtext-shadow値もOK。CSS3での仕様通り、最初に書かれた影が1番上に適用されます
  • 影の色の濃さ(透過度)はデフォルトで0.6に設定しています。rgba()を使えば、影の濃度の調節ができます(もちろんソースのデフォルト値を書き換えることでも)
  • :hoverを使えば、マウスオーバーで影を出したり逆に影を消したり影を差し替えたりもOK(ただし、MSIE7だとなぜか反映されない)
    なお、マウスオーバーで影とともに背景を出したり逆に影と背景を消したり影と背景を差し替えたりする場合は、CSS側で影を適用しない状態でも、例えば「透明画像」を背景に敷いておくなど、ちょっとばかし工夫が必要
  • text-shadow:none;にも対応
  • !important」ルールにも対応(CSSと同様、影の値の末尾につければOK)
  • MSIE7~9で動作(たぶん)。MSIE6には適用させてません
適用方法
  • text-shadowを適用させたいセレクタと影の値をJavaScriptファイル内に、 { sel : 'セレクタ', shadow : '影の値' },
    { sel : 'セレクタ2', shadow : '影の値2' },
    { sel : 'セレクタ3', shadow : '影の値3' }
    といった形で、配列としてまとめて記述。 セレクタ、影の値ともに、「'」(引用符)で文字列の前後を括ってください。 また、配列を追加する場合は、行末のカンマを忘れずに(忘れるとエラーになります)。 最後の配列の末尾にはカンマはいりません
  • オプションでCSSからの自動読み込みもできます(ただし、注意事項あり。詳細はjQuery移植版を参照のこと)
  • ieShadowSettings()の関数内を一工夫すれば、例えばMSIEのバージョン毎の制御もできます
    var ieShadowSettings = function() {
      if(isMSIE) {
        var arr = [
          //  汎用(MSIE共通)の指定
        ];
        if(ieVersion == 7.0) {
          var lArr = [
            //  MSIE7用の入れ替え指定
          ];
          // 追加して上書きする場合は
          arr = arr.concat(lArr);
          //  そっくり丸ごと入れ替えるなんてことも
          //  arr = lArr;
        }
    	/* 以下略 */
      }
    };
    
  • HTMLから外部JavaScriptとして呼び出す。以上でOK
制限事項
  • 「(:hover以外の)疑似要素/クラス(:pseudo)」には対応していません
    また、疑似要素(::beforeなど)を当てている要素に影を適用しようとすると、影の位置がズレます
  • MSIEのバグなのか、shadow値の先頭に「#nnnnnn」(#nnn)の形で書くと影が変なところに表示されてしまいます(ので、先頭に#nnnnnnがあった場合は影の適用を除外しています。CSSからの自動読み込みの場合は補正)
  • 影を適用する要素がインライン要素の場合、display:inline-block;に変更しています。 このため、影を適用する要素の文字列が長い場合、その要素の直前で改行されて表示されたり、要素に後続する文字列が改行されることがあります。
    また、影を適用させる要素のpositionを操作(position:relative;に変更)するなど、要素のCSSを一部変更していますので、場合によっては表示が崩れる可能性があります
    スクリプトによって変更されるCSS
    プロパティ元の値変更後の値備考
    displayinlineinline-blockdisplay:blockなどはそのまま
    positionstaticrelativeposition:[absolute|fixed]はそのまま
    min-heightline-height値line-heightが指定されていた場合に適用。IE7のみ
  • パディングなどの位置計算のためにフォントサイズ(font-size)を参照しています。フォントサイズがpx以外の相対指定の場合は、基準となる絶対サイズを導き出せるまで親要素を遡っていきます。最終的にhtml要素(ルート要素)まで辿り着き、そこでもフォントサイズが「%」などで相対指定となっていた場合、基準となるサイズが取れないまま計算されてしまって影の位置がずれることがあります
  • コピー&ペーストすると影文字指定部分の文字列がダブります
  • きっとまだまだ バグがあります(爆
JavaScript(しれっと随時更新 最終更新:2012/1/11)
/*
  text-shadow for MSIE
  http://asamuzak.jp
*/

var isMSIE = /*@cc_on!@*/false;
var ieVersion = (function(reg) { return isMSIE && navigator.userAgent.match(reg) ? RegExp.$1 * 1 : null; })(/MSIE\s([0-9]+[\.0-9]*)/);

function addEvent(target, type, listener) {
  target.addEventListener ? target.addEventListener(type, listener, false) :
  target.attachEvent ? target.attachEvent('on' + type, function() { listener.call(target, window.event) }) :
  target['on' + type] = function(e) { listener.call(target, e || window.event) };
}

var cNum = (function(n) { return function() { return n++; }})(0);

function showElm(eId) {
  var elm = document.getElementById(eId);
  elm && (elm.style.visibility = 'visible');
}
function hideElm(eId) {
  var elm = document.getElementById(eId);
  elm && (elm.style.visibility = 'hidden');
}

function textShadowForMSIE(eObj) {
  var ieShadowSettings = function() {
    if(isMSIE) {
      if(eObj) {
        var arr = [];
        arr[arr.length] = eObj;
        return arr;
      }
      else {
        var sArr = [];
        //  sArr = cssShadowValues();
        //  自動的にスタイルシートからtext-shadow値を読み込みます
        //  使用したい場合は上記1行(sArr = cssShadowValues();)のコメントマークを外すこと
        //  Loads text-shadow values from stylesheets automatically.
        //  If you want to do so, strip the comment mark at the line above (sArr = cssShadowValues();).
        var arr = [
          // ここ(arr = [];内)にtext-shadowを適用させるセレクタの配列を記述
          // セレクタ毎に「カンマ区切り」で配列を追加(カンマを忘れるとエラー発生)
          // Write your text-shadow settings here, like below.
          // { sel : 'h1', shadow : '2px 2px 2px gray' },
          // { sel : 'em', shadow : '1px 1px 1px rgb(0, 100, 100) !important' }
        ];
        for(var sReg = /text\-shadow\s*:\s*([0-9a-zA-Z\s\-\+\*\&#\.\(\)%\,\!\"\\'\>\<\\]+);?/, aTag = document.getElementsByTagName('*'), oId = cNum(), i = 0, l = aTag.length; i < l; i++) {
          if(aTag[i].style != null && aTag[i].style.cssText.match(sReg)) {
            aTag[i].id == '' && (aTag[i].id = 'objId' + oId, oId++);
            arr[arr.length] = { sel : '#' + aTag[i].id, shadow : RegExp.$1 };
          }
        }
        return sArr.concat(arr);
      }
    }
    else {
      return null;
    }
  };
  var getCompStyle = function(elm, pseudo) {
    return isMSIE && ieVersion < 9 ? elm.currentStyle : pseudo != null ? document.defaultView.getComputedStyle(elm, pseudo) : document.defaultView.getComputedStyle(elm, '');
  };
  var getAncestObj = function(pElm) {
    var arr = [];
    if(pElm = pElm.parentNode) {
      for(arr[arr.length] = pElm; pElm.nodeName.toLowerCase() != 'html';) {
        (pElm = pElm.parentNode) && (arr[arr.length] = pElm);
      }
    }
    return arr;
  };
  var revArr = function(arr) {
    for(var rArr = [], i = 0, l = arr.length; i < l; i++) {
      rArr.unshift(arr[i]);
    }
    return rArr;
  };
  var setShadow = function(tObj) {
    var removeDupFunc = function(fStr) {
      for(var arr = fStr.replace(/\s+/, '').split(/;/), fArr = [], bool, i = 0, l = arr.length; i < l; i++) {
        bool = true;
        for(var j = i; j < l; j++) {
          i != j && arr[i] == arr[j] && (bool = false);
        }
        bool && arr[i] != '' && (fArr[fArr.length] = arr[i]);
      }
      return fArr.join(';') + ';';
    };
    var convUnitToPx = function(sUnit, obj) {
      var getUnitRatio = function(sUnit) {
        var elm, val, dId = cNum(), dBox = document.createElement('div'), dBody = document.getElementsByTagName('body')[0];
        dBox.id = 'dummyDiv' + dId;  dId++;
        dBox.style.width = sUnit;
        dBox.style.height = 0;
        dBox.style.visibility = 'hidden';
        dBody.appendChild(dBox);
        elm = document.getElementById(dBox.id);
        val = Math.abs(elm.getBoundingClientRect().right - elm.getBoundingClientRect().left);
        dBody.removeChild(elm);
        return val;
      };
      if(sUnit.match(/^0(em|ex|px|cm|mm|in|pt|pc)?$/)) {
        return 0;
      }
      else if(sUnit.match(/^(\-?[0-9\.]+)px$/)) {
        return RegExp.$1 * 1;
      }
      else if(sUnit.match(/^(\-?[0-9\.]+)(cm|mm|in|pt|pc)$/)) {
        return RegExp.$1 * 1 >= 0 ? getUnitRatio(sUnit) : getUnitRatio((RegExp.$1 * -1) + RegExp.$2) * -1;
      }
      else if(sUnit.match(/^(\-?[0-9\.]+)(em|ex)$/)) {
        var val = RegExp.$1 * 1 >= 0 ? (getUnitRatio(sUnit) / getUnitRatio('1em')) : (getUnitRatio(sUnit) / getUnitRatio('1em') * -1), arr = getAncestObj(obj), dRoot = document.getElementsByTagName('html')[0], fSize = [];
        arr.unshift(obj);  arr[arr.length] = dRoot;
        for(var i = 0, l = arr.length; i < l; i++) {
          fSize[fSize.length] = getCompStyle(arr[i]).fontSize;
        }
        for(i = 0, l = fSize.length; i < l; i++) {
          if(fSize[i].match(/^([0-9\.]+)%$/)) {
            val *= (RegExp.$1 / 100);
          }
          else if(fSize[i].match(/^[0-9\.]+(em|ex)$/)) {
            val *= (getUnitRatio(fSize[i]) / getUnitRatio('1em'));
          }
          else if(fSize[i].match(/^smaller$/)) {
            val /= 1.2;
          }
          else if(fSize[i].match(/^larger$/)) {
            val *= 1.2;
          }
          else if(fSize[i].match(/^([0-9\.]+)(px|cm|mm|in|pt|pc)$/)) {
            val *= getUnitRatio(fSize[i]);
            break;
          }
          else if(fSize[i].match(/^xx\-small$/)) {
            val *= (getUnitRatio(getCompStyle(dRoot).fontSize) / 1.728);
            break;
          }
          else if(fSize[i].match(/^x\-small$/)) {
            val *= (getUnitRatio(getCompStyle(dRoot).fontSize) / 1.44);
            break;
          }
          else if(fSize[i].match(/^small$/)) {
            val *= (getUnitRatio(getCompStyle(dRoot).fontSize) / 1.2);
            break;
          }
          else if(fSize[i].match(/^medium$/)){
            val *= getUnitRatio(getCompStyle(dRoot).fontSize);
            break;
          }
          else if(fSize[i].match(/^large$/)) {
            val *= (getUnitRatio(getCompStyle(dRoot).fontSize) * 1.2);
            break;
          }
          else if(fSize[i].match(/^x\-large$/)) {
            val *= (getUnitRatio(getCompStyle(dRoot).fontSize) * 1.44);
            break;
          }
          else if(fSize[i].match(/^xx\-large$/)) {
            val *= (getUnitRatio(getCompStyle(dRoot).fontSize) * 1.728);
            break;
          }
          else if(fSize[i].match(/^([0-9\.]+)([a-z]+)/)) {
            val *= getUnitRatio(fSize[i]);
            break;
          }
          else {
            break;
          }
        }
        return Math.round(val);
      }
    };
    var setShadowNodeColor = function(elm) {
      for(var arr = elm.childNodes, i = 0, l = arr.length; i < l; i++) {
        if(arr[i].nodeType == 1) {
          !arr[i].hasChildNodes() ? arr[i].style.visibility = 'hidden' : (arr[i].style.color = elm.style.color, setShadowNodeColor(arr[i]));
        }
      }
    };
    var hideAncestShadow = function(oElm, pElm) {
      for(var arr = pElm.childNodes, i = 0, l = arr.length; i < l; i++) {
        if(arr[i].hasChildNodes()) {
          arr[i].nodeName.toLowerCase() == oElm.tagName.toLowerCase() && arr[i].firstChild.nodeValue == oElm.firstChild.nodeValue ? arr[i].style.visibility = 'hidden' : hideAncestShadow(oElm, arr[i]);
        }
      }
    };
    var boolShadowChild = function(elm) {
      for(var bool = true, arr = getAncestObj(elm), i = 0, l = arr.length; i < l; i++) {
        if(arr[i].tagName.toLowerCase() == 'span' && arr[i].className.match(/dummyShadow/)) {
          bool = false;
          break;
        }
      }
      return bool;
    };
    if(tObj.shadow != 'invalid') {
      for(var arr = [], nArr = tObj.elm.childNodes, bool = false, i = 0, l = nArr.length; i < l; i++) {
        if(nArr[i].nodeName.toLowerCase() == 'span' && nArr[i].className.match(/dummyShadow/)) {
          nArr[i].className.match(/hasImp/) && (bool = true);
          arr[arr.length] = nArr[i].id;
        }
      }
      if(bool == false || tObj.hasImp == true) {
        var mOver = tObj.elm.getAttribute('onmouseover') || '';
        var mOut = tObj.elm.getAttribute('onmouseout') || '';
        mOver != '' && !mOver.match(/;$/) && (mOver += ';');
        mOut != '' && !mOut.match(/;$/) && (mOut += ';');
        for(i = 0, l = arr.length; i < l; i++) {
          if(tObj.onHover && tObj.shadow == 'none') {
            mOver += "hideElm('" + arr[i] + "');";
            mOut += "showElm('" + arr[i] + "');";
          }
          else if(!(tObj.onHover && tObj.shadow != 'none')) {
            tObj.elm.removeChild(document.getElementById(arr[i]));
          }
        }
        tObj.onHover && tObj.shadow == 'none' && (tObj.elm.setAttribute('onmouseover', mOver), tObj.elm.setAttribute('onmouseout', mOut));
        for(var aBg, arr = getAncestObj(tObj.elm), i = 0, l = arr.length; i < l; i++) {
          aBg == null && (getCompStyle(arr[i]).backgroundColor != 'transparent' || getCompStyle(arr[i]).backgroundImage != 'none') && (aBg = arr[i]);
          for(var cArr = arr[i].childNodes, j = 0, k = cArr.length; j < k; j++) {
            cArr[j].nodeType == 1 && cArr[j].nodeName.toLowerCase() == 'span' && cArr[j].className.match(/dummyShadow/) && hideAncestShadow(tObj.elm, document.getElementById(cArr[j].id));
          }
        }
        tObj.shadow != 'none' && tObj.shadow.length > 1 && (getCompStyle(tObj.elm).backgroundColor != 'transparent' || getCompStyle(tObj.elm).backgroundImage != 'none') && (tObj.shadow = revArr(tObj.shadow));
        if(tObj.shadow == 'none' && tObj.onHover == false) {
          for(var arr = tObj.elm.parentNode.childNodes, i = 0, l = arr.length; i < l; i++) {
            if(arr[i].nodeName.toLowerCase() == 'span' && arr[i].className == 'dummyShadow') {
              getCompStyle(tObj.elm).display == 'inline-block' && (tObj.elm.style.display = 'inline');
              getCompStyle(tObj.elm).position == 'relative' && (tObj.elm.style.position = 'static');
              break;
            }
          }
        }
        if(tObj.shadow != 'none' && nArr.length != 0 && boolShadowChild(tObj.elm)) {
          for(var hArr = [], clNode = tObj.elm.cloneNode(true), arr = clNode.childNodes, i = 0, l = arr.length; i < l; i++) {
            arr[i] != null && arr[i].hasChildNodes() && arr[i].nodeName.toLowerCase() == 'span' && arr[i].className.match(/dummyShadow/) && (hArr[hArr.length] = arr[i].id, clNode.removeChild(arr[i]));
          }
          var sNode = clNode.innerHTML;
          ieVersion == 9 && (sNode = sNode.replace(/\n/, ' '));
          ieVersion == 8 && (tObj.elm.innerHTML = tObj.elm.innerHTML);
          for(i = 0, l = tObj.shadow.length; i < l; i++) {
            var pxRad = convUnitToPx(tObj.shadow[i].z, tObj.elm);
            var xPos = convUnitToPx(tObj.shadow[i].x, tObj.elm) - pxRad + convUnitToPx(getCompStyle(tObj.elm).paddingLeft, tObj.elm);
            getCompStyle(tObj.elm).textAlign == 'center' && (xPos -= ((convUnitToPx(getCompStyle(tObj.elm).paddingLeft, tObj.elm) + convUnitToPx(getCompStyle(tObj.elm).paddingRight, tObj.elm)) / 2));
            var yPos = convUnitToPx(tObj.shadow[i].y, tObj.elm) - pxRad + convUnitToPx(getCompStyle(tObj.elm).paddingTop, tObj.elm);
            if(ieVersion == 7 && pxRad == 0) {
              xPos >= 0 && (xPos -= 1);
              yPos >= 0 && (yPos -= 1);
            }
            var sColor = tObj.shadow[i].cProf || getCompStyle(tObj.elm).color;
            var sOpacity = 0.6;  // デフォルトの透過度
            tObj.shadow[i].cProf != null && tObj.shadow[i].cProf.match(/rgba\(\s*([0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+)\s*,\s*([01]?[\.0-9]*)\)/) && (sColor = 'rgb(' + RegExp.$1 + ')', sOpacity = (RegExp.$2 * 1));
            var sBox = document.createElement('span');
            sBox.id = 'dummyShadow' + sId;  sId++;
            sBox.className = (tObj.hasImp == true) ? 'dummyShadow hasImp' : 'dummyShadow';
            sBox.style.display = 'block';
            sBox.style.position = 'absolute';
            sBox.style.left = xPos + 'px';
            sBox.style.top = yPos + 'px';
            sBox.style.width = '100%';
            sBox.style.color = sColor;
            sBox.style.filter = 'progid:DXImageTransform.Microsoft.Blur(PixelRadius=' + pxRad + ', MakeShadow=false, ShadowOpacity=' + sOpacity + ')';
            sBox.style.zIndex = -(i + 1);
            sBox.innerHTML = sNode;
            if(getCompStyle(tObj.elm).display == 'inline') {
              tObj.elm.style.display = 'inline-block';
            }
            if(!(getCompStyle(tObj.elm).position == 'absolute' || getCompStyle(tObj.elm).position == 'fixed')) {
              tObj.elm.style.position = 'relative';
              ieVersion == 7 && (tObj.elm.style.top = getCompStyle(tObj.elm).paddingTop);
            }
            if(getCompStyle(tObj.elm).backgroundColor != 'transparent' || getCompStyle(tObj.elm).backgroundImage != 'none') {
              getCompStyle(tObj.elm).zIndex != ('auto' || null) ? (sBox.style.zIndex = tObj.elm.style.zIndex) : (tObj.elm.style.zIndex = sBox.style.zIndex = -1);
            }
            if(aBg && aBg.tagName.toLowerCase() != 'body') {
              tObj.elm.style.zIndex = 1; sBox.style.zIndex = -1;
            }
            ieVersion == 7 && getCompStyle(tObj.elm).lineHeight.match(/^([0-9\.]+)(em|ex|px|cm|mm|in|pt|pc|%)?$/) && (tObj.elm.style.minHeight = !RegExp.$2 ? convUnitToPx(RegExp.$1 + 'em', tObj.elm) : RegExp.$2 == '%' ? convUnitToPx((RegExp.$1 / 100) + 'em', tObj.elm) : convUnitToPx(RegExp.$1 + RegExp.$2, tObj.elm));
            tObj.elm.appendChild(sBox);
            if(tObj.onHover) {
              sBox.style.visibility = 'hidden';
              mOver = tObj.elm.getAttribute('onmouseover') || '';
              mOut = tObj.elm.getAttribute('onmouseout') || '';
              mOver != '' && !mOver.match(/;$/) && (mOver += ';');
              mOut != '' && !mOut.match(/;$/) && (mOut += ';');
              mOver += ("showElm('" + sBox.id + "');");
              mOut += ("hideElm('" + sBox.id + "');");
              if(hArr.length > 0) {
                for(j = 0, k = hArr.length; j < k; j++) {
                  var hElm = document.getElementById(hArr[j]);
                  if(hElm) {
                    mOver += ("hideElm('" + hElm.id + "');");
                    mOut += ("showElm('" + hElm.id + "');");
                  }
                }
              }
              tObj.elm.setAttribute('onmouseover', removeDupFunc(mOver));
              tObj.elm.setAttribute('onmouseout', removeDupFunc(mOut));
            }
            setShadowNodeColor(document.getElementById(sBox.id));
          }
        }
      }
    }
  };
  var getTargetObj = function(sObj) {
    var arr = [];
    if(document.querySelectorAll) {
      arr = document.querySelectorAll(sObj.sel);
    }
    else {  /*  quasi querySelectorAll() for MSIE7 (Beta Version)  */
      var distinctSelector = function(obj) {
        var xObj = { elm : '*', id : [], eClass : [], pseudo : [], attr : [], rDom : [] };
        var sReg = /(([a-zA-Z\*]{1}[a-zA-Z0-9]*)|(#[a-zA-Z_]{1}[a-zA-Z0-9_\-]*)|(\.[a-zA-Z_]{1}[a-zA-Z0-9_\-]*)|(::?([a-z]{1}[a-z0-9\(\)\-]*))|(\[[a-zA-Z]{2,}.+?\]){1,})+/g;
        var sArr = obj.match(sReg);
        sArr[sArr.length - 1].match(/^([a-zA-Z\*]{1}[a-zA-Z0-9]*)/) && (xObj.elm = RegExp.$1);
        sArr[sArr.length - 1].match(/#[a-zA-Z_]{1}[a-zA-Z0-9_\-]*/) && (xObj.id = sArr[sArr.length - 1].match(/#[a-zA-Z_]{1}[a-zA-Z0-9_\-]*/g));
        for(i = 0, l = xObj.id.length; i < l; i++) {
          xObj.id[i] = xObj.id[i].replace(/#/, '');
        }
        sArr[sArr.length - 1].match(/\.[a-zA-Z_]{1}[a-zA-Z0-9_\-]*/) && (xObj.eClass = sArr[sArr.length - 1].match(/\.[a-zA-Z_]{1}[a-zA-Z0-9_\-]*/g));
        for(i = 0, l = xObj.eClass.length; i < l; i++) {
          xObj.eClass[i] = xObj.eClass[i].replace(/\./, '');
        }
        sArr[sArr.length - 1].match(/::?[a-z]{1}[a-z0-9\(\)\-]*/) && (xObj.pseudo = sArr[sArr.length - 1].match(/::?[a-z]{1}[a-z0-9\(\)\-]*/g));
        for(i = 0, l = xObj.pseudo.length; i < l; i++) {
          xObj.pseudo[i] = xObj.pseudo[i].replace(/::?/, '');
        }
        sArr[sArr.length - 1].match(/\[([a-zA-Z]{2,}.+)\]/) && (xObj.attr = xObj.attr.concat(RegExp.$1.split('][')));
        for(i = 0, l = xObj.attr.length; i < l; i++) {
          xObj.attr[i] = xObj.attr[i].replace(/^\[|\]$/g, '');
        }
        if(xObj.id.length == 0) {
          var arr = document.getElementsByTagName(xObj.elm);
          for(i = 0, l = arr.length; i < l; i++) {
            if(xObj.eClass.length > 0) {
              var bool;
              for(var j = 0, k = xObj.eClass.length; j < k; j++) {
                bool = false;
                if(arr[i].className != null) {
                  arr[i].className.match(xObj.eClass[j]) && (bool = true);
                }
                if(bool == false) { break; }
              }
              bool && (xObj.id[xObj.id.length] = arr[i].id);
            }
            else {
              xObj.id[xObj.id.length] = arr[i].id;
            }
          }
        }
        if(sArr.length > 1) {
          for(var i = 0, l = sArr.length - 1; i < l; i++) {
            var regE = new RegExp(sArr[i] + '(.+?)' + sArr[i + 1]);
            if(sObj.sel.match(regE)) {
              xObj.rDom[xObj.rDom.length] = { elm : sArr[i], type : RegExp.$1 == ' ' ? 'descend' :
                RegExp.$1.match(/\>/) ? 'child' :
                RegExp.$1.match(/\+/) ? 'adjacent' :
                RegExp.$1.match(/\~/) ? 'general' : null };
            }
          }
        }
        return xObj;
      };
      var getObj = function(xObj) {
        var compareObj = function(elm, rElm, type) {
          var getPrevSibling = function(pElm) {
            return pElm.nodeType == 1 ? pElm : (pElm = pElm.previousSibling, pElm != null ? getPrevSibling(pElm) : null);
          };
          var getGeneralObj = function(pElm) {
            var arr = [];
            for((pElm = pElm.previousSibling) && pElm.nodeType == 1 && (arr[arr.length] = pElm); pElm != null;) {
              (pElm = pElm.previousSibling) && pElm.nodeType == 1 && (arr[arr.length] = pElm);
            }
            return arr;
          };
          var bool = false;
          if(type == 'child' || type == 'descend') {
            var pElm = elm.parentNode;
            if(rElm.id == pElm.id) {
              bool = true;
            }
            else if(type == 'descend') {
              for(var arr = getAncestObj(elm.parentNode), i = 0, l = arr.length; i < l; i++) {
                if(rElm.id == arr[i].id) {
                  bool = true;
                  break;
                }
              }
            }
          }
          else if(type == 'adjacent' || type == 'general') {
            if(elm.previousSibling != null) {
              var pElm = getPrevSibling(elm.previousSibling);
              if(rElm.id == pElm.id) {
                bool = true;
              }
              else if(type == 'general' && pElm.previousSibling != null) {
                for(var arr = getGeneralObj(pElm), i = 0, l = arr.length; i < l; i++) {
                  if(rElm.id == arr[i].id) {
                    bool = true;
                    break;
                  }
                }
              }
            }
          }
          return bool;
        };
        var checkAttr = function(elm, aArr) {
          var bool = true;
          if(aArr.length > 0) {
            for(var aReg = /^([a-zA-Z]+|data\-.+)([\~\|\^\$\*]?=?)["']?([a-zA-Z0-9_\-]+)["']?$/, arr = [], i = 0, l = aArr.length; i < l; i++) {
              var obj = { attr : '', type : null, val : '' };
              if(aArr[i].match(aReg)) {
                RegExp.$1 && (obj.attr = RegExp.$1);
                RegExp.$2 == '' && RegExp.$3 && (obj.attr = RegExp.$1 + RegExp.$3);
                RegExp.$2 != '' && RegExp.$3 && (obj.type = RegExp.$2, obj.val = RegExp.$3);
              }
              if(elm.getAttributeNode(obj.attr)) {
                bool = false;
                if(elm.getAttributeNode(obj.attr).nodeValue != (null || '')) {
                  if(obj.type == null && obj.val == '') {
                    bool = true;
                  }
                  else {
                    var attArr = elm.getAttributeNode(obj.attr).nodeValue.split(' ');
                    for(var j = 0, k = attArr.length; j < k; j++) {
                      if((obj.type == '=' || obj.type == '|=') && obj.val == attArr[j]) {
                        bool = true; break;
                      }
                      else if(obj.type == '~=' && obj.val == attArr[j]) {
                        bool = true; break;
                      }
                      else if(obj.type == '|=' && attArr[j].match('^' + obj.val + '\-')) {
                        bool = true; break;
                      }
                      else if(obj.type == '^=' && attArr[j].match('^' + obj.val)) {
                        bool = true; break;
                      }
                      else if(obj.type == '$=' && attArr[j].match(obj.val + '$')) {
                        bool = true; break;
                      }
                      else if(obj.type == '*=' && attArr[j].match(obj.val)) {
                        bool = true; break;
                      }
                      else {
                        bool = false;
                      }
                    }
                  }
                }
                if(bool == false) { break; }
              }
              else {
                bool = false; break;
              }
            }
          }
          return bool;
        };
        var checkPseudo = function(elm, pArr) {
          var bool = true;
          if(pArr.length > 0) {
            bool = false;  // pseudo疑似クラス/要素には未対応(あったら全てfalse)
          }
          return bool;
        };
        var arr = [];
        if(xObj.id.length > 0) {
          for(var i = 0, l = xObj.id.length; i < l; i++) {
            var elm = document.getElementById(xObj.id[i]);
            if(elm) {
              if(xObj.rDom.length == 0) {
                checkPseudo(elm, xObj.pseudo) && checkAttr(elm, xObj.attr) && (arr[arr.length] = elm);
              }
              else if(xObj.rDom.length == 1) {
                var rObj = distinctSelector(xObj.rDom[0].elm);
                if(rObj.id.length > 0) {
                  for(var type = xObj.rDom[0].type, j = 0, k = rObj.id.length; j < k; j++) {
                    var rElm = document.getElementById(rObj.id[j]);
                    rElm && compareObj(elm, rElm, type) && checkPseudo(elm, xObj.pseudo) && checkAttr(elm, xObj.attr) && (arr[arr.length] = elm);
                  }
                }
              }
              else if(xObj.rDom.length > 1) {
                for(var j = 0, k = xObj.rDom.length - 1; j < k; j++) {
                  var rObj = distinctSelector(xObj.rDom[j + 1].elm);
                  if(rObj.id.length > 0) {
                    var yObj = { elm : rObj.elm, id : rObj.id, eClass : rObj.eClass, pseudo : rObj.pseudo, attr : rObj.attr, rDom : [{ elm : xObj.rDom[j].elm, type : xObj.rDom[j].type }] };
                    var yArr = getObj(yObj);
                    var yType = xObj.rDom[j + 1].type;
                    if(yType) {
                      for(var m = 0, n = yArr.length; m < n; m++) {
                        (j == k - 1) && compareObj(elm, yArr[m], yType) && checkPseudo(elm, xObj.pseudo) && checkAttr(elm, xObj.attr) && (arr[arr.length] = elm);
                      }
                    }
                  }
                }
              }
            }
          }
        }
        return arr;
      };
      for(var aTag = document.getElementsByTagName('*'), oId = cNum(), i = 0, l = aTag.length; i < l; i++) {
        aTag[i].id == '' && (aTag[i].id = 'tmpId' + oId, oId++);
      }
      arr = arr.concat(getObj(distinctSelector(sObj.sel)));
    }
    if(arr.length > 0) {
      for(var i = 0, l = arr.length; i < l; i++) {
        sObj.elm = arr[i];
        setShadow(sObj);
      }
    }
  };
  var getShadowValue = function(shadow) {
    var convPercentTo256 = function(cProf) {
      if(cProf.match(/(rgba?)\(\s*([0-9\.]+%?\s*,\s*[0-9\.]+%?\s*,\s*[0-9\.]+%?)\s*(,\s*[01]?[\.0-9]*)?\s*\)/)) {
        for(var cType = RegExp.$1, arr = RegExp.$2.split(/,/), aCh = (RegExp.$3 || ''), rgbArr = [], i = 0, l = arr.length; i < l; i++) {
          arr[i].match(/([0-9\.]+)%/) && (arr[i] = Math.round(RegExp.$1 * 255 / 100));
          rgbArr[rgbArr.length] = arr[i];
        }
        return cType + '(' + rgbArr.join(',') + aCh + ')';
      }
    };
    if(shadow.match(/none/)) {
      return 'none';
    }
    else {
      for(var val = [], arr = shadow.match(/((rgba?\(\s*[0-9\.]+%?\s*,\s*[0-9\.]+%?\s*,\s*[0-9\.]+%?\s*(,\s*[01]?[\.0-9]*\s*)?\)|#[0-9a-fA-F]{3,6}|[a-zA-Z]+)\s)?(\-?[0-9\.]+(em|ex|px|cm|mm|in|pt|pc)?\s*){2,3}(rgba?\(\s*[0-9\.]+%?\s*,\s*[0-9\.]+%?\s*,\s*[0-9\.]+%?\s*(,\s*[01]?[\.0-9]*\s*)?\)|#[0-9a-fA-F]{3,6}|[a-zA-Z]+)?/g), i = 0, l = arr.length; i < l; i++) {
        val[i] = { x : '0', y : '0', z : '0', cProf : null };
        var uArr = arr[i].match(/\-?[0-9\.]+(em|ex|px|cm|mm|in|pt|pc)?\s+\-?[0-9\.]+(em|ex|px|cm|mm|in|pt|pc)?(\s+[0-9\.]+(em|ex|px|cm|mm|in|pt|pc)?)?/);
        if(uArr = uArr[0].split(/\s+/), uArr[0].match(/^(\-?[0-9\.]+(em|ex|px|cm|mm|in|pt|pc)?)$/) && uArr[1].match(/^(\-?[0-9\.]+(em|ex|px|cm|mm|in|pt|pc)?)$/)) {
          uArr.length >= 2 && (val[i].x = uArr[0], val[i].y = uArr[1]);
          uArr.length == 3 && uArr[2].match(/^([0-9\.]+(em|ex|px|cm|mm|in|pt|pc)?)$/) && (val[i].z = uArr[2]);
          arr[i].match(/%/) && (arr[i] = convPercentTo256(arr[i]));
          arr[i].match(/^(rgba?\(\s*[0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+\s*(,\s*[01]?[\.0-9]*\s*)?\)|[a-zA-Z]+)/) ? (val[i].cProf = RegExp.$1) :
          arr[i].match(/\s(rgba?\(\s*[0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+\s*(,\s*[01]?[\.0-9]*\s*)?\)|#[0-9a-fA-F]{3,6}|[a-zA-Z]+)$/) && (val[i].cProf = RegExp.$1);
        }
        else {
          val = 'invalid';
          break;
        }
      }
      return val;
    }
  };
  var cssShadowValues = function() {
    var getCssValues = function(prop) {
      var sReg = prop.match(/(\-)/) ? prop.replace(RegExp.$1, '\\\-') : prop;
      sReg += '\\s*:\\s*([0-9a-zA-Z\\s\\-\\+\\*\\\&#\\.\\(\\)%\\,\\!\\"\\\'\\>\\<\\\\]+);?';
      var getCssRules = function(sSheet) {
        for(var arr = [], sRules = sSheet.cssRules || sSheet.rules, i = 0, l = sRules.length; i < l; i++) {
          if(sRules[i].type) {
            sRules[i].type == 3 && (arr = arr.concat(getCssRules(sRules[i].styleSheet)));
            if(sRules[i].type == 4) {
              /*
              * matchMedia() polyfill - test whether a CSS media type or media query applies
              * authors: Scott Jehl, Paul Irish, Nicholas Zakas
              * Copyright (c) 2011 Scott, Paul and Nicholas.
              * Dual MIT/BSD license
              * Original Source matchMedia.js https://github.com/paulirish/matchMedia.js
              * Revised by Kazz http://asamuzak.jp
              */
              window.matchMedia = window.matchMedia || (function() {
                return function(q) {
                  var bool,
                    dHead = document.getElementsByTagName('head')[0],
                    dBody = document.getElementsByTagName('body')[0],
                    dStyle = document.createElement('style'),
                    dDiv = document.createElement('div'),
                    dId = cNum();
                  dDiv.id = 'dDiv' + dId;  dId++;
                  dDiv.style.cssText = 'margin:0;border:0;padding:0;height:0;visibility:hidden;';
                  dHead.appendChild(dStyle);
                  dBody.appendChild(dDiv);
                  dStyle.setAttribute('media', q);
                  dStyle.innerHTML = '#' + dDiv.id + '{ width:42px; }';
                  bool = dDiv.offsetWidth == 42;
                  dBody.removeChild(dDiv);
                  dHead.removeChild(dStyle);
                  return { matches: bool, media: q };
                };
              })();
              /* end matchMedia.js */
              window.matchMedia(sRules[i].media.mediaText).matches && (arr = arr.concat(getCssRules(sRules[i])));
            }
            sRules[i].type == 1 && sRules[i].style.cssText.match(sReg) && (arr[arr.length] = { sel : sRules[i].selectorText, prop : prop, val : RegExp.$1 });
          }
          else {
            var sText = sRules[i].style.cssText || sRules[i].cssText;
            if(sText) {
              sText.match(sReg) && (arr[arr.length] = { sel : sRules[i].selectorText, prop : prop, val : RegExp.$1 });
            }
          }
        }
        return arr;
      };
      if(document.styleSheets) {
        for(var arr = [], sArr = document.styleSheets, i = 0, l = sArr.length; i < l; i++) {
          if(isMSIE && ieVersion < 9 && sArr[i].imports) {
            for(var iArr = sArr[i].imports, j = 0, k = iArr.length; j < k; j++) {
              iArr[j] != undefined && (arr = arr.concat(getCssRules(iArr[j])));
            }
          }
          arr = arr.concat(getCssRules(sArr[i]));
        }
      }
      for(var aTag = document.getElementsByTagName('*'), oId = cNum(), i = 0, l = aTag.length; i < l; i++) {
        if(aTag[i].style != null && aTag[i].style.cssText.match(sReg)) {
          aTag[i].id == '' && (aTag[i].id = 'objId' + oId, oId++);
          arr[arr.length] = { sel : '#' + aTag[i].id, prop : prop, val : RegExp.$1 };
        }
      }
      return arr;
    };
    for(var arr = [], sArr = getCssValues('text-shadow'), revReg = /^(#[0-9a-fA-F]{3,6})\s+([0-9a-zA-Z\s\-\.\(\)%\,\!]+)$/, i = 0, l = sArr.length; i < l; i++) {
      arr[arr.length] = { sel : sArr[i].sel, shadow : sArr[i].val.match(revReg) ? RegExp.$2 + ' ' + RegExp.$1 : sArr[i].val };
    }
    return arr;
  };
  var cascadeSel = function(arr) {
    for(var sArr = [], bool, i = 0, l = arr.length; i < l; i++) {
      bool = true;
      for(var j = i; j < l; j++) {
        i != j && arr[i].sel == arr[j].sel && !arr[i].shadow.match(/important/) && (bool = false);
      }
      bool && (sArr[sArr.length] = arr[i]);
    }
    return sArr;
  };
  for(var arr = cascadeSel(ieShadowSettings()), sId = cNum(), i = 0, l = arr.length; i < l; i++) {
    for(var sSel = arr[i].sel.split(/,/), sReg = /^\s*([a-zA-Z0-9#\.:_\-\s>\+~]+)\s*$/, j = 0, k = sSel.length; j < k; j++) {
      sSel[j].match(sReg) && (sSel[j] = RegExp.$1);
      var sObj = { sel : sSel[j], shadow : getShadowValue(arr[i].shadow), hasImp : arr[i].shadow.match(/\s*\!\s*important/) ? true : false, onHover : sSel[j].match(/:hover/) ? true : false };
      sObj.onHover && (sObj.sel = sObj.sel.replace(/:hover/, ''));
      getTargetObj(sObj);
    }
  }
}
addEvent(window, 'load', function() {
  ieVersion >= 7 && ieVersion <= 9 && textShadowForMSIE();
  /* Sample to change shadow color at interactive events (eg: onclick) */
  /*
  var eObj = { sel : '#someId', shadow : 'green 2px 2px 2px !important' };
  var elm = document.getElementById(eObj.sel.replace('#', ''));
  elm && addEvent(elm, 'click', function() {
    if(ieVersion >= 7 && ieVersion <= 9) {
      textShadowForMSIE(eObj);
    }
    else if(ieVersion > 9 || !isMSIE) {
      eObj.shadow.match(/(\s*\!\s*important)/) ?
      elm.style.setProperty('text-shadow', eObj.shadow.replace(RegExp.$1, ''), 'important') :
      elm.style.setProperty('text-shadow', eObj.shadow, '');
    }
  });
  */
});

"IE9で(ついでにIE7、IE8でも)text-shadow"へのTwitter上でのコメントやRT

10件のツイートがあります。Topsyで確認する

IE9で(ついでにIE7、IE8でも)text-shadow http://asamuzak.jp/html/321

ってことで、text-shadow for MSIE で何もせずとも1つバグフィクスできたw http://t.co/uWLlHGCJ

My answer http://t.co/4Hy0fMLJ RT @rawfysh: @zoltandulac Hi Zoltan, I just submitted another issue because text-shadow isn't working on IE8.

お役立ち!めもめも asamuzaK.jp : IE9で(ついでにIE7、IE8でも)text-shadow http://t.co/CS16Qj4A @asamuzakjpさんから

text-shadow for MSIE。イベントハンドラのサンプルをいい加減に書いてたら、!importantがあったら適用されないことを発見。ムキになって修正w http://t.co/uWLlHGCJ http://t.co/aYXFVuCe via @asamuzakjp

しっかし、些か強引とはいえ、基本的に仕様に即したコードを書いてるつもりなのに、それで墜ちるとはさすがIE… ってことで、疑似要素に関して注意書きはしておいたが、バグはしばらく放置決定w http://t.co/uWLlHGCJ

text-shadow for MSIEの擬似要素絡みのバグ。insertRuleで動的に影要素のCSSを生成してるのがいけないの鴨と、あらかじめCSSに記述して追試。結果はやはりハングorz しかしIE7は桶。もうわけわからんw http://t.co/uWLlHGCJ

JSですけど試しにどうぞ http://t.co/uWLlHGCJ RT @lufnif: cssって使わないとどんどん忘れるわ。IEでサポートしてないtext-shadowを使いたい。でもjsは使いたくない。。。

試しにどうぞ http://t.co/uWLlHGCJ RT @dance00_blog: CSS3 テキストシャドウ(text-shadow)はIE9では使えなかった http://t.co/dEuk06zn

どうぞ http://t.co/uWLlHGCJ RT @_myake: IEにもtext-shadow使わせてよー もー IEだけちょっと文字読みづらいけど、それはIE以外のブラウザへの誘導作戦なのだよ!

"IE9で(ついでにIE7、IE8でも)text-shadow"へのコメント

23 件のコメントが寄せられています。 コメントを投稿する

This is great work! Thanks for publishing this. I will be playing around with it for the next little while. What license is it distributed under?

It's free.
Just, please don't remove the commented lines at the top (link to my web).
/*
text-shadow for MSIE
http://asamuzak.jp
*/

if its not working for you,
lets say you using a background image and you have on it.
try to add z-index:2; on tag.

i have some problems on ie7. Shadow positions are wrong, they need to close 1px more :-/ How can i fix that? or what can problem on that?

Ünsal :
Thanks for testing.
Is there a link or a test case that can reproduce the problem?

I'm not sure by now, but in the middle of making this script, I remember that IE7 had that kind of problem.
IE7 rendered shadow position differently in cases below.
*Case which only one font size is used. (the problem occurred in this case, I think)
*Case if any element has another font size there.

So, what happens if you add some elements with different font sizes (eg: <small>, <span style="font-size:larger"> etc.) in the case which you are testing?

今、会社のPCで試しに表示させてみたら、MSIE8で入れ子部分以降が盛大にずれまくっていたのを発見orz
IE9の開発者ツールでのブラウザモードって、まんまIE8とは違うの?

IE8で見つかった入れ子時のバグへの対処を施してみた
自宅にあった古いPCのIE8で確認した限りはOKっぽいし、
ケガの功名(?)でIE7のバグもついでに解消できたっぽいが
自信ナシw

I've updated the script now.
Some IE8 and IE7 bugs maybe fixed, but not so sure :p

ok i created a test page for you
http://kremim.com/test.html
I will soon open site, i hope we can fix this because i want shadow for my ie7 visitors :P
You are first person see this site before open ^^


Still ie7 is problem. Esspecially those shadows:
.item h3
.static2_desc p

Ünsal :
I can't figure out why by now.
Give me some time.
But until then, try this.

var ieShadowSettings = function() {
if(isMSIE) {
var arr = [
{ sel : '.item h3', shadow : '1px 1px 1px #A9A9A9'},
{ sel : '.item-content span.tag', shadow : '1px 1px 1px #131212'},
{ sel : '.intro_fullwidth h1', shadow : '1px 2px 2px rgba(0,0,0,0.8)'},
{ sel : '.page_meta_box p', shadow : '1px 1px 1px rgba(0,0,0,0.4)'},
{ sel : '#footer a, #footer_bottom_wrapper a', shadow : '1px 1px 1px rgba(0, 0, 0, 0.8)'},
{ sel : '#footer h3', shadow : '1px 2px 2px rgba(0, 0, 0, 0.8)'},
{ sel : '.static2_desc p', shadow : '1px 1px 1px rgba(0,0,0,0.4)'}
];
if(ieVersion == 7) {
var lArr = [
{ sel : '.item h3', shadow : '0px 0px 1px #A9A9A9'},
{ sel : '.static2_desc p', shadow : '0px 0px 1px rgba(0,0,0,0.4)'}
];
for(var i = 0, l = lArr.length; i < l; i++) {
arr[arr.length] = lArr[i];
}
}
return arr;
}
else {
return null;
}
};

I figured out what causes the shadow length's gap in IE7.
It was line-height.
I think I have fixed the bug.

oh well yes shadows works but now it removes all height from element :-/ an example: http://kremim.com/ie7.jpg

(ps i updated then reverted back)

Fixed the script.
It was a simple mistake.
Now, setting min-height, so it won't affect element's height anymore.
How about it ?

Awesome!!
http://kremim.com is opened and using your code now. You can use it as your example site if you want. Thanks a lot for your awesome work :)

ドツボりながらも久々に更新

変更点
*text-align : center が適用されつつ、左右のpaddingが異なる場合に影の位置がズレるバグを修正
*インラインのstyle属性での指定に関しては自動的にtext-shadowの値を読み込むようにした

Updated the script.
*Bug fix. Recalculate shadow's x-position when "text-align : center;" is set.
*Inline style attribute (eg: style="text-shadow : 1px 1px 1px orange;") will be loaded automatically.

文字列のダブりを解消するために、clipboardDataをgetして
…とか一瞬妄想したけど、それじゃスパイウェアだわなw
やめやめ!!

About
#1: Can't get it working in IE7-8 - Issues - zoltan-dulac/cssSandpaper - GitHub
https://github.com/zoltan-dulac/cssSandpaper/issues/1

I don't have a GitHub account, so I'll write my suggestion here.

Aren't you using 'rem' or other new CSS3 units in font-size (or padding)?
IE8 nor 7 can't handle new CSS3 units.
Set your stylesheet like below, and maybe it'll work.

E {
font-size : 16px; /* for IE8 or 7 */
font-size : 1rem;
}

スクリプトを更新
onclickイベントなどでも影の色などを変更できるように微修正
IE7の:hover時のバグもこれで直せるな
…まだやってないけどw

Updated the script.
Now you can handle shadows at interactive events (eg: onclick).

大幅に書き直して、これまでにあった制限事項をほぼ解消した。
これで、スタンドアローンでも機能的にjQuery版と同等になった…かな

今回の更新では、document.querySelectorAll()を使うことにしたので、これによってこれまでのスクリプトにあった制限事項はほぼ解消された。
しかし、IE7がdocument.querySelectorAll()には未対応なので、それに相当するスクリプトをほとんど1から書き起こすという羽目になった。…これが疲れた
属性セレクタや疑似要素/クラスへの対応は今回は見送り。
IE7の:hover時のバグも引き続き放置プレイw

スクリプト更新。
属性セレクタに対応させた

Updated the script.
Now you can use [attr] selectors.

バグ・メモ

影を適用しようとする要素に、::before, ::first-letter, ::first-lineなど、疑似要素のスタイル付けが指定されている場合に、影の位置がずれる

E {
text-shadow : 1px 1px 1px red;
}
E::before {
margin : 1em;
padding : 1em;
content : 'foo';
}

対処案:
CSSを読み込んで、疑似要素の指定を別途保持しておく?

コメント投稿フォーム

名前、メールアドレス、URIはいずれも任意です。 コメントは承認後に公開されます(承認されない場合もあります)。 なお、メールアドレスは公開されません。

情報の保存

"IE9で(ついでにIE7、IE8でも)text-shadow"へのトラックバック

6 件のトラックバックが寄せられています。

IE8でもtext-shadow [asamuzaK.jp]
MSIE8でSafariとかFirefoxとかOperaのtext-shadow風な装飾効果を実現
CSS text-shadow in IE9 (and also IE7 & 8) [asamuzaK.jp]
JavaScript library to apply CSS3 text-shadow like effect in MSIE
IE9でtext-shadowの続き・・・ [虚弱だけど健康生活ブログ]
前回、チャレンジしていた IE9でtext-shadowを使う方法を模索中 ですが、 なんと、asamuzaK.jp の管理者さま自らコメントをいただきま...
IE9で(ついでにIE7、IE8でも)text-shadow (jQuery移植版) [asamuzaK.jp]
text-shadow for MSIE のjQueryプラグインっぽい移植版
IEでもtext-shadowを使いたい! [Web no Sirabe]
このサイトではウィジェットタイトルなどにCSS3のtext-shadowが使われています。文字に影をつけてくれる便利なものです。しかし、IEには対応してな...
text-shadow for MSIE を更新 [asamuzaK.jp]
text-shadow for MSIE を久々に更新したが、そのときにドツボったメモ

この記事にトラックバックするには、http://asamuzak.jp/cgi-bin/mt/mt-trackbacks-mmxii.cgi/339までpingを送信してください。 トラックバック送信元にこの記事への言及(リンク)がない場合は受け付けない設定にしています。