webForumDet fria alternativet

Tomma float-divvar kollapsar trots width/height

23 svar · 2 001 visningar · startad av spango · sida 2 av 2

joserMedlem sedan mars 20021 152 inlägg
#21

Tack för informationen. Missade faktiskt att du skippade gamla IE. :)

Det svar jag skulle ge för övriga webbläsare hade sett ut ungefär så här (kanske det kan vara till någon nytta):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled</title>
<meta name="generator" content="PSPad editor, www.pspad.com">
<style type="text/css">
ul{
	padding:0;
}
li{
	margin-bottom:-1px;
	border:1px solid;
	padding-right:5em;
	overflow:hidden;
	list-style:none;
	line-height:1.2;
}
li:before,
li:after{
	float:right;
	margin:0 -3.8em -6em 0;
	border:solid;
	border-width:0 1px;
	width:1.2em;
	height:7.2em;
	content:" ";
}
li:after{
	margin:-6em -1.3em 0 0;
}
</style>
</head><body>

<h1>Somewhere</h1>

<h2>Place 1</h2>
<ul>
	<li>Item 1, which really is rather long and spans more than a line and causes a line break</li>
	<li>Item 2</li>
</ul>

<h2>Place 2</h2>
<ul>
	<li>Item 3</li>
	<li>Item 4, which really is rather long, too, and spans more than line and causes a line break</li>
</ul>

</body></html>
jarvkloMedlem sedan juli 20013 378 inlägg
#22

Joser:: Snyggt och hårdoptimerat exempel :bire

spango skrev:

HTML är egentligen inte ett optimalt format (eftersom det enda jag är ute efter är visuell formatering för utskrift - man öppnar XML:en i sin Firefox och skriver ut, det är i princip den interaktion man har med dokumentets HTML-skepnad), men det är portabelt och förhållandevis okomplicerat.

Håller med.
Semantiken man får på köpet i ett XML-dokument kan vara att föredra om man är ute efter tolkning.

I en värld där man slipper tänka på IE, (typ i de förutsättningar som gäller i den här tråden :) ), och där det enbart handlar om en, två, tre eller fyra "krysskolumner") behöver man iofs inte gå över ån efter vatten...

... det går lika bra att köra "pang på rödbetan" (och blir IMHO ungefär lika okomplicerat och portabelt till det mesta utom IE) om man kopplar CSS:en direkt till XML-filen och på så sätt skippar "det osynliga mellansteget" att generera HTML som man sedan skjuter in innehåll i med CSS...

t.ex. för den utskrift med fyra kryssrutor du är ute efter:

list { display: block; padding: 10px; font-family:"Courier New", Courier, monospace;}
list:before {
	display: block; 
	content: attr(name);
	font-size: 26px;
	font-weight: bold;
}
place { display: block;}
place:before {
	content: attr(name);
	display: block; 
	font-size: 20px;
	font-weight: bold;
}
item { 
	display: block; 
	border: 1px solid black; 
	margin-bottom: -1px; 
	font-size: 14px;
	line-height: 1.2; 
	padding-right: 5em; /* lämna plats för det inducerade (flytande) innehållet om två flytande block */
	overflow: hidden;
}

item:before,
item:after {
	float: right;  /* Lägg bägge innehållsinduktionerna till höger */
	content: " ";
	width: 1.2em;
	height:7.2em;
	border: 1px solid blue;
	margin:-6em -1.3em -1px 0;  /* trixa med marginalerna för att rita upp två plus två streck - steg 1 */
}

item:before {
		margin:-1px -3.8em -6em 0; /* trixa med marginalerna för att rita upp två plus två streck - steg 2 */
		border-color: red;
}

och XML:en:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="spangolist.css" type="text/css"?>
<list name="Somewhere">
	<place name="Place 1">
		<item>Item 1</item>
		<item>Item 2</item>
		<item>Item 3 - en hyfsat lång och ordrik förklaring som gör att texten radbryter när den når högerkanten</item>
		<item>Item 4</item>
		<item>Item 5</item>
	</place>
	<place name="Place 2">
		<item>Item 6</item>
		<item>Item 7</item>
		<item>Item 8 - också en hyfsat lång och ordrik förklaring som gör att texten radbryter när den når högerkanten</item>
		<item>Item 9</item>
	</place>
</list>

Testa: http://jarvklo.se/htmlexempel/spangolist.xml

OBS! - Om utseendet enbart skall gälla för utskrift (och man inte vill se kryssrutorna på skärmen), kan man också utnyttja media-attributet och köra med

<?xml-stylesheet href="spangolist.css" type="text/css" media="print"?>

(även om det blir lite torftigt rent utseendemässigt då om man inte också lägger på en liknande stilmall (eller XSLT-mall, för det går att "blanda" mallar med olika mime-typer) för t.ex. media="screen" ;)

Lycka till :bire

