Met behulp van frames kan een auteur een browservenster verdelen in meerdere (rechthoekige) vakken. Meerdere documenten kunnen, ieder in hun eigen frame (kader), worden weergegeven in één venster. In grafische browsers kan in deze frames zelfstandig worden geschoven (ge'scroll'd), en links kunnen het in een frame weergegeven document verversen, zonder de andere documenten te beïnvloeden.
Een frameset is een bepaalde samenstelling van frames. Om frames te gebruiken, moet een document een frameset definiëren, zodat andere documenten in de frames kunnen worden weergegeven. Dit document wordt het frameset-document genoemd. Het frameset-document dient ook alternatieve niet geframede inhoud te bevatten in een <NOFRAMES>
-element.
Het HTML 4-frames model heeft belangrijke ontwerpfouten die toegankelijkheidsproblemen voor webgebruikers veroorzaken. Frames dienen alleen met grote zorgvuldigheid te worden gebruikt. De 'Guide to frames' <http://www.htmlhelp.com/design/frames/> van de Web Design Group bevat richtlijnen voor het juiste gebruik van frames, naast een beschrijving van de benodigde HTML-syntax.
Zorg ervoor dat in het frameset-document (het HTML-document dat de <FRAMESET>
en <FRAME>
elementen bevat), de individuele frames een naam hebben gekregen met behulp van het NAME
-attribuut. Het volgende voorbeeld maakt een bovenframe genaamd "navigatie" en een onderframe genaamd "tekst":
<FRAMESET ROWS="*,3*">
<FRAME NAME="navigatie" SRC="navigatie.html">
<FRAME NAME="tekst" SRC="tekst.html">
<NOFRAMES><BODY>
<!-- Alternatieve geen-frames-versie -->
</BODY></NOFRAMES>
</FRAMESET>
In het document met de link gebruik je vervolgens het TARGET
-attribuut om het frame aan te geven, dat moet worden gebruikt om de link in weer te geven. (De waarde van het TARGET
-attribuut moet overeen komen met de waarde van het NAME
-attribuut van het doelframe.) Je kunt het doel aangeven voor een link (bijv. <A TARGET="tekst" HREF=...>
) of voor een formulier (bijv. <FORM TARGET="tekst" ACTION=...>
). Verder kun je <BASE TARGET=...>
gebruiken om het standaard doelframe te veranderen voor het gehele document (normaal is de standaardwaarde voor het doelframe "_self", het huidige frame).
Als er nog geen frame bestaat met de naam die je gebruikt voor het TARGET
-attribuut, zal er een nieuw browservenster worden geopend, en zal dit venster de gebruikte naam krijgen toegewezen. Verder zal ook TARGET="_blank"
een nieuw, onbenoemd browservenster openen.
In HTML 4.0 is de TARGET
attribuutwaarde ongevoelig voor hoofdletters en kleine letters, dus abc
en ABC
verwijzen beide naar hetzelfde frame/venster, en _top
en _TOP
hebben beide dezelfde betekenis. De meeste browsers behandelen de TARGET
attribuutwaarde echter als hoofdlettergevoelig en herkennen ABC
niet als zijnde hetzelfde als abc
, of _TOP
als zijnde het speciale geval _top
.
Verder bevatten sommige browsers een beveiligingsfunctie, die voorkomt dat documenten worden gekaapt door framesets van derden. Als de link in een document als doel een frame heeft, dat is gedefinieerd door een frameset-document dat op een andere server is geplaatst dan het document zelf, dan openen deze browsers de link in een nieuw venster.
Er zijn twee basistechnieken om meerdere frames gelijktijdig bij te werken met een enkele link: De op HTML gebaseerde techniek linkt naar een nieuw frameset-document dat de nieuwe combinatie van frames opgeeft. De op JavaScript gebaseerde oplossing gebruikt het onClick
-attribuut van een link om het extra frame (of frames) bij te werken.
De op HTML gebaseerde techniek kan met TARGET="_top"
naar een nieuw frameset-document linken (de gehele frameset wordt vervangen), maar er is een alternatief als de te vervangen frames onderdeel zijn van een genestte frameset. Gebruik een tweede frameset-document binnen het initiële frameset-document, om de genestte frameset in te stellen. Bijvoorbeeld:
<FRAMESET COLS="*,3*">
<FRAME SRC="tekst.html" NAME="Tekst">
<FRAME SRC="frameset2.html" NAME="Weergeven">
</FRAMESET>
Een link kan nu de code TARGET="Weergeven"
gebruiken om alle frames die worden gedefinieerd door frameset2.html
, tegelijk te vervangen.
De op JavaScript gebaseerde oplossing gebruikt het onClick
-attribuut van een link om de tweede update uit te voeren. Bijvoorbeeld:
<A HREF="URL1" TARGET="Frame1"
onClick="top.Frame2.location='URL2';">Frames bijwerken</A>
Deze link zal Frame1
normaal bijwerken met URL1
. Als de browser van de lezer JavaScript ondersteund (en het heeft ingeschakeld), dan zal Frame2
ook worden bijgewerkt (met URL2
).
Als je de auteur bent is dat heel makkelijk. Je hoeft alleen maar het TARGET
-attribuut toe te voegen aan de link die de lezers naar het bedoelde 'buiten'-document brengt. Geef het de waarde _top
.
In veel van de huidige browsers is het niet mogelijk om een frame in het volledige venster weer te geven, het is in ieder geval niet erg gemakkelijk. De lezer zou de URL van het gewenste frame moeten kopiëren, en deze URL dan handmatig moeten opvragen.
Ik zou willen aanbevelen dat auteurs, die deze optie aan hun lezers willen aanbieden, een link naar het document toevoegen onderaan in het document zelf, met het TARGET
-attribuut ingesteld op _top
, zodat het document in het volledige venster wordt weergegeven als de link wordt gevolgd.
Als de subdocumenten van een frameset-instantie direct worden benaderd, verschijnen ze zonder de context van de bovenliggende frameset.
Als de browser van de lezer JavaScript-ondersteuning heeft ingeschakeld, zal het volgende script de frameset herstellen:
<SCRIPT TYPE="text/javascript">
<!--
if (parent.location.href == self.location.href) {
if (window.location.replace)
window.location.replace('frameset.html');
else
// veroorzaakt wat problemen met de terug-knop, maar het werkt
window.location.href = 'frameset.html';
}
// -->
</SCRIPT>
Een meer algemene aanpak is een "herstel frames" link:
<A HREF="frameset.html" TARGET="_top">Herstel Frames</A>
Merk op dat je in beide gevallen een apart frameset-document nodig heeft voor elk inhoud-document. Als je naar de standaard frameset-document linkt, krijgt de lezer ook het standaard inhoud-document, in plaats van het inhoud-document dat hij/zij probeerde te bereiken. Deze frameset-documenten zouden automatisch gegenereerd moeten worden, om het gedoe en de foutkans te voorkomen bij het met de hand maken.
Merk op dat je het probleem met het 'bookmarken' van frameset-instanties kunt voorkomen, door naar deze aparte frameset-documenten te linken met gebruik van het TARGET="_top"
-attribuut, in plaats van te linken naar de aparte inhoud-documenten.
"Geframed worden" heeft te maken met de weergave van je documenten binnen de frameset van iemand anders, zonder jouw toestemming. Dit kan per ongeluk gebeuren (de auteur van de frameset vergat om TARGET="_top"
te gebruiken bij het linken naar jouw document) of met opzet (de auteur van de frameset wilde jouw inhoud weergeven met zijn/haar eigen navigatie- of reclame-frames).
Om het "framen" van andermans documenten te voorkomen, moet je TARGET="_top"
toevoegen aan alle links, die leiden naar documenten buiten de bedoelde omgeving.
Er is helaas geen betrouwbare manier om vast te leggen, dat een bepaald document moet worden weergegeven in het volledige browservenster, in plaats van in het huidige frame. Als je jouw server kunt instellen om de niet-standaard header Window-Target: _top
te versturen in de HTTP response, zullen Netscape browsers jouw document weergegeven in het volledige browservenster. Andere browsers negeren deze header echter, en het werkt niet om <META HTTP-EQUIV="Window-target" CONTENT="_top">
in het document zelf te gebruiken om de HTTP response na te doen.
Een andere oplossing is het gebruik van <BASE TARGET="_top">
in het document, maar dit geeft alleen maar het standaard doelframe voor links in het huidige document aan, niet voor het document zelf.
Als JavaScript is ingeschakeld in de browser van de lezer, verwijderd het volgende script automatisch alle bestaande framesets:
<SCRIPT TYPE="text/javascript">
<!--
if (top.frames.length!=0)
top.location=self.document.location;
// -->
</SCRIPT>
Een alternatief script is
<SCRIPT TYPE="text/javascript">
<!--
function breakOut() {
if (self != top)
window.open("my URL","_top","");
}
// -->
</SCRIPT>
</HEAD>
<BODY onLoad="breakOut()">
Dit is helaas niet mogelijk. Tijdens het navigeren door een site waar frames worden gebruikt, zal de URL niet veranderen als de documenten in de individuele frames veranderen. Dit betekent dat er geen methode is om een de combinatie van documenten aan te geven, die in de huidige instantie van de frameset voorkomen.
De auteur kan een link aanbieden naar meerdere frameset-documenten, een voor elke combinatie van frame-inhoud. Deze frameset-documenten kunnen automatisch aangemaakt worden, mogelijk zelfs à al minute met een CGI-programma. In plaats van te linken naar de afzonderlijke inhoudsdocumenten, kan de auteur ook linken naar deze aparte frameset-documenten met behulp van TARGET="_top"
. Op die manier zal de URL van het huidige frameset-document altijd die combinatie van frames aangeven, die wordt weergegeven op dat moment. Zo kunnen links, bladwijzers, enz. normaal werken.
Het verwijderen van de rand om frames gebeurt door zowel de frame-randen niet te tekenen als het verwijderen van de ruimte tussen de frames. De twee belangrijkste frames-herkennende browsers gebruiken verschillende niet-standaard attributen om dit voor elkaar te krijgen.
Netscape herkent het BORDER
-attribuut in FRAMESET
. Dit kan op 0 worden gezet, waardoor de rand niet zal worden getoond, en de tussenruimte zal op nul worden gezet.
Microsoft Internet Explorer herkent de FRAMEBORDER
- en FRAMESPACING
-attributen in FRAMESET
, maar in sommige versies ook in FRAME
voor individuele frames. Beide attributen moeten op 0 worden gezet.
De best ondersteunde methode om randloze frames weer te geven is dus <FRAMESET ... BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>
.
Merk op dat deze attributen niet-standaard zijn, en geen deel uitmaken van de HTML 4 specificaties. Ook maakt het verwijderen van de rand om een frame het onmogelijk om het van grootte te veranderen, aangezien deze rand in de meeste GUI's wordt gebruikt om de afmeting van het venster te veranderen.
De enige manier waarmee je een een frame krijgt met wel een vertikale, maar geen horizontale schuifbalk, is door het frame te definiëren met SCROLLING="auto"
(de standaardwaarde), met inhoud die geen horizontaal verschuiven vereist. Er bestaat geen manier om een frame in te stellen met wel de ene maar niet de andere schuifbalk. Het gebruik van SCROLLING="yes"
dwingt schuifbalken in beide richtingen af (zelfs wanneer ze niet nodig zijn), en het gebruik van SCROLLING="no"
voorkomt alle schuifbalken (zelfs wanneer verschuiven nodig is de inhoud van het frame te bereiken). Er zijn geen andere waardes voor het SCROLLING
attribuut.
De titel die wordt weergegeven is de titel van het frameset-document, in plaats van de titels van een van de pagina's in de frames. Link naar een nieuw frameset-document met behulp van TARGET="_top"
om de weergegeven titel te wijzigen (hiermee de gehele frameset vervangend).
Netscape Navigator schijnt met pixels vastgelegde frame-afmetingen af te ronden naar het dichtstbijzijnde gehele percentage, en deze op percentages gebaseerde afmetingen te gebruiken bij het opmaken van de frames. Dus zullen frames met in pixels opgegeven afmetingen, met een iets andere grootte worden afgebeeld dan opgegeven in het frameset-document. Er bestaat geen methode om dit gedrag te voorkomen, en de afrondingsmarge zal afhangen van de exacte afmetingen van het browservenster.
Om dit op te vangen, zou je jouw site zodanig moeten ontwerpen, dat deze zich aanpast aan variaties in de browser's weergave. Dat is altijd al een goed idee, maar zeker in dit geval.
Het fundamentele probleem met het systeem van frames is, dat framesets instanties in de browser aanmaken, die niet adresseerbaar zijn. Zodra een van de frames binnen een frameset niet meer zijn oorspronkelijke inhoud heeft, is er geen manier meer de huidige instantie van de frameset te adresseren. Zo'n frameset instantie is moeilijk om te 'bookmarken' - en onmogelijk om te linken of te indexeren. Het is onmogelijk om te verwijzen naar zo'n frameset instantie in andere media. Als de sub-documenten van zo'n frameset instantie direct worden benaderd, verschijnen ze zonder de context (omgeving) van de bovenliggende frameset. Basisfuncties van de browser (bijv. afdrukken, terug/vooruit navigeren in de browser's geschiedenis) gedragen zich anders met framesets.
Verder richten frames zich op lay-out in plaats van op informatie-structuur, en veel auteurs van geframede sites verwaarlozen het aanbieden van bruikbare alternatieve inhoud in het <NOFRAMES>
-element. Deze twee factoren veroorzaken toegankelijkheidsproblemen voor browsers die significant afwijken van de verwachtingen van de auteur, en voor zoekmachines.
Zie voor verdere discussie <URL:http://www.htmlhelp.com/design/frames/whatswrong.html>
Zoekmachines kunnen rechtstreeks verwijzen naar in frames opgenomen inhoudelijke documenten, maar ze kunnen niet verwijzen naar de combinaties van frames waarvoor deze inhoudelijke documenten zijn ontworpen. Dit is het gevolg van een fundamenteel gebrek in het ontwerp van frames.
Zoekmachines proberen hun gebruikers te voorzien van links naar nuttige documenten. Veel in frames opgenomen inhoudelijke documenten zijn moeilijk te gebruiken als ze direct benaderd worden (buiten de frameset die voor hen bedoeld is), dus is er weinig voordeel als zoekmachines links aanbieden naar zulke documenten. Daarom negeren veel zoekmachines frames helemaal, en gaan ze verder met het indexeren van meer nuttige (niet-geframede) documenten.
Zoekmachines indexeren wel uw <NOFRAMES>
-inhoud, en alle inhoudelijke documenten die bereikbaar zijn via uw <NOFRAMES>
-inhoud. Zulke inhoudelijke documenten zouden nuttig moeten zijn indien ze direct benaderd worden vanaf een zoekmachine-link.