Archive for ‘ 十二月, 2009

给新手的20条Email设计最佳实践与资源(译文)

最近接了个新工作需要制作HTML电子邮件模板。一直以来对电邮推广的认识之存在于概念中。虽然身为设计人员,不过让我挑选的话,我会选择纯文本的电邮方式,直接明了,人人看得懂,不必顾虑各邮件服务器对html的兼容性。不过对于电子商务类的推广,一封设计美观的电邮想必能够勾起更大的消费欲望。

在网上搜索了一下,发现这方面的E文资料挺多的。比如这篇《20 Email Design Best Practices and Resources for Beginners》就不错!时间有限,纯意译,翻译只为记要点以备学习积累之用。

原文地址:http://net.tutsplus.com/tutorials/html-css-techniques/20-email-design-best-practices-and-resources-for-beginners/

即使对于经验老道的设计者来说,要设计制作一封电邮也不是容易的事。当你接到一个漂亮的设计稿,要将它制作成电邮可能会遇到各种问题:比如样式无法被渲染,图片不可见,等等。

原则一:保持简洁

电邮的设计与网站设计有所不同,既要设计得美观,又要恰如其分。所以试着以一个基础而美观的图片为邮件的头部,紧接着是邮件的正文,这样不失为一种较好的组织形式。

越是干净的设计,编码就越简单,从而也避免了许多由于浏览器和邮件客户端解析而引起的怪异问题。

mail1

原则二:使用TABLE

多数邮件客户端建立得较早,所以所有电邮的布局最好都采用TABLE来完成。当然有一些CSS样式是可以使用的,这一点在后文会继续讨论。

不建议采用的代码:

<div id="header"> 
    <h4>Header 1</h4> 
</div> 
<div id="content"> 
    Lorem ipsum dolor sit amet.  
</div>f  
<div id="footer"> 
    Sign off and footer  
</div>

推荐的方式:


<table> 
    <tr> 
        <td>Header 1</td> 
    </tr> 
    <tr> 
        <td>Lorem ipsum dolor sit amet.</td> 
    </tr> 
    <tr> 
        <td>Sign off and footer</td> 
    </tr> 
</table>

原则三:在多种浏览器下进行预览

尽可能多的使用各种浏览器来测试,毕竟,天知道谁将看到你的电邮,而他又是使用什么浏览器呢?

