itfag | Teknologi. Data. Læring. Deling.

TAG | css

Av: Svend Andreas Horgen, høgskolelektor og faglærer i blant annet PHP og Ajax

Blogginnlegget Layout med CSS, flere kolonner (del 1) presenterte designet på en webside laget i PhotoShop. Deretter analyserte vi i del 2 hvilke grunnelementer websiden er bygget opp av. Nå i siste del (3) skal vi arbeide oss fram til en fullstendig kode som fungerer (tilnærmet) likt i alle nettlesere. Det kan være lurt å gjenoppfriske det som ble sagt i disse to forutgående innleggene. Vil du gå rett på, så ser målet som vi prøver å realisere med CSS-kode, slik ut:

I forrige blogginnlegg brukte vi en div-boks for hovedinnholdet, og satte venstremargen til å starte på en pikselverdi som var litt mer til venstre enn den totale bredden på menu-div-en.

Et smart triks, og egentlig veldig logisk om en tenker firkantede bokser. Men – det blir feil. Menyen slutter for tidlig. Den skal gå helt ned like langt som innholds-diven er. Det er umulig å beregne høyden på forhånd (fordi innholdet på hver webside som bruker dette designet varierer i lengde). Hva gjør en da?

Svaret er å tenke innpakning. Ordet «to wrap» på engelsk betyr å pakke inn, og i dataverdenen sier vi gjerne at en «wrapper» er noe som er kledd utenpå noe. Hva er vitsen med det? Se først hvordan wrapperen ser ut:

Denne kan vi realisere med HTML-kode:

<body>
	<div id="header">
		Toppseksjon her
	</div> 

	<div id="wrapper-main-menu">
		<div id="menu">
		 - home <br /> 
		 - about <br /> 
		 - partners <br /> 
		 - bla bla <br />
		 - menu item <br />
		 - contact
		</div> 
		
		<div id="content">
			Innhold her: Lorem ipsum 
                       dolor sit amet... og så videre... 
		</div>
	</div>
</body>

En praksis som viser seg å være brukbar her, er å ikke tenke at meny-diven får farge, men at wrapperen får en bakgrunnsfarge! Ta følgende figur i betraktning

Smart! Hvordan realisere dette med CSS-kode? Trikset er bruken av background repeat-y i wrapperen #wrapper-main-menu. Den nye koden er uthevet i fet skrift.

#header {
	height: 100px; 
	border-style: dotted; 
	border-width: 2px; 
	border-color: blue; 	
}

#content {
	margin-left: 175px; 
	padding-left: 30px;	
	padding-bottom: 20px; 
	border-style: dotted; 
	border-width: 2px; 
	border-color: blue; 
}

#menu {
	float: left; 
	width: 161px; 
	border-style: dotted; 
	border-width: 2px; 
	border-color: blue; 
}

#wrapper-main-menu {
	float: left; 
	margin-top:-10px;
	background:#FFF url("bitmaps/leftcolor_bg.png") 
                repeat-y top left; 
}

Her bruker vi bakgrunnsbildet «leftcolor_bg.png» til å fylle bakgrunnen i wrapper-diven. Bildet er 161 piksler i bredden (med vilje). Dermed blir menyen tilsynelatende 161 piksler bred. Dette passer godt med teksten vi har plassert i menu-diven som aldri kommer utenfor boksen sin (også den er 161 piksler). Det må ikke være match mellom tallene her, men det blir i hvertfall riktig om det er det.

Setter vi nå sammen HTML og CSS-koden, så ser vi at det stemmer så langt. border-style: dotted; er bare et triks for å se hvor div-boksene faktisk befinner seg, og skal slettes i den endelige løsningen. Bruk av repeat-y sikrer at bildet ikke bare vises én gang, men repeteres i vertikal retning (gjennom hele div-en). Hadde vi brukt repeat-x ville bildet blitt repetert i horisontal retning, og det ville vært feil her.

