<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>toscho.design&#187; Browser</title>
	<atom:link href="http://toscho.de/thema/browser/feed/" rel="self" type="application/rss+xml" />
	<link>http://toscho.de</link>
	<description>Redaktion und schwer geprüftes Webdesign aus Halle (Saale)</description>
	<lastBuildDate>Sat, 07 Jan 2012 14:55:02 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>daily</sy:updatePeriod>
	<sy:updateFrequency>4</sy:updateFrequency>
	
		<item>
		<title>WordPress: Internet Explorer ohne CSS-Hacks ansprechen</title>
		<link>http://toscho.de/2010/wordpress-internet-explorer-ohne-css-hacks-ansprechen/</link>
		<comments>http://toscho.de/2010/wordpress-internet-explorer-ohne-css-hacks-ansprechen/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 07:43:50 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Markup]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Trickkiste]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1731</guid>
		<description><![CDATA[Wie man jede Version des Internet Explorers einfach mit einem Klassennamen ansprechen kann. Extra Code für WordPress-Themes inklusive.]]></description>
			<content:encoded><![CDATA[<p><img src="http://toscho.de/wp-content/uploads/2010/09/ie-150.png" alt="" title="ie-150" width="150" height="150" class="alignright size-full wp-image-1732" />Den Internet Explorer betrachten die meisten Webentwickler zu Recht als chronische Krankheit. Neben anderen Browsern sieht auch die kommende Version 9 <a href="http://www.findmebyip.com/litmus">eher bedrückend</a> aus. Ehe wir diesem Browser keine Extrawurst mehr braten müssen, wird noch viel Zeit vergehen.</p>
<p>Um den IE im Stylesheet gesondert anzusprechen, brauchen wir weder Hacks im CSS noch eine zusätzliche Datei oder gar (pfui!) eine serverseitige Browserweiche. Wir müssen nur das Element <code>&lt;html&gt;</code> über <a href="http://msdn.microsoft.com/en-us/library/ms537512(VS.85).aspx" lang="en" hreflang="en">Conditional Comments</a> anpassen. Diese Idee <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/" hreflang="en">hatte Paul Irish schon 2008</a>.</p>
<p>Ich habe das neulich in einem WordPress-Theme eingesetzt und mag es so sehr, daß ich künftig all meine Themes damit ausrüsten werde.<br />
Ein wenig umständlich: Die Sprachattribute werden in WordPress mit der Funktion <a href="http://codex.wordpress.org/Function_Reference/language_attributes"><code>language_attributes()</code></a> erzeugt – und die hat ein fest eingebautes <code>echo</code>, das man nicht abschalten kann. Ich will nun nicht drei Meter Code in der <code>header.php</code> stehen haben, deshalb habe ich mir zwei kleine Funktionen gebaut. Die Funktion <code>get_language_attributes()</code> ist obendrein etwas schlanker als das Original, und sie gibt das Attribut <code>dir</code> nur aus, wenn der Text von rechts nach links läuft. Andernfalls ist es an dieser Stelle überflüssig.</p>
<p>Doch zum Code, er gehört in die <code>functions.php</code>:</p>
<div class="php-code">
<pre class="notranslate php"><span class='openclose'>&lt;?php
</span><i class='comment'>/**
 * html5 start tag + language attribute + conditional tags for IE Win
 * @link   <a href="http://paulirish.com/?p=88">http://paulirish.com/?p=88</a>
 * @param  bool $print
 * @return void|string
 */</i>
<span class='internal'>function</span> htmlstart(<var>$print</var> <span class='operator'>=</span> <span class='internal'>TRUE</span>)
{
    <var>$out</var>  <span class='operator'>=</span> <span class='string'>&#039;&lt;!Doctype html&gt;&#039;</span>;
    <var>$lang</var> <span class='operator'>=</span> get_language_attributes();
    <var>$ies</var>  <span class='operator'>=</span> <span class='internal'>array</span> (
        6 <span class='operator'>=&gt;</span> <span class='string'>&#039;lte6 lte7 lte8&#039;</span>
    ,   7 <span class='operator'>=&gt;</span> <span class='string'>&#039;lte7 lte8&#039;</span>
    ,   8 <span class='operator'>=&gt;</span> <span class='string'>&#039;lte8&#039;</span>
    ,   9 <span class='operator'>=&gt;</span> <span class='string'>&#039;&#039;</span>
    );

    <span class='internal'>foreach</span> ( <var>$ies</var> <span class='internal'>as</span> <var>$n</var> <span class='operator'>=&gt;</span> <var>$class</var> )
    {
        <var>$out</var> <span class='operator'>.=</span> &quot;<span class='string'>&lt;!--[if IE </span><var>$n</var><span class='string'>]&gt;&lt;html </span><var>$lang</var><span class='string'> class=&#039;ie ie</span><var>$n</var><span class='string'> </span><var>$class</var><span class='string'> lte9&#039;&gt;&lt;![endif]--&gt;</span>&quot;;
    }

    <var>$out</var> <span class='operator'>.=</span> &quot;<span class='string'>&lt;!--[if !IE]&gt;&lt;!--&gt;&lt;html </span><var>$lang</var><span class='string'>&gt;&lt;!--&lt;![endif]--&gt;</span>&quot;;

    <span class='internal'>if</span> ( <span class='operator'>!</span> <var>$print</var> )
    {
        <span class='internal'>return</span> <var>$out</var>;
    }

    <span class='internal'>print</span> <var>$out</var>;
}

<span class='internal'>if</span> ( <span class='operator'>!</span> <a href='http://php.net/function_exists'>function_exists</a>(<span class='string'>&#039;get_language_attributes&#039;</span>) )
{
    <i class='comment'>/**
     * Returns the language attributes.
     *
     * Unobstrusive copy from the core.
     * Requires WP 3.0+
     *
     * @param string $doctype The type of html document (xhtml|html).
     */</i>
    <span class='internal'>function</span> get_language_attributes(<var>$doctype</var> <span class='operator'>=</span> <span class='string'>&#039;html&#039;</span>) {
        <var>$output</var> <span class='operator'>=</span> is_rtl() <span class='operator'>?</span> <span class='string'>&#039;dir=&quot;rtl&quot;&#039;</span> <span class='operator'>:</span> <span class='string'>&#039;&#039;</span>;

        <span class='internal'>if</span> ( <var>$lang</var> <span class='operator'>=</span> get_bloginfo(<span class='string'>&#039;language&#039;</span>) )
        {
            <var>$output</var> <span class='operator'>.=</span> ( ( get_option(<span class='string'>&#039;html_type&#039;</span>) <span class='operator'>!=</span> <span class='string'>&#039;text/html&#039;</span>
                <span class='operator'>||</span> <var>$doctype</var> <span class='operator'>==</span> <span class='string'>&#039;xhtml&#039;</span> )
                <span class='operator'>?</span> <span class='string'>&#039; xml:&#039;</span> <span class='operator'>:</span> <span class='string'>&#039;&#039;</span>) <span class='operator'>.</span> <span class='string'>&#039;lang=&quot;&#039;</span> <span class='operator'>.</span> <var>$lang</var> <span class='operator'>.</span> <span class='string'>&#039;&quot;&#039;</span>;
        }

        <span class='internal'>return</span> apply_filters(<span class='string'>&#039;language_attributes&#039;</span>, <var>$output</var>);
    }
}</pre>
</div>
<p>Im Theme rufen wir die Funktion dort auf, wo früher die Doctype-Deklaration und das Start-Tag standen.<br />
Die Ausgabe sieht (hier aufgehübscht) etwa so aus:</p>
<pre class="notranslate html">&lt;!Doctype html&gt;
&lt;!--[if IE 6]&gt;
    &lt;html lang=<code class="string">"de-DE"</code> class=<code class="string">'ie ie6 lte6 lte7 lte8 lte9'</code>&gt;
&lt;![endif]--&gt;
&lt;!--[if IE 7]&gt;
    &lt;html lang=<code class="string">"de-DE"</code> class=<code class="string">'ie ie7 lte7 lte8 lte9'</code>&gt;
&lt;![endif]--&gt;
&lt;!--[if IE 8]&gt;
    &lt;html lang=<code class="string">"de-DE"</code> class=<code class="string">'ie ie8 lte8 lte9'</code>&gt;
&lt;![endif]--&gt;
&lt;!--[if IE 9]&gt;
    &lt;html lang=<code class="string">"de-DE"</code> class=<code class="string">'ie ie9 lte9'</code>&gt;
&lt;![endif]--&gt;
&lt;!--[if !IE]&gt;&lt;!--&gt;
    &lt;html lang=<code class="string">"de-DE"</code>&gt;
&lt;!--&lt;![endif]--&gt;</pre>
<p>Nein, das ist kein sehr schönes Markup mehr. Aber so richtig schlimmes auch nicht. Obendrein validiert es.</p>
<p>Im Stylesheet können wir den Internet Explorer jetzt ganz einfach mit der passenden Klasse ansprechen:</p>
<pre class="notranslate">.ie8
{
    top:        10px;
}
.lte7
{
    top:        15px;
}</pre>
<p>Das kann ich mir viel besser merken als Kommentarhacks oder Spielereien mit ungültigen Selektoren und Eigenschaften.</p>
<p>Mehrere Internet Explorer auf einem Windows kann man sich mit der <a href="http://utilu.com/IECollection/" lang='en' hreflang='en'>Utilo IE Collection</a> einrichten. Zum Testen der Conditional Comments habe ich im Labor eine kleine Seite eingerichtet: <a href="http://labs.toscho.de/test/conditional-comments/">CC-Test</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/wordpress-internet-explorer-ohne-css-hacks-ansprechen/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Browser-ABC</title>
		<link>http://toscho.de/2010/browser-abc/</link>
		<comments>http://toscho.de/2010/browser-abc/#comments</comments>
		<pubDate>Sun, 16 May 2010 06:35:03 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[Links]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1680</guid>
		<description><![CDATA[Welche Seiten mir der Browser anbietet, wenn ich nur einen Buchstaben in das Adressfeld eintippe.]]></description>
			<content:encoded><![CDATA[<p>Ich bin gerade erst darüber gestolpert – Sonntagmorgen, fragt nicht! – <a href="http://leumund.ch/browser-abc-008247">Christian Leu listet auf</a>, welche Seite ihm der Browser für jeden einzelnen Buchstaben vorschlägt. Find’ ich lustig, also steige ich verspätet noch ein. Das Ergebnis entlarvt mich vermutlich als langweiligen Fachmenschen. Und doch stehe ich dazu.</p>
<p class="wideimg"><img src="http://toscho.de/wp-content/uploads/2010/05/browser-abc.png" alt="Browser-ABC" width="500" height="347" class="size-full wp-image-1681 border" /></p>
<ul>
<li><a href="http://www.andrewnacin.com/">andrewnacin.com</a></li>
<li><a href="http://bugs.webkit.org/">bugs.webkit.org</a></li>
<li><a href="http://core.trac.wordpress.org/">core.trac.wordpress.org</a></li>
<li><a href="http://developer.palm.com/">developer.palm.com</a></li>
<li><a href="http://www.evalotta.net/">evalotta.net</a></li>
<li><a href="http://www.fileformat.info/">fileformat.info</a></li>
<li><a href="https://github.com/">github.com</a></li>
<li><a href="http://hakre.wordpress.com">hakre.wordpress.com</a></li>
<li><a href="http://ip-lookup.net">ip-lookup.net</a></li>
<li><a href="http://www.joindiaspora.com/">joindiaspora.com</a></li>
<li><a href="http://kaliban.de/">kaliban.de</a></li>
<li><a href="http://labjs.com/">labjs.com</a></li>
<li><a href="http://meta.stackexchange.com">meta.stackexchange.com</a></li>
<li><a href="http://neuralmesh.com/">neuralmesh.com</a></li>
<li><a href="http://opera-info.de">opera-info.de</a></li>
<li><a href="http://www.php.net/">php.net</a></li>
<li><a href="http://www.quirksmode.org">quirksmode.org</a></li>
<li><a href="http://research.swtch.com/">research.swtch.com</a></li>
<li><a href="http://stackoverflow.com">stackoverflow.com</a></li>
<li><a href="http://www.typolexikon.de">typolexikon.de</a></li>
<li><a href="http://www.unwrongest.com/">unwrongest.com</a></li>
<li><a href="http://validator.nu">validator.nu</a></li>
<li><a href="http://wpdocs.labs.thedextrousweb.com/">wpdocs.labs.thedextrousweb.com</a></li>
<li><a href="http://xhtmlforum.de">xhtmlforum.de</a></li>
<li><a href="http://yoast.com">yoast.com</a></li>
<li><a href="http://zomigi.com/">zomigi.com</a></li>
</ul>
<p>Wer spielt mit?</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/browser-abc/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Opera: Der Colorpicker</title>
		<link>http://toscho.de/2010/opera-colorpicker/</link>
		<comments>http://toscho.de/2010/opera-colorpicker/#comments</comments>
		<pubDate>Tue, 04 May 2010 21:20:35 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1673</guid>
		<description><![CDATA[Ausführliche Vorstellung des Farbwählers in Opera Dragonfly. Screenshots und eine Schritt-für-Schritt-Anleitung.]]></description>
			<content:encoded><![CDATA[<p>Seltsamerweise ist bei all der Presse um Opera 10.5 ein Detail nahezu untergegangen, über das <em>ich</em> mich sehr gefreut habe: Der Farbwähler in Opera <a href="http://www.opera.com/dragonfly/">Dragonfly</a>.</p>
<p><a href="http://toscho.de/wp-content/uploads/2010/05/colorpicker.png"><img src="http://toscho.de/wp-content/uploads/2010/05/colorpicker-300x106.png" alt="Opera Colorpicker" width="300" height="106" class="alignnone size-medium wp-image-1674 border" /></a></p>
<p>Wir finden ihn im Reiter <i lang="en">Utilities</i> in Dragonfly, das wir bei ausgeblendeter Menuleiste am leichtesten erreichen, wenn wir irgendwo im Dokument das Kontextmenu aufrufen und dort ›Element untersuchen‹ auswählen (im Englischen <i lang="en">›Inspect Element‹</i>).</p>
<p>Fahren wir jetzt mit der Maus über die Seite, so wird in einem Vorschaufenster die Fläche unter der Maus stark vergrößert dargestellt.</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/05/colorpicker-auswahlfeld.png" alt="Colorpicker Auswahlfeld" width="278" height="286" class="alignright size-full wp-image-1675 border" />Ganz links können wir festlegen, wie groß die jeweilige Auswahl sein soll, die von der Maus erfaßt wird, und wie stark die Vergrößerung ist.</p>
<p>Das finde ich noch nicht sehr verständlich, und mit <i lang="en">Scale 1</i> fährt sich der Auswahlmodus auch manchmal fest. Mit einem einem kleinen Trick gießen wir Öl ins Getriebe: Kurz den Reiter wechseln; dann läuft es wieder. Langfristig hilft wie bei <em>jedem</em> technischen Problem natürlich nur mehr RAM.</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/05/colorpicker-manage.png" alt="Colorpicker Farbmanager" width="191" height="142" class="alignright size-full wp-image-1676 border" />Auf der linken Fläche finden wir noch ein anderes Feature: Gespeicherte Farben. Hier können wir einmal ausgewählte Farben dauerhaft merken. Der Button <i lang="en">›Manage stored colors‹</i> bietet derzeit nur das Löschen an. Ich wünsche mir noch das Benennen und eine Sortierung nach Schlagworten oder Verzeichnissen. Ansonsten ist das schon sehr praktisch.</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/05/colorpicker-select.png" alt="Colorpicker Select" width="285" height="236" class="alignright size-full wp-image-1677 border" />Rechts des Vorschaufensters können wir innerhalb der Auswahl noch einmal wählen: Wir können ein Quadrat festlegen, das wir mit der Maus auf dem Vorschaufeld plazieren. Der durchschnittliche Farbwert des Quadrates wird dann in drei Notationen ausgegeben: als RGB, als HSL und als Hexwert. Und speichern können wir die Farbe natürlich auch.<br />
Die Maximalgröße des Quadrates beträgt 9×9 Pixel – das finde ich für einige Verläufe und Fotos etwas zu klein. Die Minimalgröße beträgt 1×1 Pixel. Klein genug. Subpixel sieht man ohnehin nicht.</p>
<p>Die Funktionsweise mal Schritt für Schritt zum Mitmachen:</p>
<ol>
<li>Eine Seite öffnen, beispielsweise diese hier.</li>
<li>Rechtsklick auf ein Element (das Auge) und im Kontextmenu ›Element untersuchen‹ auswählen.</li>
<li>Jetzt öffent sich Dragonfly unten im Browserfenster mit dem Reiter ›DOM‹</li>
<li>Zum Reiter ›Utilities‹ wechseln und mit der Maus über das Auge fahren.</li>
<li>Über einer besonders schönen Stelle einmal links klicken, damit das Vorschaubild die Auswahl festhält.</li>
<li>In <i lang="en">Color Select</i> eine Größe wählen (7×7) und im Vorschaubild auf die Stelle klicken, deren durschnittlichen Farbwert man gerne haben möchte.</li>
<li>Wenn der richtige gefunden wurde, auf ›Store color‹ klicken.</li>
<li>Fertig.</li>
</ol>
<p>Brauchen wir später eine gespeicherte Farbe, so klicken wir einfach darauf. Der Wert steht dann im rechten Feld.</p>
<p>Fazit: Die Oberfläche kann durchaus klarer werden, und ein paar Features fehlen mir noch: ein Export und Variieren der Farben beispielsweise. Aber im Ganzen ist das schon eine schöne Demonstration der Möglichkeiten, die die neue API Dragonflys bietet. Dragonfly ist übrigens Open Source, <a href="http://my.opera.com/dragonfly/blog/2010/05/04/100-000-milestone-and-changes-to-the-licence">seit heute</a> unter einer Apache-2.0-Lizenz. Es muß nicht extra installiert werden, womit eine Last wegfällt, die man mit externen Werkzeugen ja meistens hat.</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/opera-colorpicker/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Designlinks 12</title>
		<link>http://toscho.de/2010/designlinks-12/</link>
		<comments>http://toscho.de/2010/designlinks-12/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 10:19:33 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[Zeichen]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1669</guid>
		<description><![CDATA[Eine Katze, die gerne duscht, langsame Referenzen, schlanke User-Agent-Strings, fette Zeichenreferenzen, ein enorm flexibles Stylesheet und ein Malprogramm.]]></description>
			<content:encoded><![CDATA[<p>Wird mal wieder Zeit. Aber zuerst entspannen wir uns ein bißchen:</p>
<p class="wp-caption-text"><object type="application/x-shockwave-flash" data="http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=1920326&#038;fullscreen=1" width="480" height="360" ><param name="allowfullscreen" value="true"/><param name="wmode" value="transparent"/><param name="allowScriptAccess" value="always"/><param name="movie" quality="best" value="http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=1920326&#038;fullscreen=1"/><embed src="http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=1920326&#038;fullscreen=1" type="application/x-shockwave-flash" wmode="transparent"  width="480" height="360"  allowScriptAccess="always"></embed></object><br />
Quelle: <a href="http://www.collegehumor.com/video:1920326" hreflang="en">CollegeHumor</a>.</p>
<p>›<a href="http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html" hreflang="en" lang="en">Do not use PHP references</a>‹, empfiehlt Johannes Schlüter, denn Referenzen kosten Tempo, Übersicht und Flexibilität. Ob seiner klaren und verständlichen Darstellung dieses kniffligen Themas möchte ich den Artikel jetzt schon in die Liste der zehn besten dieses Jahres rücken.</p>
<p>Nicholas C. Zakas: <a href="http://www.nczonline.net/blog/2010/01/12/history-of-the-user-agent-string/" hreflang="en" lang="en">History of the user-agent string</a>. Warum die UA-Strings heute oft so sonderbar aussehen. Die neue <a href="http://blogs.msdn.com/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx" hreflang="en">Kennung des IE 9</a> lautet:</p>
<pre class="notranslate">Mozilla/5.0 (compatible, MSIE 9.0; Windows NT 6.1; Trident/5.0)</pre>
<p>Anhängsel irgendwelcher Zusatzsoftware werden nicht mehr eingebaut; damit schrumpft die <a href="http://www.useragentstring.com/_uas_Internet%20Explorer_version_8.0.php" hreflang="en">Liste der möglichen Kennungen</a> gewaltig – was es Proxys erheblich erleichtert, gespeicherte Versionen einer Webseite auszuliefern. Das erklärt Billy Hoffman gut in: ›<a href="http://zoompf.com/blog/2010/03/the-big-performance-improvement-in-ie9-no-one-is-talking-about" hreflang="en" lang="en">The Big Performance Improvement in IE9 No One is Talking About</a>‹. Er rät auch dazu, die <a href="http://toscho.de/2010/gzip-pro-und-kontra/">gzip-komprimierte</a> Version <em>nur noch</em> anhand des Accept-Headers zu versenden und den User-Agent zu ignorieren, damit beispielsweise ein Safari-Nutzer die Version bekommt, die der Firefox-Nutzer zuvor in den Proxy gehievt hat.</p>
<p>Man kann <a href="http://toscho.de/2008/zeichenkodierung-begriffe/#toc-maskierung-entity-und-zeichenreferenz">dezimale Zeichenreferenzen</a> mit beliebig vielen führenden Nullen versehen. So läßt sich das <samp>A</samp> als <code>&amp;#65;</code> schreiben oder als <code>&amp;#000000000000000000000000000000065;</code><br />
›hakre‹ hat mal ausprobiert, wie weit man damit gehen kann: ›<a href="http://hakre.wordpress.com/2010/02/25/html-entity-boundaries-zero-padding/" hreflang="en" lang="en">HTML Entity Boundaries – Zero Padding</a>‹.<br />
Ein Experiment, dessen praktischer Nutzen sicher weit unter seinem Unterhaltungswert liegt. Doch zeigt es, wie weit die Entwickler vorausdenken und wo sie die Grenze ziehen zwischen ›das versuche ich noch‹ und ›das wird zu langsam‹. Wenig überraschend frißt Firefox die meisten Nullen – bis zum Erstickungstod.</p>
<p>Anne van Kesteren hat auch ein Experiment mit gewaltigem Geekpotential hingestellt: <a href="http://annevankesteren.nl/test/contenteditable-style.htm" lang="en">Live style sheet editing!</a><br />
Und da muß ich einfach mal den Quelltext zitieren:</p>
<pre class="notranslate">&lt;!doctype html&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;title&gt;Live style sheet editing!&lt;/title&gt;
  &lt;style style="<code class="string">white-space:pre <i>/* hack for Opera */</i></code>" contenteditable=""&gt;
html {
margin:.2em;
font-size:2em;
color:lime;
background:purple
}
head, title, style
{
display:block
}
body {
display:none
}
  &lt;/style&gt;
 &lt;/head&gt;
 &lt;body&gt;<i>&lt;!-- nothing is needed here --&gt;</i>&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Zum Schluß noch ein Link für die Freunde der Maus: <a href="http://mrdoob.com/projects/harmony/">Harmony</a>, ein Zeichenprogramm in Javascript und Canvas. Das macht wirklich Freude.</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/04/harmony-toscho.png" alt="Harmony. Ein Experiment." width="485" height="330" class="alignnone size-full wp-image-1670 border" /></p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/designlinks-12/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Text-rendering: illegibility</title>
		<link>http://toscho.de/2010/text-rendering-illegibility/</link>
		<comments>http://toscho.de/2010/text-rendering-illegibility/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 05:11:26 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Typographie]]></category>
		<category><![CDATA[Webdesign]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1665</guid>
		<description><![CDATA[Der Browser des Palm OS stolpert über eine ganz harmlos wirkende CSS-Deklaration – und zeigt dann keinen Text mehr an. Wie man das testet und repariert, zeigt dieser Artikel.]]></description>
			<content:encoded><![CDATA[<p>Wenn zwischen Absicht und Ergebnis fremder Code steht, dann braucht der geübte Binärschubser seine wichtigste Kompetenz: Fluchen. So auch ich, als ich gestern von Christoph Schnieder dieses kleine Horrorstück zugesandt bekam:</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/04/palm-pre-broken.png" alt="palm-pre-broken" width="320" height="480" class="alignnone size-full wp-image-1666" /></p>
<p>Tatort war ein Palm Pre WebOS, Tatwerkzeug der eingebaute Browser auf WebKit-Basis.</p>
<p>Um das überhaupt nachzuvollziehen, habe ich den <a href="http://www.genuitec.com/mobile/" hreflang="en">MobiOne Emulator für Palm Pre</a> installiert. Das ging verdächtig leicht, und das Ergebnis half mir überhaupt nicht. Es war nämlich in Ordnung:</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/04/mobi-one-emulator.png" alt="mobi-one-emulator" width="404" height="758" class="alignnone size-full wp-image-1667" /> </p>
<p>Dieser Emulator ist im Wesentlichen ein zurechtgestutztes Eclipse; seine Abhängigkeit vom Gastsystem erkennt man schon daran, daß er dessen Schriften benutzt. Unbrauchbar.</p>
<p>Dann habe ich das <a hreflang="en" href="http://developer.palm.com/index.php?option=com_content&#038;view=article&#038;layout=page&#038;id=1661">Palm webOS SDK</a> installiert, das in einer virtuellen Maschine läuft – und das Problem ganz genau wiedergibt. Das scheint also ein recht realistisch arbeitendes Werkzeug zu sein. Etwas umständlich finde ich nur das <a href="http://www.uni-regensburg.de/EDV/Misc/KeyBoards/keys02.jpg">englische Tastaturlayout</a>, das ich nicht umstellen konnte.</p>
<p>Nach allerlei Tests habe ich endlich die Ursache gefunden: Ich hatte im Stylesheet eine Deklaration stehen, von der ich annahm, sie werde <a href="https://developer.mozilla.org/En/CSS/Text-rendering" hreflang="en">nur von Gecko interpretiert</a>.</p>
<pre class="notranslate">p,
address,
li
    {
        text-rendering:optimizeLegibility;
    }</pre>
<p>Diese Eigenschaft <a href="http://www.w3.org/TR/SVG/painting.html#TextRenderingProperty" hreflang="en">stammt aus SVG</a>, wie man leicht an der dämlichen Binnenmajuskel erkennt. Sie sollte Firefox dazu anregen, auch bei kleineren Schriftgraden als 20px das <a href="http://www.typolexikon.de/k/kerning.html">Kerning</a> zu respektieren.<br />
Was genau der Palm Browser hier versucht, vermag ich nicht zu sagen. Vielleicht hängt es mit der Schriftgröße zusammen, denn Überschriften, die mindestens 20px groß sind, werden noch gezeigt.</p>
<p>Ich habe die ganze Regel jetzt weggeworfen und einen Bugreport geschrieben.</p>
<p>Sicher ließe sich das auch hinter einem proprietären Selektor für Mozilla verstecken, aber davon will ich eigentlich weg. Und wenn ich damit leben kann, daß Mozilla-Nutzer noch keine abgerundeten Ecken sehen, dann darf ich genauso gut unterstellen, daß sie sich an schlampiges Kerning gewöhnt haben. Also nehmt es mir nicht übel, ja?</p>
<p>Ach ja, das aktuelle Ergebnis:</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/04/palm-web-os-sdk-fixed.png" alt="palm-web-os-sdk repariert" width="319" height="480" class="alignnone size-full wp-image-1668" /></p>
<p>Da der Browser jetzt nur die Systemschriften des Palm OS verwendet, setzt er keine Kursivschnitte für serifenlose Schriften mehr um, und eine Monospace-Schrift findet oder nutzt er auch nicht. Das ist nicht schlimm, aber man kann es unter »Aha. Mist!« ablegen.</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/text-rendering-illegibility/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Webdesign fürs iPad</title>
		<link>http://toscho.de/2010/webdesign-fuers-ipad/</link>
		<comments>http://toscho.de/2010/webdesign-fuers-ipad/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 13:43:33 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Webdesign]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1625</guid>
		<description><![CDATA[Wie man sein Layout iPad-tauglich gestaltet.]]></description>
			<content:encoded><![CDATA[<p>Der Bettvorleger ist <a href="http://www.heise.de/mobil/meldung/iPad-Apple-praesentiert-das-erwartete-Tablet-2-Update-915500.html">gelandet</a>. Apple hat am Mittwoch das iPad vorgestellt, ein Gerät, das die Nachteile eines Notebooks mit denen des iPhones kombiniert: Kein USB-Anschluß, kein DVD- oder BlueRay-Laufwerk, kein UMTS. Multitasking, das Ausführen parallel laufender Programme, geht auch nicht. Das einzige, das glänzt, ist das Display in einer Auflösung von 768×1024 Pixeln.</p>
<p><object width="480" height="295"><param name="movie" value="http://www.youtube.com/v/1ZS8HqOGTbA&#038;hl=de_DE&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/1ZS8HqOGTbA&#038;hl=de_DE&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"></embed></object></p>
<p>Viele <a title="Christian Reber: iPad - Aber auch nur beinahe perfekt" href="http://www.christianreber.com/ipad-aber-auch-nur-beinahe-perfekt">Beobachter</a> geben sich jetzt <a href="http://al3x.net/2010/01/28/ipad.html" hreflang="en" title="Alex Payne: On the iPad">enttäuscht</a>. So ein Wirbel um ein so <em>langweiliges</em> Spielzeug? Mich hat das nicht überrascht oder gar enttäuscht. Ich mache mit Apple ohnehin keine Geschäfte.<br />
Aber für den Markt freue ich mich: Die Geräteklasse wird durch Apple eingeführt und bekannt gemacht, und jeder Konkurrent kann den Pionier leicht ausstechen. Es genügt ein USB-Anschluß und die Option, daß der Kunde im Gegensatz zum iPad seine Akkus <em>selber wechseln</em> kann, wenn er möchte. Packt man noch ein richtiges, <em>mattes</em> Display drauf und eine UMTS-Verbindung, dann kommt sogar ein mobiles Gerät dabei heraus.</p>
<p>Als Designer freue ich mich auch: Die Bildschirmbreite von maximal 1024 Pixeln wird all jenen auf die Füße fallen, die bisher Festbreiten gemeißelt und damit das Web verschmutzt haben. Real werden die Benutzer dieses Spielzeugs lieber hochkant lesen, also nur 768 Pixel bereitstellen. Gute Layouts passen sich dem an, schlechte werden einfach nicht mehr benutzt.</p>
<p>Wer jetzt erst auf ein modernes Layout umstellt, mag dies bedenken:</p>
<ul>
<li>Auf einem <i lang="en">Touchscreen</i> sollten <strong>Links</strong> nicht zu dicht beieinander liegen. Finger treffen schlechter als eine Maus. Peter-Paul Koch hat dazu gerade ein bißchen geforscht: <a href="http://www.quirksmode.org/blog/archives/2010/02/the_touch_actio.html" hreflang="en" lang="en">The touch action</a>.<br />
Das interessante Problem hierbei: Wer mit solchen Bildschirmmaßen kommt und <em>doch</em> eine Maus benutzt, der möchte keinen Platz für zusätzlichen Leeraum vergeuden. Vielleicht wird sich der iPad-Safari ja per Javascript zu erkennen geben, damit man den gezielt ansprechen kann.<br />
Die Pseudo-Klasse <code>:hover</code> oder <code>onmouse*</code>-Events werden nicht angesprochen.</li>
<li>Eine horizontale Navigation sollte am Seitenrand <strong>umbrechen</strong>, sonst verschwinden vielleicht wichtige Elemente rechts hinter dem Bildschirmrand.</li>
<li>Bei Tageslicht liefert ein Spiegeldisplay schlechte <strong>Kontraste</strong>. Orangefarbene Links auf weißem Hintergrund beispielsweise dürften kaum noch zu erkennen sein.<br />
Sehr lange Texte möchte sicher niemand auf weißem Hintergrund lesen. Hier kann man einen Styleswitcher anbieten, wenn das iPad keinen eigenen Regler mitbringt.</li>
<li>
<p>Safari, der Webbrowser auf dem iPad, unterstützt <strong><a href='http://www.w3.org/TR/css3-mediaqueries/' hreflang="en" lang="en">Media Queries</a></strong> ein bißchen. Das kann man so ansprechen:</p>
<pre class="notranslate">@media screen and (max-device-width: 1024px)
{
    <em>/* Horizontal */</em>
}
@media screen and (max-device-width: 768px)
{
    <em>/* Vertikal */</em>
}
@media screen and (max-device-width: 480px)
{
    <em>/* iPhone. Findet @media handheld nicht. */</em>
}</pre>
<p>Opera und Firefox verstehen das natürlich auch, im Gegensatz zu Safari sogar nach einer <a hreflang="en" href="http://msdn.microsoft.com/en-us/library/ms537634(VS.85).aspx">IE-Expression</a>.</p>
<pre class="notranslate">* html textarea
    {
        border:             expression(
            this.onfocus = function()
                {
                    this.style.borderColor = '<code class="string">#27b</code>';
                },
            this.onblur = function()
                {
                    this.style.borderColor = '<code class="string">#888</code>';
                }
            );
    }

@media screen and (max-device-width: 768px)
{
    <em>/* Das liest Safari nicht. */</em>
}</pre>
</li>
<li>Auf dem iPad gibt es <strong>kein Flash</strong>. Dafür sollte normalerweise schon längst eine Alternative bereitstehen, aber oft sieht die <a href="http://www.google.com/search?q=ihr+browser+unterst%C3%BCtzt+kein+flash&#038;num=50&#038;ie=utf-8&#038;oe=utf-8">eher peinlich</a> aus. Safari versteht Javascript und <a href="http://www.peterkroener.de/eine-kleine-canvas-einfuehrung/">Canvas</a>; wer das nutzt, kann auf Flash oft verzichten.</li>
<li>Wenn der Safari als Mobilvariante installiert ist, dann kann er vielleicht <a href="http://doctyper.com/archives/200808/fixed-positioning-on-mobile-safari/">kein <code>position:fixed</code></a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/webdesign-fuers-ipad/feed/</wfw:commentRss>
		<slash:comments>52</slash:comments>
		</item>
		<item>
		<title>CSS: Mein Userstylesheet</title>
		<link>http://toscho.de/2010/css-mein-userstylesheet/</link>
		<comments>http://toscho.de/2010/css-mein-userstylesheet/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 12:09:36 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[Opera]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1605</guid>
		<description><![CDATA[Meine derzeit verwendete Universalvorlage.]]></description>
			<content:encoded><![CDATA[<p>CSS habe ich mit Userstylesheets gelernt, und diese Perspektive prägt meine Arbeit noch heute. Mein Standardstylesheet ist seit  <a href="http://www.opera.com/docs/history/#o351" hreflang="en">Opera 3.5</a> lange mit den Fähigkeiten des Browsers <a title="Mein Userstylesheet von 2004" href="http://opera-info.de/forum/thread.php?threadid=739">gewachsen</a>, doch seit etwa zwei Jahren werfe ich immer mehr heraus.</p>
<p>Für bestimmte Webseiten stecke ich mir noch Spezialvorlagen aus einem privaten Framework zusammen. Das Gestalten von Formularen und Scrollbars im Browser habe ich abgeschaltet, und der Adblocker arbeitet zuverlässig. Das aktuelle Userstylesheet sieht deshalb sehr schlank aus:</p>
<pre class="notranslate">*
    {
        letter-spacing:     normal      !important;
    }
body
    {
        line-height:        1.4;
        font-family:        "<code class="string">Minion Web Pro</code>";
        margin:             10px;
    }
@media print
    {
        body
            {
                margin:     0 10%;
            }
    }
p, li, blockquote, dd, dt, div
    {
        font-size:          16px;
        line-height:        1.4;
    }
#content p, #content li, #content blockquote
    {
        font-size:          16px        !important;
        line-height:        1.4         !important;
    }
body,
div,
p,
li,
dl, dt, dd,
td
    {
        cursor:             text        !important;
    }
textarea,
pre, pre *,
code,
.code,
samp,
var,
.dp-highlighter,
.dp-highlighter * <i>/* oft benutztes Highlightscript */</i>
    {
    <i>/* Die Lucida Sans Unicode hilft beim Finden exotischer Zeichen. */</i>
        font:               1em/1.2 Consolas, Lucida Sans Unicode,
                            monospace   !important;
        background-image:   none        !important;
        cursor:             text        !important;
    }
textarea:focus
    {
        color:              #000        !important;
        background:         #fff        !important;
    }
pre *,
code *,
.code *,
samp *,
var *
    {
        font-size:          1em         !important;
    }
pre,
pre *
    {
        line-height:        1.3         !important;
        white-space:        pre-wrap    !important;
    }
[align="justify"]
    {   <i>/* Andere Blocksatzsünder findet man leider nicht so leicht. */</i>
        text-align:         left        !important;
    }
table,
td,
th
    {
        border-collapse:    collapse;
        vertical-align:     top         !important;
    }
a:hover
    {
        text-decoration:    none;
    }
[href],
[onclick]
    {
        cursor:             pointer     !important;
    }
iframe[width="0"], iframe[height="0"],
iframe[width="1"], iframe[height="1"],
img[width="0"], img[height="0"],
img[width="1"], img[height="1"]
    {
        display:            none        !important;
    }
[alt]
    {
        white-space:        normal      !important;
    }
h1[id]:hover:after,
h2[id]:hover:after,
h3[id]:hover:after,
h4[id]:hover:after,
h5[id]:hover:after,
h6[id]:hover:after
    { <i>/* Findet interne Links, falls ich mal auf
       einen Abschnitt in einer Seite linken will. */</i>
        content:            "<code class="string"> #</code>" attr(id);
        font:               bold 14px/1 Consolas;
    }
button,
[type="submit"]
    {
        color:              #000        !important;
    }</pre>
<p>Siehe auch:</p>
<ul>
<li><a href="http://toscho.de/2009/userscript-userstyle-spiegel/">Userscript und Userstyle für Spiegel Online</a></li>
<li><a href="http://toscho.de/2009/licht-aus/">Licht aus! Das dunkle Userstylesheet</a></li>
<li><a href="http://toscho.de/2009/stil-des-stylesheets/">Der Stil des Stylesheets</a></li>
</ul>
<p>Eure Vorschläge?</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/css-mein-userstylesheet/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Designlinks 11</title>
		<link>http://toscho.de/2010/designlinks-11/</link>
		<comments>http://toscho.de/2010/designlinks-11/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 18:13:39 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[Webdesign]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1588</guid>
		<description><![CDATA[Über den Dialog zwischen Webprofis und Amateuren, eine performante Einbindung von Print-Stylesheets, das Opera-OS »Tabbee« und einen ungewöhnlichen Fall von Unordnung.]]></description>
			<content:encoded><![CDATA[<ul>
<li>Molily: <a lang="en" href="http://molily.de/weblog/new-amateurs">In Defense of New Amateurs</a>.<br />
Laßt euch vom Titel nicht erschrecken: Der Text wurde auf Deutsch geschrieben.<br />
Mathias beklagt hier, daß die Webexperten sich nicht (genug) um die Anfänger kümmerten, zu wenig verständliches Wissen vorhanden sei und kein Dialog zustande komme.</p>
<p>Ich finde es gut und wichtig, diesen Dialog zwischen Profis und Amateuren mal zum Thema zu machen. Aber ganz so schlecht ist die Situation ja nicht: Michael Jendryschik hat mit seiner <a href="http://jendryschik.de/wsdev/einfuehrung/">Einführung in XHTML, CSS und Webdesign</a> einen übersichtlichen Einstieg hingelegt, den man kostenlos im Netz lesen oder als Buch kaufen kann. Im <a href="http://xhtmlforum.de/">XHTML-Forum</a> diskutieren täglich Anfänger und Experten auf Augenhöhe miteinander – zuweilen mit eiserner Geduld.</p>
<p>Und dann gibt es tausende Blogs, kleine Foren und ähnliche Angebote. Die Information für Einsteiger gibt es noch – nur weiter gestreut als vor zehn Jahren.</li>
<li>Billy Hoffman: <a hreflang="en" lang="en" href="http://zoompf.com/blog/2009/12/browser-performance-problem-with-css-print-media-type/">Browser Performance Problem with CSS “print” Media Type</a>.
<p>Webbrowser sind gierig: Sie laden <span lang="en">Print-Stylesheets</span> immer, ob gedruckt wird oder nicht. Hoffman schlägt unter anderem vor, den Link zu diesem Stylesheet erst nach <code>onload</code> ins Dokument zu schreiben, um das Rendering am Bildschirm zu beschleunigen.</p>
<p>Wer dann aber versucht, eine validierende Noscript-Variante einzubauen, dürfte ordentlich ins Schwitzen kommen.</p>
<p>Sehr unschön finde ich übrigens die vielen Spamlinks im Seitenkopf. In Opera mal unter »Ansicht/Seitendarstellung« den Benutzermodus auswählen … und das Essen im Magen halten. Bah!</li>
<li>Haavard K. Moen: <a hreflang="en" lang="en" href="http://my.opera.com/haavard/blog/2009/12/14/opera-tabbee">Chrome OS, eh? How about designing your own OS using Opera and Widgets?</a>.
<p>Haavard stellt <a hreflang="fr" href="http://www.tabbee.fr/">Tabbee</a> vor, die Alternative zu Chrome OS. Die ganze Oberfläche besteht aus Opera-Widgets!<br />
Bei den Auswahllisten sieht man gut, warum man <em>so</em> keine Navigation bauen sollte: Der Finger ist doppelt so dick wie ein Listeneintrag.</p>
<p><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/k7VhlItPzkE&#038;hl=de_DE&#038;fs=1&#038;hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/k7VhlItPzkE&#038;hl=de_DE&#038;fs=1&#038;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>
</li>
<li><a hreflang="en" lang="en" href="http://www.sankakucomplex.com/2009/12/29/otaku-nightmare-room/">Otaku Nightmare Room</a>.
<p>Ganz ehrlich: Bei mir sieht es nicht immer ordentlich aus. Die ganze Wohnung ist zugebüchert; selbst unter der Decke habe ich Regale langgezogen. Aber seitdem ich <em>das</em> gesehen habe, fühlt sich meine Wohnung geradezu steril an.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/designlinks-11/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Gzip: Pro und Kontra</title>
		<link>http://toscho.de/2010/gzip-pro-und-kontra/</link>
		<comments>http://toscho.de/2010/gzip-pro-und-kontra/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 16:15:18 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[Suchmaschinen]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1601</guid>
		<description><![CDATA[Warum gzip nicht nur Probleme löst und wann man sich dafür oder dagegen entscheidet.]]></description>
			<content:encoded><![CDATA[<p>Die Firefox-Addons <a href="https://addons.mozilla.org/de/firefox/addon/5369">YSlow (Yahoo)</a> und <a href="http://code.google.com/intl/de/speed/page-speed/">Page Speed (Google)</a> helfen Webentwicklern, die Ladezeiten ihrer Seiten zu beschleunigen.<br />
Sie arbeiten ihrer Natur nach sehr pauschal und empfehlen immer, alle textbasierten Webressourcen mit <i lang="en">gzip</i> zu komprimieren.</p>
<p><a href="http://www.gzip.org/">Gzip</a> (<abbr title="GNU is not Unix">GNU</abbr> zip) komprimiert Textdateien sehr effizient. Das Format wird nicht durch Patente belastet, und die meisten Browser und Crawler können damit umgehen. Die <em>meisten</em>, nicht <em>alle</em>.</p>
<p>Wir können die komprimierte Variante einer Ressource nicht auf gut Glück verschicken, sondern nur, wenn der Empfänger dies bekannt gibt:</p>
<p><em lang="en">Request-Header:</em></p>
<pre class="notranslate">Accept-Encoding: <strong>deflate</strong>, <strong>gzip</strong>, <strong>x-gzip</strong>, identity, *;q=0</pre>
<p>Das heißt: Wir müssen <i lang="en">Content-Negotiation</i> betreiben, über den Inhalt also mit dem Empfänger verhandeln – und eine unkomprimierte Variante vorhalten. </p>
<p>Spannend finde ich die Erkenntnisse, die Arvind Jain und Jason Glasgow <a href="http://googlecode.blogspot.com/2009/11/use-compression-to-make-web-faster.html">zusammengefaßt</a> haben: Anti-Virus-Software, Browser-Bugs, Webproxys und fehlkonfigurierte Webserver verhindern oft die Kompression.</p>
<p>Nehmen wir einmal an, Browser 1 verstehe gzip, Browser 2 nicht. Beide erreichen unsere Website über den selben Proxyserver. Browser 1 holt sich die gzip-Variante, der Proxy speichert diese und schickt sie später Browser 2. Obwohl der mit gzip nichts anzufangen weiß. Nicht so gut.</p>
<p>Also senden wir das Dokument mit einem Response-Header zurück, der den Proxy darüber informiert, wann er die Seite an einen anderen Browser ausliefern darf: Wenn der das gleiche <i lang="en">Accept-Encoding</i> vorlegt.</p>
<p><em lang="en">Response-Header:</em></p>
<pre class="notranslate">Vary: Accept-Encoding</pre>
<p>Der <i lang="en">Vary-Header</i> wurde erst in HTTP/1.1 eingeführt – also bekommen alle Anfragen, die per HTTP/1.0 einschlagen, <em>immer</em> die unkomprimierte Variante.</p>
<p>Jetzt kann der Internet Explorer (zumindest bis Version 6) die unkomprimierte Ressource überhaupt <a href="http://marc.info/?l=apache-modgzip&#038;m=103951214411428&#038;w=2">nicht mehr</a> im <i lang="en">Cache behalten</i>, und die komprimierte landet auf jeden Fall darin. »Abhilfe« schafft ein weiterer </p>
<p><em lang="en">Response-Header:</em></p>
<pre class="notranslate">Cache-Control: private</pre>
<p>Und jetzt kann der Proxy die Ressource nicht mehr speichern. </p>
<p>Um das Thema »Internet Explorer« schnell hinter uns zu bringen, seien noch zwei Bugs erwähnt: </p>
<ul>
<li>Wenn ein XHTML-Dokument komprimiert und mit XML-Deklaration verschickt wird <em>und</em> überdies sehr lange oder viele Response-Header (Cookies beispielsweise) vorausgehen, dann versucht der Internet Explorer 6 in einigen Versionen, den MIME-Typen zu erraten. Er kommt dann zu dem Schluß, er habe XML vor der Nase – und <a href="http://support.microsoft.com/kb/947195/en-us">scheitert kläglich</a>.</li>
<li>Wenn ein komprimiertes Dokument per SSL (HTTPS) angeboten wird, kann es auch passieren, daß der Leser <a href="http://support.microsoft.com/?scid=kb;en-us;837251&#038;spid=2073&#038;sid=218">gar nichts sieht</a>.</li>
</ul>
<p>Inzwischen hat sich die Situation jedoch <a href="http://blogs.msdn.com/ie/archive/2005/10/31/487509.aspx">gebessert</a>.</p>
<p>Zu den Problemen beim Transfer und beim Caching stellt sich noch die Frage: <em>Lohnt es sich?</em><br />
Das Ein- und Auspacken kostet ja auch Zeit. Gerade bei Dokumenten, die erst bei Abruf komprimiert werden, müssen wir Faktoren berücksichtigen, die eventuell den Zeitgewinn ausstechen: die Serverlast und die Verarbeitungsdauer auf dem Server und beim Client.<br />
Ein 3-kB-Dokument zu komprimieren, bringt überhaupt nichts. Bei 5 kB wird es langsam interessant, und ab 10 kB spürt der Leser den Unterschied.</p>
<p>Wir sollten beide Varianten statisch vorhalten, damit der Server nicht immer wieder dieselbe Arbeit erledigen muß. Hier fällt natürlich noch ein gewisser Koordinationsaufwand an.</p>
<p>Wann also komprimieren?</p>
<ul>
<li>Wenn die Ressource nicht unbedingt im Cache landen soll und/oder</li>
<li>5 kB überschreitet und</li>
<li>der Server genug Kapazität dafür übrig hat oder beide Varianten fertig vorliegen.</li>
</ul>
<p>Und wann nicht?</p>
<ul>
<li>Wenn die Ressource unbedingt in den Cache gelangen soll (Stylesheets in einem Webforum) und noch viele IE-6-Nutzer daherkommen oder</li>
<li>der Server unter hoher Last steht oder</li>
<li>das generierende Skript schon lange genug arbeitet.</li>
</ul>
<p>Diese Hinweise bitte ich als grobe Richtlinien zu verstehen. Je nach Kontext können sie auch sehr danebenliegen. Per <code>@font-face</code> eingebettete Schriften will man <a href="http://www.phpied.com/font-face-gzipping-take-ii/">ganz gewiß komprimieren</a> – aber nur einmal verschicken. Hier lohnt sich ein <a href="http://toscho.de/2010/logfiles-analysieren/">Blick ins Logfile</a>: Welche Browser benutzen meine Leser? Und dann trifft man eine informierte Entscheidung.</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/gzip-pro-und-kontra/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WordPress: Shortlinks reloaded</title>
		<link>http://toscho.de/2010/wordpress-shortlinks-reloaded/</link>
		<comments>http://toscho.de/2010/wordpress-shortlinks-reloaded/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 21:25:07 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[Interna]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[Markup]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1594</guid>
		<description><![CDATA[Wie man Short-URIs in WordPress erzeugt, ausgibt und narrensicher per .htaccess abfängt. Code und ein Plugin zum Download.]]></description>
			<content:encoded><![CDATA[<!--TOC-->
<p>Im April 2009 habe ich gezeigt, wie man in WordPress <a href="http://toscho.de/2009/shortlinks-in-wordpress/">mit Bordmitteln kurze URLs</a> für Seiten und Artikel erzeugt: Blog-Adresse plus »<code class="string">?p=</code>« plus Post-Id. Das funktioniert einfach und schnell. Nicht.</p>
<h2>Formatkrieg</h2>
<p>Meine Grundidee war: Ich habe nur einen Ort für die Logik des Verfahrens – die <code>functions.php</code>. Das stellte sich als zu naiv heraus, als die ersten <strong>kaputten Crawler</strong> aufschlugen, die das Fragezeichen mit einem <code>urlencode()</code> vorbehandelten. Requests auf <samp>/%3F=762</samp> sind eben etwas anderes als auf <samp>/?=762</samp>.</p>
<p>Jetzt mußte ich doch einen zweiten Ort anfassen: die .htaccess.</p>
<pre class="notranslate">RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/\<strong>%3f</strong>p\=(\d+)$
RewriteRule ^.* /?p=%1 [L,R=301]</pre>
<p>Dann versagte auch die URL-Erkennung bei <strong>Twitter</strong>: Verlinkt wurde nur der Teil bis zum Fragezeichen, alles dahinter fiel weg.<br />
Also habe ich die Kurz-URLs auf das Format /p762 umgestellt und die .htaccess angepaßt:</p>
<pre class="notranslate">RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/\%3fp\=(\d+)$ [OR]
RewriteCond %{REQUEST_URI} ^<strong>/p</strong>\=?(\d+)$
RewriteRule ^.* /?p=%1 [L,R=301]</pre>
<p>Auftritt <strong>Rivva-Bot</strong>: Der hat das neue Format um einen Slash <code>/</code> ergänzt, <a href="http://toscho.de/2010/logfiles-analysieren/#toc-400er">die Fehlerseite bestaunt</a> – und dann blieb er weg. Kein Problem:</p>
<pre class="notranslate">RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/\%3fp\=(\d+)$ [OR]
RewriteCond %{REQUEST_URI} ^/p\=?(\d+)<strong>/?</strong>$
RewriteRule ^.* /?p=%1 [L,R=301]</pre>
<h2>Markup</h2>
<p>In einem sehr fruchtbaren <a href="http://toscho.de/2009/shortlinks-in-wordpress/#comment-405">Ideen-Pingpong</a> (vulgo: Dialog) mit <a href="http://bernhardhaeussner.de/">Bernhard Häussner</a> haben wir die perfekte Notation für die Bekanntgabe des Shortlinks gefunden: Ein separater HTTP-Header samt <code>meta</code>-Element:</p>
<pre class="notranslate">&lt;meta http-equiv="<code class="string">X-Short-URI</code>" content="<code class="string">http://toscho.de/?p=762</code>"&gt;</pre>
<p>Interessiert kein Schwein. Am 14. August <a href="http://en.blog.wordpress.com/2009/08/14/shorten/">schuf WordPress.com Tatsachen</a> und verstetigte die sehr schlechte Lösung <code>rel="shortlink"</code> (<a href="http://microformats.org/wiki/rel-shortlink">Referenz</a>). Schade.</p>
<p>Jetzt könnte die URL also so angegeben werden:</p>
<pre class="notranslate">&lt;link rel="shortlink" href="http://toscho.de/?p=762"&gt;</pre>
<p><div id="attachment_1595" class="wp-caption alignright" style="width: 287px"><img src="http://toscho.de/wp-content/uploads/2010/01/opera-shortlink-info.png" alt="Opera: Shortlink im Infopanel" width="277" height="279" class="border size-full wp-image-1595" /><p class="wp-caption-text">Opera: Shortlink im Infopanel</p></div><em>Könnte.</em> Opera, auf den ich unter keinen Umständen verzichte, ignoriert leider genau diesen Link im Info-Panel. Also füge ich als Beziehung noch ein <code>alternate</code> hinzu, damit die Erkennung wieder klappt.<br />
Wer es ausprobieren möchte: F4 drücken, »Leiste anpassen/Erscheinungsbild/Paneele/« und ein Häkchen bei »Info« setzen.</p>
<h2 style="clear:right">PHP-Code</h2>
<p>Ich habe den Code zur Ausgabe in WordPress in eine kleine Klasse mit statischen Methoden gegossen – des armen Mannes Namensraum. Verzeiht mir.</p>
<pre class="notranslate">&lt;?php
<i>/**
 * Class Short_URI: Short-URIs erzeugen und ausgeben.
 * @author Thomas Scholz &lt;http://toscho.de&gt;
 * @see <a href="http://microformats.org/wiki/rel-shortlink">http://microformats.org/wiki/rel-shortlink</a>
 * @license GPL 3 &lt;<a href="http://www.gnu.org/licenses/gpl.html">http://www.gnu.org/licenses/gpl.html</a>&gt;
 * @version 1.3
 *
 */</i>
class Short_URI {

    <i>/**
     * Kurz-URI
     * @var string
     */</i>
    protected static <var>$short_uri</var>      = NULL;

    <i>/**
     * Sendet einen Link-HTTP-Header
     * @param bool <var>$headonly</var> Nur bei HEAD-Requests senden?
     * @return void
     */</i>
    public static function send_header(<var>$headonly</var> = TRUE)
    {
        if (<var>$headonly</var> and ('<code class="string">HEAD</code>' != <var>$_SERVER</var>['<code class="string">REQUEST_METHOD</code>']) )
        {
            return;
        }
        if ( ! self::prepare() )
        {
            return;
        }
        header('<code class="string">Link: &lt;</code>' . self::<var>$short_uri</var> . '<code class="string">&gt;; rel="shortlink"</code>');
        return;
    }

    public static function link_elem(<var>$echo</var> = TRUE)
    {
        if ( ! self::prepare() )
        {
            return;
        }
        <var>$link</var> = '<code class="string">&lt;link rel="alternate shortlink" title="Shortlink"</code>'
                . '<code class="string"> href="</code>' . self::<var>$short_uri</var> . '<code class="string">" /&gt;</code>';

        if ( ! <var>$echo</var>)
        {
            return <var>$link</var>;
        }

        echo <var>$link</var>;
        return;

    }

    <i>/**
     * Erzeugt einen Link zum Twittern der aktuellen Seite.
     * @param string|array <var>$args</var>
     * @return string
     */</i>
    static function tweet_link(<var>$args</var> = NULL)
    {
        <var>$message_template</var> = '<code class="string">Lese gerade: %TITLE %URL von @toscho</code>';
        <var>$link_text</var>        = '<code class="string">Artikel twittern</code>';
        <var>$title_length</var>     = 80;
        <var>$class</var>            = '<code class="string">twitterlink</code>';
        <i>// Zum Ändern echo=0 übergeben.</i>
        <var>$echo</var>             = TRUE;

        if ( ! is_null(<var>$args</var>) )
        {
            if ( is_array(<var>$args</var>) )
            {
                extract(<var>$args</var>);
            }
            elseif ( is_string(<var>$args</var>) )
            {
                parse_str(<var>$args</var>);
            }
            else
            {
                trigger_error(
                    '<code class="string"><var>$args</var> muss ein Array oder ein String sein.</code>',
                    E_USER_ERROR
                );
            }
        }
        global <var>$post</var>;

        <var>$title</var>       = trim(<var>$post</var>-&gt;post_title);

        if ( isset ( <var>$title</var>[<var>$title_length</var>+2] ) )
        {<i>// Verkürzen bei Bedarf</i>
            <var>$title</var> = self::end_on_word(substr(<var>$title</var>, 0, <var>$title_length</var>)) . '<code class="string"> …</code>';
        }

        <var>$message</var> = str_replace(
            array('<code class="string">%TITLE</code>', '<code class="string">%URL</code>'),
            array(<var>$title</var>, self::<var>$short_uri</var> ),
            <var>$message_template</var>
        );

        <var>$link</var> = '<code class="string">&lt;a class="</code>' . <var>$class</var>
            . '<code class="string">" href="http://twitter.com/home?status=</code>' . urlencode(<var>$message</var>)
            . '<code class="string">" title="</code>' . <var>$message</var> . '<code class="string">"&gt;</code>'
            . <var>$link_text</var> . '<code class="string">&lt;/a&gt;</code>';

        if (<var>$echo</var>)
        {
            echo <var>$link</var>;
            return;
        }

        return <var>$link</var>;
    }

    <i>/**
     * Prüft, ob eine Short-URI erstellt werden soll
     * @return bool
     */</i>
    public static function prepare()
    {
        if ( is_front_page() )
        {
            return FALSE;
        }
        if ( is_page() or is_single() or is_attachment() )
        {
            global <var>$post</var>;

            if ( is_null( self::<var>$short_uri</var> ) )
            {
                self::<var>$short_uri</var> =
                    rtrim(get_option('home'), '<code class="string">/</code>') . '<code class="string">/p</code>' . <var>$post</var>-&gt;ID;
            }
            return TRUE;
        }
        <i>// Archive</i>
        return FALSE;
    }

    <i>/**
     * Entfernt unvollständige Worte am Ende eines Strings.
     * @see http://toscho.de/2009/php-funktion-end_on_word/
     * @param <var>$str</var> Zeichenkette
     * @return string
     */</i>
    static function end_on_word(<var>$str</var>)
    {
        <var>$str</var> = trim(<var>$str</var>);

        <i>// Nur ein Wort, wird also nicht gekürzt.</i>
        if ( FALSE === strpos(<var>$str</var>, '<code class="string"> </code>') )
        {
            return <var>$str</var>;
        }

        <i>// Jedes Wort ein Eintrag im Array …</i>
        <var>$arr</var>   = explode('<code class="string"> </code>', <var>$str</var>);
        <i>// … letztes Stück wegwerfen …</i>
        array_pop(<var>$arr</var>);
        <i>// … den String wieder herstellen und Kommas trimmen.</i>
        return rtrim( implode('<code class="string"> </code>', <var>$arr</var>), '<code class="string">,;</code>');
    }
}</pre>
<p>Wer bis hierhin durchgehalten hat, darf sich das auch als …</p>
<p class="downloadlink"><a class='piwik_download' href="http://f.toscho.de/php-skripte/short-uri.0.1.zip">WordPress-Plugin Short-URI herunterladen</a>.</p>
<p>Den Tweetlink baut ihr <em>innerhalb des Loops</em> mit diesem Code ein:</p>
<pre class="notranslate">do_action('tweet_link');</pre>
<p>Oder so:</p>
<pre class="notranslate">do_action('tweet_link', 'parameter=wert');</pre>
<p>Die darin enthaltene Klasse könnt ihr natürlich auch einfach in die <code>functions.php</code> einbinden, um den Code direkt zu verwenden.</p>
<p>Ich habe ihn unter die <a href="http://www.gnu.org/licenses/gpl.html">GPL 3</a> gestellt (<a href="http://toscho.de/2009/no-no-no-nofollow/#comment-1109">hallo Helmut!</a>), damit ihr damit machen könnt, was immer ihr wollt. Er ist mir länger geraten, als ich erhofft hatte; das heißt: Er hat sicher auch mehr Fehler. Findet sie!</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/wordpress-shortlinks-reloaded/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Database Caching using disk: basic
Object Caching 613/747 objects using disk: basic

Served from: toscho.de @ 2012-02-04 11:24:53 -->