spangoMedlem sedan juni 20008 205 inlägg
#23

Shit grabbar, nu börjar jag nästan grina. Vilken stilig kod!

Anledningen till att jag gjorde transformeringen till HTML var för att jag inte såg nåt vettigt sätt att få till rutorna med bara CSS, men nu kan vi nog kyssa XSLT-mallen farväl.

jarvkloMedlem sedan juli 20013 378 inlägg
#24

spango skrev:

Anledningen till att jag gjorde transformeringen till HTML var för att jag inte såg nåt vettigt sätt att få till rutorna med bara CSS, men nu kan vi nog kyssa XSLT-mallen farväl.

Hmm...
Visst kan du det - eller så kan du utnyttja en annan XSLT-mall för att göra lösningen mer generell och återanvändningsbar även för de fall du eventuellt behöver fler än fyra rutor i högerkanten;)

Om du använder XSLT för att lägga till rutorna direkt i XML:en "on the fly" (istället för att gå omvägen via HTML) - kan du förenkla CSS:en rätt avsevärt samtidigt som du slipper att CSS-hårdkoda kryssrutorna mha :before och :after-float-trixande i CSS:en ;)

XML:en skulle t.ex. kunna utökas såhär: (En extra processinstruktion innan CSS-instruktionen, och användning av en annan CSS-mall i övrigt samma kod)

<?xml version="1.0" encoding="UTF-8"?>
[b]<?xml-stylesheet href="spangolist2.xslt" type="text/xml"?>[/b]
<?xml-stylesheet href="[b]spangolist2.css[/b]" type="text/css" media="screen,print"?>
<list name="Somewhere">
	<place name="Place 1">
		<item>Item 1</item>
		<item>Item 2</item>
		<item>Item 3 - en hyfsat lång och ordrik förklaring som gör att texten radbryter när den når högerkanten</item>
		<item>Item 4</item>
		<item>Item 5</item>
	</place>
	<place name="Place 2">
		<item>Item 6</item>
		<item>Item 7</item>
		<item>Item 8 - också en hyfsat lång och ordrik förklaring som gör att texten radbryter när den når högerkanten</item>
		<item>Item 9</item>
	</place>
</list>

Och då skulle t.ex. en XSLT-transform liknande denna (som stuvar om <item> lite) kunna köras innan CSS:en appliceras:

<?xml version="1.0" encoding="utf-8"?>
 <xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- regel för rotelemenet -->
  <xsl:template match="/">
      <xsl:apply-templates />
  </xsl:template>

<!-- mall för item -->
  <xsl:template match="item">
  	<item>
<!-- skapa ett nytt underelement för innehållet i item -->
<!-- så att vi kan "lägga till" fler "kolumner i gridden" -->
  	  <xsl:element name="text">
  	  	<xsl:value-of select="."/>
  	  </xsl:element>
<!-- en checkbox per rutkolumn läggs till (ingen begränsning i antal !) -->
      <checkbox/>
      <checkbox/>
      <checkbox/>
      <checkbox/>
    </item>
  </xsl:template>

  <!-- identity template (kopierar allt som explicit saknar egen regel)-->
  <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Som du ser, läggs <checkbox/> element efter behag till inuti regeln för <item> samtidigt som originalinnehållet i <item> flyttas "ner" i ett <text>-element - detta gör att gamla "item" nu kan fungera som en "css-table-row" så att vi kan utnyttja tabellens alla trevliga egenskaper för layouten utan att göra avkall på semantiken i elementen :)

... och i det resulterade läget, skull man kunna förenkla CSS:en ganska avsevärt (till att helt sakna en massa "float hacks" och specialare)

list { display: block; padding: 10px; font-family:"Courier New", Courier, monospace;}
list:before {
	display: block; 
	content: attr(name);
	font-size: 26px;
	font-weight: bold;
}
place { display: table; border-collapse: collapse; empty-cells:show; width: 100%;}
place:before {
	content: attr(name);
	display: table-row;; 
	font-size: 20px;
	font-weight: bold;
}
item { display: table-row;}
text, 
checkbox {
	display: table-cell;
	border: 1px solid silver; 
	font-size: 14px;
}
checkbox { width: 20px;}

Och voila som greven säger.... (testa)

Tricket är alltså att lägga på både en XSLT-omformning av innehållet och en CSS-mall direkt på XML-dokumentet i syfte att slippa skapa ett mellanläge som begränsas av HTML:s begränsade semantik, och som i värsta fall tvingar fram ett eller annat CSS-hack ;)

... och nu har du ett läge där du även kan välja om XSLT-transformen skall köras bara för skrivare (media="print" används även för XSLT-mallen ;) ) eller "alltid" som i exemplet oavsett om du har media-specifk CSS eller ej ...

Lycka till :birp

125 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
123 ms — hämta tråd, inlägg och bilagor (db)