Nå er vi snart i mål. Se tilbake på originalfiguren, og du identifiserer følgende struktur:

Det blå i menyen er nå på plass. Hvordan få et tilsvarende rødt område ute til høyre? Merk at den røde er litt anderledes – den går helt fra toppen og til bunnen, mens den blå starter under headeren. La oss bruke samme triks som tidligere med å pakke inn div-ene i en wrapper. Det vi nå trenger er en ytre wrapper som faktisk pakker inn hele websiden, og så sette rød bakgrunn til høyre i denne wrapperen, og repetere bakgrunnen nedover i hele wrapper-diven. HTML-koden er nå ferdig, og ser slik ut (nye ting markert i fet skrift)

<body>

<div id="wrapper">

	<div id="header">
		Toppseksjon her
	</div> 

	<div id="wrapper-main-menu">
		<div id="menu">
		 - home <br /> 
		 - about <br /> 
		 - partners <br /> 
		 - bla bla <br />
		 - menu item <br />
		 - contact
		</div> 
		
		<div id="content">
			Innhold her: Lorem ipsum 
                       dolor sit amet... og så videre... 
		</div> <!-- end concent -->

	</div> <!-- end wrapper-main-menu -->
	
	<div id="nofloat"></div> 
	
</div> <!-- end wrapper -->

</body>

Den ytre wrapperen er grei, men hvorfor en div med id="nofloat"? Som du ser i CSS-koden har vi definert en ny regel som heter «nofloat» øverst. Det den gjør, er å kansellere float-egenskapen. Hvis ikke vil også wrapperen flyte. Hele CSS-koden er nå slik (nye ting i fet skrift):

/* Clear float */
#nofloat {
	clear: both; 
}


#wrapper{  					
	width:100%;
	background:#FFF url("bitmaps/rightcolor_bg.jpg") 
          repeat-y top right;	
	margin: 0px; 
}

#header {
	margin-right: 161px;
	height: 100px; 			
	border-style: dotted; 
	border-width: 2px; 
	border-color: blue; 	
}

#content {
	margin-left: 175px; 
	padding-left: 30px;	
	padding-bottom: 20px; 
	border-style: dotted; 
	border-width: 2px; 
	border-color: blue; 
}

#menu {
	float: left; 
	width: 161px; 
	border-style: dotted; 
	border-width: 2px; 
	border-color: blue; 
}

#wrapper-main-menu {
	float: left; 
	margin-top:-10px;
	margin-right: 200px; 	
	background:#FFF url("bitmaps/leftcolor_bg.png") 
           repeat-y top left; 
}

Igjen bruker vi trikset med å la et rødt bakgrunnsbilde repeteres i y-retning, denne gangen helt til høyre i hoved-wrapperen. Dermed skapes illusjonen om at vi har en rødfarget høyre kolonne («rightcolor_bg.jpg» er et rødt bilde på 161 piksler i bredden).

Husk at innholdet på siden ikke skal nå lengre bort enn ytterkanten av #wrapper-main-menu. Derfor er margin-right: 200px; valgt til nettopp 200. 200 er større enn bredden i høyre kolonne (rød bakgrunn har bredde 161 piksler). Slik blir det litt luft mellom teksten i hovedområdet og den røde kolonnen. Dette er både genialt og litt vrient på en gang. Det er en del baller å holde styr på, og det er lurt å utvikle gradvis med prøv og feil. Samtidig er det en logikk bak, og det er lurt å prøve å sette seg skikkelig inn i tankesettet og virkemåten til boksmodellen i CSS.

Er vi ferdige da? Nesten. Det gjenstår litt finpuss. Slik ser det ut nå i nettleseren Safari for Mac:

Hvis vi fjerner alle border-reglene vi har brukt som hjelp for å tydeliggjøre boksene, ser det enda bedre ut. I tillegg må bakgrunnen i toppen farges grå, og logoen skal tilsynelatende gå ned i hovedområdet. Men – også her kan en trikse det til med hendige bakgrunnsbilder og repeat-x-egenskapen. Du kan prøve selv på dette.

