RSS
 

Opera Mini und die Bildschirmauflösung

21 Okt

Für einen grossen Kunden soll eine auf mobile Endgeräte optimierte Version der existierenden Website erstellt werden. Laut den Anforderungen muss die Website auf Safari, dem Android Browser, Opera Mobile und Opera Mini laufen. Die mobile Website ist prinzipiell flexibel aufgebaut, das heisst Elemente werden so breit dargestellt wie der Bildschirm es erlaubt. Gewisse Elemente (beispielsweise ein Sprache-Wechseln div) sind im CSS mit float: right deklariert und werden daher – egal wie gross die horizontale Auflösung des Endgeräts ist – am rechten Rand positioniert.

Für Endgeräte mit einer Bildschirmbreite von 240 Pixel oder weniger funktioniert das float: right System konzeptionell nicht, weil dann eine Überlappung der rechts am Rand positionierten Elemente mit dem restlichen Inhalt stattfindet. Aus diesem Grund wird in dem Fall eine weitere CSS Datei mobile240.css geladen, die diese Elemente verkleinert und absolut positioniert.

Zusätzlich wird für Opera Mini ein weiteres CSS mobile240.css geladen, weil in diesem Browser das vertikale Zentrieren mittels der CSS Eigenschaft line-height nicht funktioniert. Im Code unten wird das mit Javascript erreicht. Das dient nur zur Veranschaulichung und zur Debug-Ausgabe. Im Produktivsystem wird dies mit CSS Mediaqueries erreicht:

<link rel="stylesheet" type="text/css" media="only screen and (max-device-width: 240px)" href="css/mobile240.css" />

Das System funktioniert hervorragend, ausser bei Opera Mini.

<!DOCTYPE html>
<html>
<head>
	<title>Opera Mini Test</title>
	<script type="text/javascript">// <![CDATA[
		function loadCss(cssfile) {
			loadcss = document.createElement('link')
			loadcss.setAttribute('rel', 'stylesheet')
			loadcss.setAttribute('type', 'text/css')
			loadcss.setAttribute('href', 'css/' + cssfile)
			document.getElementsByTagName('head')[0].appendChild(loadcss)
		}

		var status = '';
		var operaMini = (/opera mini/i.test(navigator.userAgent.toLowerCase()));
		if (operaMini) {
			status += 'loading operamini.css<br />';
			loadCss('mobile_operamini.css');
		}

		screenWidth = screen.width;
		if (screenWidth < '320') {
			status += 'loading mobile240.css<br />';
			loadCss('mobile240.css');
		}

		status += 'screen values: ' + screen.width + "x" + screen.height + ', ';
		status += window.innerWidth + 'x' + window.innerHeight;
	// ]]></script>
	<style type="text/css">
	<!--
		body {
			margin: 0px;
			padding: 0px;
		}

		#testcontainer {
			height: 50px;
			width: 320px;
			background: #666666 url('image/debug-width-2.png') 0px 0px no-repeat;
		}
	-->
	</style>
</head>
<body>
	<div id="testcontainer">
		Opera Mini Test
	</div>
	<div id="browserinfo">
	</div>
	<script type="text/javascript">// <![CDATA[
		document.getElementById('browserinfo').innerHTML = status;
	// ]]></script>
</body>
</html>

Opera Mini gibt auf dem Samsung Galaxy Ace GT-S5830 Testgerät bei obigem Code folgendes als Ausgabe:

loading operamini.css
loading mobile240.css
screen values: 228x245,229x246

Das Galaxy Ace hat eine Bildschirmauflösung von 320×480 Pixel, warum liefert Opera Mini als Wert für screen.width 228? Im Opera Mini Forum wird die gleiche Frage gestellt und vermutet, dass das Verhalten mit der Tatsache zusammenhängt, dass alle via Opera Mini aufgerufenen Seiten auf den Servern von Opera gerendert und dann erst an das mobile Endgerät geschickt werden. Eine Lösung wurde dort aber leider nicht gepostet.

Opera Mobile und der Andriod Browser liefern für obigen Code das erwartete Ergebnis. Auch der Opera Mobile Emulator unter Windows liefert sinnvolle Werte:

Screenshot Opera Mobile Emulator 240 Pixel

Screenshot Opera Mobile Emulator 320 Pixel

Ich bin für jeden Lösungsvorschlag dankbar, der mich näher zum Ziel führt zuverlässig zu erkennen, ob bei der Verwendung von Opera Mini das 240er CSS geladen werden muss oder nicht.

 
 

Kommentare

 

 
  1. nico

    22/10/2011 01:31

    Ist das dargestellte Root-Element nicht im Grunde wichtiger als die Bildschirm Breite? Wenn das Body Element die ganze mögliche Breite einnimmt würd ich mal schauen wie viele Pixel das breit ist.

     
  2. jule_

    24/10/2011 11:24

    Klingt nach einer guten Idee, nico. Das werd ich mal probieren sobald ich wieder an dem Projekt sitze.

    Es könnte aber problematisch sein, weil mobile Browser dazu tendieren den initialen sichtbaren Bereich selbst nach irgendwelchen Algorithmen zu definieren.

    Wenn der Browser dann beispielsweise lieber initial die Website in kompletter Höhe (und dafür sehr stark verkleinert) darstellt, dann ist die Breite des Body Tags zu gross und kann für meine Zwecke nicht verwendet werden.

    Ich werds ausprobieren und dann drüber berichten.

     
  3. phil

    24/10/2011 12:51

    Den Viewport kann man aber einschraenken, bzw das Skalieren unterbinden.

    Siehe: http://dev.opera.com/articles/view/an-introduction-to-meta-viewport-and-viewport/

     
  4. jule_

    27/10/2011 10:25

    Wenn ich in obigem Beispielcode den body-tag mit der id „testbody“ versehe und JQuery einbinde und dann

    var bodyheight = $(‚#testbody‘).height();
    var bodywidth = $(‚#testbody‘).width();
    var bodystatus = ‚body width = ‚ + bodyheight + ‚, body height = ‚ + bodyheight;

    in der $(function() abfrage erhalte ich in

    Opera Mini: „body width = 110, body height = 110“
    Opera Mobile: „body width = 79, body height = 79“
    Android Browser: „body width = 79, body height = 79“

    Eine Einschränkung des Viewports via Meta-Tag ändert nichts daran, dass Opera Mini sich anders verhält als der Rest.

    Ich werde die Sache mal ruhen lassen und mit den Projektverantwortlichen Rücksprache halten. Vielleicht müssen wir als Lösung auf eine Device Datenbank (zB [1]) zurückgreifen.

    Danke euch beiden!

    [1] http://wurfl.sourceforge.net/