请至少使用以下浏览器测试预览:

  • Internet Explorer 6
  • Internet Explorer 7
  • Internet Explorer 8
  • Mozilla Firefox 3
  • Apple Safari 3
  • Google Chrome
  • 原则四:注册多个邮件服务提供商

    越多越好。(对于偶这种一年设计一两封的人就不必了)。以下是推荐注册的(推荐的是E文的):

  • Google Mail (http://mail.google.com)
  • Hotmail/Live Mail (http://www.hotmail.com)
  • Yahoo Mail (http://mail.yahoo.com)
  • AOL Mail (http://webmail.aol.com)
  • 原则五:使用内联样式

    对于网页设计来说,想必所有靠谱的设计师都会弃用内联样式。但是在电邮的世界里,邮件客户端很可能会强行扒掉你的CSS钩子,所以如果必须使用样式的话,请内联之。

    原则六:给所有img标签一个alt属性

    这是非常重要又经常被忽略的一步。为图片所在的td标签定义一些比较美观的文本样式,如字体、大小、颜色等。这样一旦图片无法加载,文字说明就会代替之。

    没有alt的情况:

    mail2

    有alt的情况:

    mail3

    原则七:不要为图片设定宽高。

    这是出于柔性减弱的用户体验考虑。设想假如图片无法显示而你又设定了固定的宽高,那么邮件会出现大量不必要的空白。

    原则八:将电邮放在width:100%的table里。

    邮件客户端通常会将你的代码放进一个body标签里,而不是你原来的那个body标签,所以,假设你要使用背景色的话,就应该设定一个宽度100%的TABLE,用TABLE的背景色来将原来的背景色覆盖掉。

    
    <table width="100%"> 
        <tr> 
            <td> 
                <table width="600" align="center"> 
                    <tr> 
                        <td>Lorem ipsum dolor sit amet.</td> 
                    </tr> 
                </table> 
            </td> 
        </tr> 
    </table>
    

    原则九:不要大于600px

    事实上多数用户几乎不打开电邮正文,而是在预览框里查看。平均计算预览框最小的宽度在600px左右。所以尽量按照这个宽度去设计,除非你不希望用户能够看到电邮的全貌。

    原则十:为超链接定义样式

    别忘记为超链接重新定义样式以覆盖邮件客户端默认的链接外观。

    <a href="#" style="color:#000000; text-decoration:none;">Link</a>
    

    原则十一:尽量不要嵌套TABLE

    除了最外层的100%宽度TABLE,尽量不要在内部多层嵌套表格。只要使用堆列的方式,就可以轻易避免这么做。

    不要这么写:

    
    <table> 
        <tr> 
            <td> 
                <table> 
                    <tr> 
                        <td>Lorem ipsum dolor sit amet.</td> 
                    </tr> 
                </table> 
            </td> 
        </tr> 
        <tr> 
            <td> 
                <table> 
                    <tr> 
                        <td>Lorem ipsum dolor sit amet.</td>
                    </tr>
                </table> 
            </td> 
        </tr> 
    </table>
    

    你可以这样:

    
    <table> 
        <tr> 
            <td>Lorem ipsum dolor sit amet.</td> 
        </tr> 
    </table> 
    <table> 
        <tr> 
            <td>Lorem ipsum dolor sit amet.</td> 
        </tr> 
    </table>
    

    原则十二:不要使用背景图片

    对文本尽量使用实色背景,只有在没有文本的区域才使用渐变色、图片等作为背景。

    原则十三:边框(border)失效

    边框在邮件客户端兼容得不好。可以采用1px宽度的td来代替(回到原始时代)。

    不起作用:

    <td width="600" style="border-right:1px solid #000000; border-left:1px solid #000000;">Lorem ipsum</td>
    

    起作用:

    
    <td width="1"></td> 
    <td width="598">Lorem ipsum dolor sit amet.</td> 
    <td width="1"></td>
    

    原则十四:HOTMAIL的BUG修复

    过去几年微软一直致力于对hotmail服务的升级,但是却又一个奇怪的bug一直未被修复,那就是图片周围会毫无缘由的多出一些补白(padding)。如何解决这个问题?

    <img src="image.jpg" style="display:block;">
    

    是的,为每个img标签添加display:block的样式。

    原则十五:对所有字符使用编码方式

    不是必须,但是推荐这么做。如:

    "Some sample code - with special characters"
    

    写成:

    &quot;Some sample code &#45; with special characters&quot;
    

    原则十六:JavaScript = 垃圾邮件

    使用JavaScript的电邮会被邮件客户端认为是垃圾邮件而直接扔进垃圾箱。所以,最好保持干净古老的HTML代码。

    原则十七:给用户一个后门

    尽管你的电邮设计十分精美,但不可避免的有些用户可能并不希望收到它们。所以,留给你的用户退订它们的方式。

    原则十八:用户需要多种选择

    有些用户或许是使用手机终端等较为基础的服务在接收和阅读电邮,所以,他们也许看不到电邮中那些漂亮的图片。所以,记住在邮件头部保留一个链接指向电邮所在的网址以便他们能够阅读。

    原则十九:使用space.gif

    一些浏览器(其实就是IE啦)不支持没有内容的td,即使你给它10个像素的宽度也没用。所以如果你想在布局中留一些空隙,只能在td中使用透明图片。

    原则二十:多做测试

    自己给自己在各种邮件客户端多发邮件做测试,这是至关重要的。

    其他有用的资源:

  • http://www.shayhowe.com/resource/smart-email-marketing/
  • http://www.webdesignerdepot.com/2009/11/a-guide-to-creating-email-newsletters/
  • http://www.smartbiz.com/article/articleview/2073/1/53/
  • http://www.smartbiz.com/article/view/2076/1/53
  • http://www.kamikazemusic.com/quick-tips/basics-html-email-newsletters/
  • http://www.mailchimp.com/articles/email_marketing_subject_line_comparison/
  • http://lyrishq.lyris.com/index.php/Email-Marketing/Email-Subject-Lines-15-Rules-to-Write-Them-Right.html
  • http://net.tutsplus.com/misc/6-easy-ways-to-improve-your-html-emails/
  • http://www.copyblogger.com/persuasive-writing/
  • 电邮设计参考:

  • Campaign Monitor Gallery
  • Beautiful Email Newsletters
  • HTML Email Gallery
  • 服务:

  • Mail Chimp
  • Campaign Monitor
  • Emma Email Marketing
  • AWeber
  • Interspace SendStudio
  • Feel Breeze
  • 设计工具:

  • LitmusApp
  • Preview My Email
  • 电邮模板:

    ThemeForest Email Templates

    一篇国内较好的文章:电子邮件制作规范和建议

    习作:

    mail3

    一个有趣的浮动测试

    CSS 允许任何元素浮动,不管是图像、段落还是列表。但这并非没有代价:浮动元素引入了自身的特殊性。浮动元素在决定决定文档流方面有不同之处。例如,由其他元素生成的框按浮动元素不存在绘制,但这些元素内容的绘制则必须把浮动元素考虑在内。这就影响了元素框的生成,意味着浮动对这些框存在着间接影响。
     —— 《CSS权威指南》

    浮动元素对其相邻块级元素影响,做一个小测试:

    当元素A浮动且有固定宽度,元素B不浮动且有固定宽度时,IE浏览器各版本的表现:

    情况一:元素A浮动且有固定宽度,元素B不浮动且有固定宽度,IE浏览器各版本的表现。

    代码:

    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns=<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>>
    <head>
    <link href="css/global.css" rel="stylesheet" type="text/css">
    <title>XHTML-test</title>
    <style type="text/css">
    #left {
     float:left;
     width:200px;
     height:100px;
     background:red;
     }
    #right {
    width:200px;
    height:100px;
     background:blue;
     }
    </style>
    </head>
    <body>
      <div id="left">元素A</div>
      <div id="right">元素B</div>
    </body>
    </html>
    

    IE6的表现:有个可爱的3px bug,其他表现如我们所期望的。

    ie6

    IE7的表现:似乎符合我们的期望值。

    ie7

    IE8和火狐的表现:虽然在外观上怪异,但实际上按照《权威指南》的说法,这才是浏览器所应有的表现。元素B的框按浮动元素A不存在的情形来绘制,用工具就可以发现,元素B的框其实和元素A的框重叠,并且由于它们等宽,所有元素B的框被浮动元素A的框覆盖掉了。而元素B的内容则由于受到元素A的影响,而被推到了下方。

    ie8

    现在稍微修改一下CSS,使元素B的宽度大于元素A的宽度。

    
    #left {
     float:left;
     width:200px;
     height:100px;
     background:red;
     }
    #right {
    width:300px;/*元素B的宽度比A多出100px*/
    height:100px;
     background:blue;
     }
    

    IE6和IE7的表现与上类似,IE8和火狐的新表现。可以看到,此时被覆盖的元素B有部分背景色露出来:

    ie8-2

    情况二:元素A浮动且有固定宽度,元素B不浮动不设宽度,IE浏览器各版本的表现。

    其他不变,修改上面的CSS:

    
    #left {
     float:left;
     width:200px;
     height:100px;
     background:red;
     }
    #right {
     height:100px;
     background:pink;
     }
    

    IE6:元素B延伸至页面右侧尽头,3px bug风雨无阻。

    ie6-1

    IE7:元素B延伸至页面右侧尽头,元素B为蓝色边框所标示范围。

    ie7-1

    IE8和火狐:元素B延伸至页面右侧尽头,元素B为蓝色边框所标示范围。

    ie8-1

    由上可见,在这种情况下,虽然视觉效果各浏览器得到了基本一致的效果,但是在对元素B的范围界定上,实则有本质的区别。

    情况三:元素A浮动且有固定宽度,元素B不浮动不设宽度,给元素A添加右边距。为测试效果,将文字左对齐。

    修改CSS:

    
    #left {
     float:left;
     width:200px;
     height:100px;
     background:red;
     margin-right:10px;
     }
    #right {
     height:100px;
     background:pink;
     }
    

    IE6的表现:3px+10px右边距诞生

    ie6-2

    IE7的表现:10px右边距

    ie7-2

    IE8和火狐的表现:注意元素B的背景和文字位置。可见浮动元素A对其相邻的块级元素B及其子元素(如文本节点或内联元素)的影响是有所不同的。

    ie8-3

    情况四:元素A浮动且有固定宽度,元素B不浮动不设宽度,给元素B添加左边距。为测试效果,将文字左对齐。

    
    #left {
     float:left;
     width:200px;
     height:100px;
     background:red;
    
     }
    #right {
     height:100px;
     background:pink;
     margin-left:10px;
     }
    

    可以看到在视觉上所有浏览器都几乎不产生任何效果。但是在IE8和火狐中,其实margin已经生效,只是为元素A所覆盖,无法看到效果,对子元素(文字或内联元素)也不产生任何影响。注意下图蓝色边框对元素B的标示。

    ie8-4

    总结:如果要实现类似下图的布局

    sample

    采取左右元素均浮动是比较保险且好控制的方法。如果只想浮动左侧,则右侧元素最好不要固定宽度,让宽度自适应,边距尽量在左边的元素上定义,这样可以尽可能的保证浏览器显示一致。

    深入理解JavaScript的变量作用域[转]

    晚上没事看了看《ActionScript3.0基础教程》。以前一直认为ActionScript和Javascript师出同门,应该是极为相似的,不过看了一下还是有些区别的。比如ActionScript是可以严格控制数据类型的,并且函数作用域相比Javascript来说更为明晰。限于本人是这两种语言的超级菜鸟,顺便goole了一篇很不错的关于JavaScript变量作用域的文章,备忘。

    原文地址:http://www.cnblogs.com/rainman/archive/2009/04/28/1445687.html

    在学习JavaScript的变量作用域之前,我们应当明确几点:

    a、JavaScript的变量作用域是基于其特有的作用域链的。
    b、JavaScript没有块级作用域。
    c、函数中声明的变量在整个函数中都有定义。

    1、JavaScript的作用域链

    首先看下下面这段代码:

    
    <script type="text/javascript" language="javascript">
    
    var rain = 1;
    function rainman(){
        var man = 2;
        function inner(){
            var innerVar = 4;
            alert(rain);
        }
        inner();    //调用inner函数
    }
    rainman();    //调用rainman函数
    
    </script>
    

    观察alert(rain);这句代码。JavaScript首先在inner函数中查找是否定义了变量rain,如果定义了则使用inner函数中的rain变量;如果inner函数中没有定义rain变量,JavaScript则会继续在rainman函数中查找是否定义了rain变量,在这段代码中rainman函数体内没有定义rain变量,则JavaScript引擎会继续向上(全局对象)查找是否定义了rain;在全局对象中我们定义了rain = 1,因此最终结果会弹出’1′。

    作用域链:JavaScript需要查询一个变量x时,首先会查找作用域链的第一个对象,如果以第一个对象没有定义x变量,JavaScript会继续查找有没有定义x变量,如果第二个对象没有定义则会继续查找,以此类推。

    上面的代码涉及到了三个作用域链对象,依次是:inner、rainman、window。

    2、函数体内部,局部变量的优先级比同名的全局变量高。

    
    <script type="text/javascript" language="javascript">
    
    var rain = 1;    //定义全局变量 rain
    function check(){
        var rain = 100;    //定义局部变量rain
        alert( rain );    //这里会弹出 100
    }
    check();
    alert( rain );    //这里会弹出1
    
    </script>
    

    3、JavaScript没有块级作用域。

    这一点也是JavaScript相比其它语言较灵活的部分。

    仔细观察下面的代码,你会发现变量i、j、k作用域是相同的,他们在整个rain函数体内都是全局的。

    
    <script type="text/javascript" language="javascript">
    
    function rainman(){
    /**
     * rainman函数体内存在三个局部变量 i j k
     */
        var i = 0;
        if( 1 ){
            var j = 0;
            for( var k = 0 ; k < 3 ; k++ ){
                alert( k );    //分别弹出 0 1 2
            }
            alert( k );    //弹出3
        }
        alert( j );    //弹出0
    }
    
    </script>
    

    4、函数中声明的变量在整个函数中都有定义。

    首先观察这段代码。

    
    <script type="text/javascript" language="javascript">
    
    function rain(){
        var x = 1;
        function man(){
            x = 100;
        }
        man();    //调用man
        alert( x );    //这里会弹出 100
    }
    rain();    //调用rain
    
    </script>
    

    上面得代码说明了,变量x在整个rain函数体内都可以使用,并可以重新赋值。由于这条规则,会产生“匪夷所思”的结果,观察下面的代码。

    
    <script type="text/javascript" language="javascript">
    
    var x = 1;
    function rain(){
        alert( x );    //弹出 'undefined',而不是1
        var x = 'rain-man';
        alert( x );    //弹出 'rain-man'
    }
    rain()
    
    </script>
    

    这是由于在函数rain内局部变量x在整个函数体内都有定义( var x= ‘rain-man’,进行了声明),所以在整个rain函数体内隐藏了同名的全局变量x。这里之所以会弹出’undefined’是因为,第一个执行alert(x)时,局部变量x仍未被初始化。

    所以上面的rain函数等同于下面的函数。

    
    function rain(){
        var x;
        alert( x );
        x = 'rain-man';
        alert( x );
    }
    

    5、未使用var关键字定义的变量都是全局变量。

    
    <script type="text/javascript" language="javascript">
    
    function rain(){
        x = 100;    //声明了全局变量x并进行赋值
    }
    rain();
    alert( x );    //会弹出100
    
    </script>
    

    这也是JavaScript新手常见的错误,无意之中留下的许多全局变量。

    6、全局变量都是window对象的属性

    
    <script type="text/javascript" language="javascript">
    
    var x = 100 ;
    alert( window.x );//弹出100
    alert(x);
    
    </script>
    

     
    等同于下面的代码:

    
    <script type="text/javascript" language="javascript">
    
    window.x = 100;
    alert( window.x );
    alert(x);
    
    </script>
    

    附录:一些比较BT的有关全局变量和局部变量的测试

    <script>
    /*
    * javascript 的全局变量与局部变量一直都是一个头疼的问题,今天在写程序的时候有出现了个问题。在ie7下,在函数里就可以访问全局变量,而在ie6
    * 下面居然变量的值变成了undefined。
    * 以前网上查到的资料都是在定义变量的时候不使用var就定义的是全局变量,但为什么就不行了呢?
    * 我就写了下面的测试程序:
    */
    
    /*----------------------------------------*/
     
    /*
    a = 1;      //A 此处为全局变量
    var b = 2;  //B 此处为全局变量
    function params(){
    alert(a);   //程序输出为1
    alert(b);   //程序输出为2
    }
    params();
    */
     
    /*----------------------------------------*/
     
    /*
    a = 1;      //A 此处为全局变量
    var b = 2;  //B 此处为全局变量
    function params(){
    var a = 11;  //C 此处为局部变量
    var b = 22;  //D 此处为局部变量
    alert(a);    //程序输出为11
    alert(b);    //程序输出为22
    }
    params();
    alert(a);        //程序输出为1
    alert(b);         //程序输出为2
    */
     
    /*----------------------------------------*/
     
    /*
    a = 1;      //A 此处为全局变量
    var b = 2;  //B 此处为全局变量
    function params(){
    a = 11;     //C 修改全局变量a的值
    b = 22;     //D 修改全局变量b的值
    alert(a);   //程序输出为11
    alert(b);   //程序输出为22
    }
    params();
    alert(a);       //程序输出为11
    alert(b);       //程序输出为22
    */
     
    /*----------------------------------------*/
     
    /*
    a = 1;      //A 此处为全局变量
    var b = 2;  //B 此处为全局变量
    function params(){
    var a = 11;    //C 此处为局部变量
    var b = 22;    //D 此处为局部变量
    alert(a);      //程序输出为11
    alert(b);      //程序输出为22
    alert(window.a);//程序输出为1
    alert(window.b);//程序输出为2
    }
    params();
    alert(a);           //程序输出为1
    alert(b);           //程序输出为2
    */
     
    /*----------------------------------------*/
     
    /*
    a = 1;      //A 此处为全局变量
    var b = 2;  //B 此处为全局变量
    function params(){
    a = 11;    //C 修改全局变量a的值
    b = 22;    //D 修改全局变量b的值
    alert(a);      //程序输出为11
    alert(b);      //程序输出为22
    alert(window.a);//程序输出为11
    alert(window.b);//程序输出为22
    }
    params();
    alert(a);           //程序输出为11
    alert(b);           //程序输出为22
    */
    
    /*----------------------------------------*/
     
    /**
    * 从以上的测试程序,应该明白全局变量和局部变量.
    * 个人觉得访问全局变量,如果只需兼容ie,最好使用 window.a 这种方式来访问.
    */
    </script>
    

    猜猜以下代码输出什么:

    <SCRIPT LANGUAGE="JavaScript">  
    var x='000';  
    document.writeln(x);
    a();
    function a(){  
       var x='aaa';  
       function b(){  
         document.writeln(x); 
         var x='bbb';  
         document.writeln(x);  
         }  
       b(); 
       document.writeln(x);
       }  
    </SCRIPT>
    

    答案:000 undefined bbb aaa
    改一下代码,得到 000 undefined 111 111:

    <SCRIPT LANGUAGE="JavaScript">  
    var x='000';  
    document.writeln(x); 
    a(); 
    function a(){  
      function b(){  
        document.writeln(x); 
        document.writeln(x); 
      }  
      document.writeln(x);
      var x='111';  
      b();   
      }  
    </SCRIPT>
    

    猜猜以下代码会输出什么:

    <SCRIPT LANGUAGE="JavaScript">  
      var x=100;  
      document.writeln(x); 
      add(x); 
      document.writeln('</br>------------------------</br>'); 
      var x=200;  
      document.writeln(x);  
      add(x); 
      function add(x){  
        document.writeln(x);
        var x=300;     
        document.writeln(x);  
        var x=400;  
        document.writeln(x);  
        }  
    </SCRIPT>
    

    估计很多人能得出正确答案:
     
    100 100 300 400
    ————————
    200 200 300 400

    photoshop小技术点之——图层复合

    从06年开始使用photoshop CS2,到现在的photoshop CS4,居然一直没发现“图层复合”这个面板,甚至连这个功能是从哪个版本开始出现的都不清楚,汗|||。可见本人的好奇心已经低到了什么程度。一个很简单的功能,今天无意中在一个flash英文教程视频中发现。

    所谓图层复合,不是指图层合并,也不是什么图层盖印,而是指在psd文件中根据需要对不同的图层和组进行组合显示的一种小功能。

    简单的理解,图层复合面板会记录当前文档中的图层显示状态。当你关闭或打开一些图层和组时,图层复合面板可以帮你记录下文档当前的显示状态并创建一条记录。

    比如我们在制作一个网站的首页,你可能在同一个psd文件中制作了两种布局以供选择,这样,你可以通过“图层复合”的功能,将这两种布局状态分别储存起来,在“图层复合”面板上控制它们显示或不显示,并添加相关的注释。

    这个功能对于团队协作非常有帮助。

    教程地址:http://99ut.blueidea.com/text/photoshop/basic/pss05_10.html