Håper dette var nyttig. Fins det andre, alternative måter å løse dette på? Eller har du spørsmål? Føl fri til å legge igjen en kommentar (ingen spørsmål er dumme).

Dette innlegget har 5 kommentarer. Gjerne bidra :-)

Av: Svend Andreas Horgen, høgskolelektor og faglærer i blant annet PHP og Ajax

Blogginnlegget Layout med CSS, flere kolonner (del 1) presenterte designet på en webside laget i PhotoShop. I dette innlegget gjennomgås CSS-kode som kan brukes for å realisere dette designet. La oss starte med å analysere hvilke grunnelementer websiden er bygget opp av, og deretter arbeide oss fram til en fullstendig kode som fungerer likt i alle nettlesere.

Hvilken struktur har denne siden? Den har en toppseksjon, en meny til venstre, en høyremarg og et hovedområde med selve innholdet for hver side, i midten. Det er noen kompliserende elementer som at siste del av logoen «UnderstandIT» skal gå ned fra toppseksjonen og inn i hovedområdet.

I tillegg er det et hvitt område nederst i venstremargen som skal gå inn helt til hovedområdet. Hvordan løse logoen? Den er egentlig enkel: Vi kan se på logoen som et bilde som ser slik ut:

Altså må nedre del av logoen ha samme bakgrunnsfarge som menyen (blå) og hovedinnholdet (hvit). Det blir i så måte viktig at menyen har nøyaktig riktig bredde. Det kan vi lett få til med CSS. Vi trenger ikke se på boksen i venstremargen enda, så la oss heller se på strukturen bak websiden:

Er du enig i at strukturen er nogenlunde slik? Njaaa, ikke helt. Den røde margen til høyre er vrien, fordi den går oppover i toppseksjonen. En vanlig feil når en jobber med CSS er å tenke for komplisert til å begynne med. Det er bedre å tenke enkelt og utvide. En bedre start vil være å tenke en toppseksjon, en meny og en innholdsseksjon. Om vi lager tre div-bokser, og lar den ene flyte til venstre, så vil den andre skyves til høyre i stedet for å starte på en ny linje. En div vil i utgangspunktet oppfattes som en boks, og for å synliggjøre hvor boksen befinner seg når vi tester, kan vi sette på border-style, border-width og border-color. Dette er et lurt triks i testfasen, men det skal ikke være med i den endelige CSS-koden.

I utgangspunktet vil tre div-bokser etter hverandre komme under hverandre. Det vi trenger er å endre flyten slik at den ene div-boksen (menyen) er til venstre for div-en som representerer hovedinnholdet. Dette løser vi ved å angi float: left. Da vil etterfølgende div-bokser «flyte» rundt den som har float:left. Altså blir CSS-koden slik:

#header {
	height: 100px; 
	border-style: dotted; 
	border-width: 2px; 
	border-color: blue; 	
}

#content {
	border-style: dotted; 
	border-width: 2px; 
	border-color: green; 
}

#menu {
	float: left; 
	width: 161px; 
	border-style: dotted; 
	border-width: 2px; 
	border-color: red; 
}

HTML-koden består ganske enkelt av tre div-bokser. Når vi bruker en id i hver boks, vil riktig CSS-regel slå til. Altså vil id="header" bety at regelen #header i CSS-koden blir brukt.

<body>
	<div id="header">
		Toppseksjon her
	</div> 

	<div id="menu">
		 - home <br /> 
		 - about <br /> 
		 - partners <br /> 
		 - bla bla <br />
		 - menu item <br />
		 - contact
	</div> 
		
	<div id="content">
			Innhold her: Lorem ipsum dolor sit amet, 
			og så videre...
	</div>

</body>

Det som skjer er at teksten i div-en med id="content" vil flyte rundt menu-div-en. Problemet oppstår i det vi får mye tekst i content-div-en. Da flyter teksten inn under menu-div-en. Se figuren under. Vi ønsker jo at venstremargen skal være blå og gå helt ned. Da kan ikke teksten flyte inn i margen på denne måten.

Løsningen på akkurat dette problemet er ganske enkel: Angi at content-div-en skal ha en venstremarg som starter flere piksler til venstre enn den totale bredden på menu-div-en! Husk at #menu hadde definert width: 161px. Dermed kan vi si at venstremargen til div-boksen med hovedinnholdet (id=»content») skal starte for eksempel 175 piksler fra nettleservinduets venstre side:

#content {
	margin-left: 175px; 
	padding-left: 30px;	
	padding-bottom: 20px; 
	border-style: dotted; 
	border-width: 2px; 
	border-color: blue; 
}

Resultatet blir slik (tar ikke med selve innholdet heretter i figurene, kun strukturen)

Hvis du tester dette selv, så ser du et viktig avvik fra den opprinnelige PhotoShop-skissen. Menyboksen blir bare så høy at det akkuart er plass til innholdet i menyen. Hvis innholdet i content er kjempelangt, så blir det et stort tomt område under menyen. Hvordan få menyen til å strekke seg nedover så langt innholdet i hovedboksen er?

Det blir feil å tenke at menyen må få definert en høyde med height=tallverdi. Det er nemlig umulig å beregne høyden på forhånd. For det første vil hver side på nettstedet ha ulikt innhold, og dermed også ulik høyde i content-div-en. For det andre kan brukeren lage vinduet stort eller lite, og det påvirker lengden på content-div-en. Videre kan brukeren øke tekststørrelsen, noe som ytterligere øker lengden.

Hmmmmmm. Hvordan løse dette? Svaret får du i del 3 (siste del). Da skal vi se på mer avanserte teknikker som hjelper til med å realisere den fullstendige løsningen basert på PhotoShop-skissen vår. Var dette lærerikt så langt, eller bør noe forklares bedre? Har du spørsmål? Føl fri til å legge igjen en kommentar (ingen spørsmål er dumme).

Dette innlegget har 8 kommentarer. Gjerne bidra :-)

Av: Svend Andreas Horgen, høgskolelektor og faglærer i blant annet PHP og Ajax

Dette innlegget er småteknisk, men jeg vil dele noen verdifulle CSS-erfaringer med deg. CSS er en standard brukt innen webutvikling og gjør det mulig å utforme slik at alle websider blir like med minimalt med kode.

Jeg fikk i oppdrag å lage en webside for forskningsprosjektet UnderstandIT. Dette er et EU-prosjekt, og websiden må derfor ha engelsk innhold. Designeren vår, Therese, lagde et forslag til utseende. Dette er vist under (klikk for større versjon i nytt vindu). Se nøye på bildet. Hvilke elementer har vi å gjøre med her?

Dette er egentlig en nokså kompleks layout. Det fins flere muligheter for å realisere en slik webside med HTML-kode. Tidligere har jeg brukt tabeller (table-taggen) til dette, og hvis en bruker verktøy ala DreamWeaver eller FrontPage, får en gjerne generert en hel masse tabeller nøstet i tabeller nøstet i tabeller nøstet i…. Det er lite fleksibelt og vanskelig å vedlikeholde, og tabeller anbefales ikke brukt til layout.

Men hvordan lage en såpass komplisert side med CSS? Er denne siden komplisert? Gruble gruble…. Løsningen jeg kom fram til, beskrives i et kommende blogginnlegg om noen dager.

Nå spør jeg deg: Hvorfor er dette komplisert? Hvilke elementer her byr på utfordringer? Hvilke særegenheter vil du si at siden er bygget opp av, som kan by på problemer? Legg gjerne igjen en kommentar nedenfor. Dine innspill er veldig nyttige og kanskje du lærer litt på veien!

Dette innlegget har 3 kommentarer. Gjerne bidra :-)

Theme Design by devolux.nh2.me