2014-07-25 7 views
14

Kurzbeschreibung der Ausgabe:Schriftgröße CSS-Werte basierend auf Schatten DOM Wurzel

ich nach einem Weg suche Schriftgröße basierend Werte zu setzen (ähnlich eine Eigenschaft auf einen em-Wert zu setzen) in einem Element innerhalb eines Schatten-Doms relativ zum Schatten-Host, unabhängig von der Schriftgröße des Eltern-Elements im Schatten-Dom. Ähnlich wie rem-values, aber mit dem Schatten als root anstelle des html root.

Der Grund dafür ist in der Lage, Inhalt wie ein Widget (das mit Schatten dom eingefügt wird) an einer Stelle zu skalieren. Wenn Eigenschaften, die auf der Schriftgröße basieren, auf diese Weise skaliert werden können, kann ein ganzes Widget in jedem Kontext skaliert werden, ohne dass viele CSS-Werte festgelegt werden müssen, damit es an jedem Ort passt.

Lange Beschreibung der Ausgabe:

ich für einen Weg, um Größe Text (font-size) auf einem bestimmten Element in der DOM-basierte Suche, innerhalb dieses Elements verschiedene Teile des Inhalts skalieren zu können, basierend auf diesem Umhüllungselement (gut für Widgets und so). Dies ist nicht nur für den eigentlichen Text, es ist oft gut, viele CSS-Werte auf Schriftgröße basieren, so dass die Elemente visuelle Layout skalieren mit der Größe des Textes (wie Padding, Rand-Radius und Schatten). Wenn alles auf em-Werten basiert, kann dies ein wenig unordentlich werden. Wenn es innerhalb des Elements mehrere Ebenen der Vererbung von Schriftgrößen gibt und ich die erste Ebene vergrößern möchte, ohne die zweite zu ändern, müsste ich die em der ersten Ebene im Dom vergrößern, während ich jedes Element der zweiten Ebene reduzieren würde (das auf dieser ersten Ebene berechnet wird), damit der Text von Unterelementen die gleiche Größe behält. Dies ist in vielen Fällen nicht optimal.

Eine nette Lösung basiert auf Root EM (rem), also hat das Ändern einer Ebene des Doms keinen Einfluss auf die Unterelemente. Wenn ich jedoch den gesamten Text innerhalb dieser Umhüllungselemente vergrößern/verkleinern möchte (an einer Stelle), ohne die anderen Elemente auf der gleichen Seite zu beeinflussen, müsste ich die Rem-Werte aller Schriftgrößen vergrößern/verkleinern Elemente innerhalb dieses Umhüllungselements.

Ich habe vor kurzem begonnen, in Webkomponenten mit Shadow DOM und Vorlagen zu suchen. In Template-Tags ist css eingekapselt, was großartig ist, da das Design dieser Box/Widget/Komponente eigenständig gestylt werden kann, ohne an den Rest des Designs, unerwünschte vererbte Werte und dergleichen denken zu müssen. Endlich eine gute Möglichkeit, unabhängige Komponenten zum Aufbau einer Webseite zu machen. Aber es wäre toll, wenn ich eine Art Template-Root-Schriftgröße für die Vorlage selbst festlegen könnte. Wenn ich also ein Element innerhalb der Vorlage als font-size 2rem (oder eine andere ähnliche Einheit) einstelle, dann wäre die Schriftgröße dieses Elements 2x die Stammschriftgröße der Vorlage, unabhängig von der Schriftgröße im Host Element, wo diese Vorlage verwendet wird, und unabhängig von der Schriftgröße des Stamms der Seite (das HTML-Element).

Wenn ich mit Rem-Werten innerhalb einer Vorlage getestet wurde, basierte es immer noch auf der Schriftgröße der Seitenwurzel (HTML-Tag). Ich habe auch vw-Werte getestet, aber dies basiert auch auf dem gesamten Ansichtsfenster und nicht nur auf dem eingekapselten Bereich (der Schattenwurzel).

Ich habe viele Artikel über Shadow DOM angeschaut, aber ich konnte keine Lösung zu diesem Thema finden. Irgendwelche Vorschläge?

Was (vereinfachte Beispiele) geschieht:

<html style="font-size: 16px"> 
    <body style="font-size: 12px"> 
     I am 12px large 

     <!-- em, based on the body in this case --> 
     <div style="font-size: 1.5em"> 
      I am 18px large 

      <div style="font-size: 1.5em"> 
       I am 27px large 
      </div> 
     </div> 

     <!-- rem, based on the styles of the html element --> 
     <div style="font-size: 1.5rem"> 
      I am 24px large 

      <div style="font-size: 1.5rem"> 
       I am 24px large 
      </div> 
     </div> 
    </body> 
</html> 

Was ich will:

<html style="font-size: 16px"> 
    <body style="font-size: 12px"> 
     I am 12px large 

     <div style="font-size: 1.5em"> 
      I am 18px large 
     </div> 
     <div style="font-size: 1.5rem"> 
      I am 24px large 
     </div> 

     <template> <!-- Simulates that it is inserted into the DOM by using shadow elements --> 
      <style> 
       :root{ /* Or something like that */ 
        font-size: 20px; /* This is the simulated "template root fontsize" */ 
       } 
      </style> 

      <div style="font-size: 1.5trem"> <!-- Based on the template root fontsize --> 
       I am 30px large 

       <div style="font-size: 2trem"> 
        I am 40px large 
       </div> 
      </div> 

     </template> 
    </body> 
</html> 

Dies würde einen Platz geben (das: Wurzelteil des Beispiels oben) alle relativ font- zu steuern Größen innerhalb dieser Komponente, und dies kann dann mit nicht-relativen Schriftgrößen wie px oder anderen normalen CSS-Werten kombiniert werden.

Antwort

0

Der Selektor :host bestimmt das Element, das den Schattenstamm enthält. Dies hat den gleichen Effekt wie das Styling des Host-Elements mit den äußeren CSS/Styles (z. B. <div id="rootelm" style="font-size:20px"></div> für das Beispiel unten). Wenn Sie :host statt Ihrer falschen :root Selektor verwenden, sollte es wie erwartet funktionieren. Hier ein Beispiel:

<!DOCTYPE HTML> 
<html style="font-size: 16px"> 
    <body style="font-size: 12px"> 
     I am 12px large 

     <div style="font-size: 1.5em"> 
      I am 18px large 
     </div> 
     <div style="font-size: 1.5rem"> 
      I am 24px large 
     </div> 

     <div id="rootelm"></div> 

     <template id="testtemplate"> 
      <style> 
       :host{ /* Our new selector */ 
        font-size: 20px; /* This is the "template root fontsize" */ 
       } 
      </style> 
      <div style="font-size: 1em"> 
       I am 20px large 
       <!-- Absolute size for comparison --> 
       <div style="font-size: 20px">I am 20px large as well</div> 
       <div style="font-size: 2em"> 
        I am 40px large 
        <!-- Absolute size for comparison --> 
        <div style="font-size: 40px">I am 40px large as well</div> 
       </div> 
      </div> 
     </template> 

     <script> 
      var shadow = document.querySelector('#rootelm').createShadowRoot(); 
      var template = document.querySelector('#testtemplate'); 
      shadow.innerHTML = template.innerHTML; 
     </script> 
    </body> 
</html> 

plunker

EDIT: Aktualisierte Plunker mit JS machen Schrift auf das Element relative Größe, die den Schatten-Stamm befindet. Das Skript ist unten wiedergegeben.

+0

Dies löst das Problem nicht. Ich möchte basierend auf der Schattenwurzel, unabhängig vom übergeordneten Element, auf Schriftgröße basierende Werte festlegen. Dann kann ich den Vorlagenstamm mit Medienabfragen steuern und den Inhalt relativ dazu skalieren, anstatt Medienabfragen für alle Unterelemente zu haben. em-Werte basieren auf übergeordneten Rem-Werten im HTML-Wurzelverzeichnis. In meinem Beispiel ist html font-size 16, und Vorlage root ist 20. Ich möchte in der Lage sein, ein Element auf 1.5x Vorlage Stammschriftgröße (wie "Ich bin 30px groß" in meinem Beispiel) und ein Unter -Elemente davon 2x Template Root (40px) unabhängig von der Eltern (das ist 30px). – henit

+0

@henit Ich glaube nicht, dass das nur mit CSS möglich ist, aber es kann mit Javascript gemacht werden. Ich habe die Antwort und den [bottker] (http://plnkr.co/edit/P1KOZ4NGmpycGgCgRpSq?p=preview) mit einem Skript aktualisiert, das Rem-Schriftgrößen relativ zum Schattenstamm ändert. Öffnen Sie den Plocker und ändern Sie die Größe des Fensters, um die Änderungen der Medienabfrage zu sehen. – quantumwannabe

0

Das Problem ist, dass Sie ein DOM-Objekt eine "Schattenwurzel" aufrufen, was Sie haben, ist ein anderes DOM-Element, das eine Verzweigung von Root ist. Die Tag-Vorlage hat in HTML5 keine besondere Bedeutung. Es gibt keine "Schattenwurzel". Es gibt mehrere Möglichkeiten, ein Dokument in ein anderes Dokument zu injizieren. Verwenden von iframes, Objekttags, Elementtags. Ich empfehle, keine von ihnen zu tun, da es die Fähigkeit des Dokuments, das richtig pars ist, zusammen mit einer langen Liste anderer zukünftiger Probleme bricht, die Sie haben werden.

Die beste Option besteht darin, ein DOM-Element in CSS zu erstellen, das die Basisattribute aufweist, mit denen Sie beginnen möchten, und mithilfe von css die Unterelemente dieses Elements basierend auf Ihrem CSS zu ändern. Sie können eine DOM-Elementvorlage in CSS erstellen und ihr einen Basisstil zuweisen.

CSS-Datei

template{ 
    font-size: 20px; 
} 

html-Datei

<template> 
    <div style="font-size: 1.5trem"> 
     I am 30px large 
     <div style="font-size: 2trem"> 
      I am 40px large 
     </div> 
    </div> 
</template> 

dies wird jedes DOM-Element gesetzt Vorlage auf die font-size 20px und alle Unter dom Elemente genannt werden auf dem übergeordneten Element ändern sich entsprechend. versuchen Sie auch nicht, inline-Stil auf Elemente verwenden, css-Selektoren können eine Menge Arbeit für Sie tun.

+0

Es scheint (korrigieren Sie mich, wenn ich falsch liege) Sie sind vielleicht nicht vertraut mit der HTML5-Technologie namens Web-Komponenten, eine Reihe von Standards einschließlich Shadow DOM, Templates und mehr. Der Zweck dieser Technologien ist genau, um zu vermeiden, dass Inhalte durch Einbetten, Iframe und ähnliche Wege eingefügt werden müssen. Diese Seite erläutert die Konzepte von Webkomponenten: http://css-tricks.com/modular-future-web-components/ – henit

+0

Shadow DOM funktioniert nur in Chrome, Opera, Android-Browser, Chrome für Android. So funktioniert es nicht in IE, Firefox, Safari, IOS Safari, Opera Mini. Ein "Shadow DOM" wird nur sehr wenig genutzt, wenn Sie wissen, wie man CSS auf ein Element setzt und wie Attribute den DOM-Baum durchqueren. In meinem Beispiel wird die Schriftgröße festgelegt, sodass alle untergeordneten Elemente des Vorlagen-DOM-Elements dann genau die Ausgabe von der Vorlage übernehmen, die in der Frage enthalten war. Auch Shadow-DOM-Status ist "Under Consideration" nicht in Stein gemeißelt. –

+0

Basierend auf der Frage Web Components wird nicht benötigt und ist Overkill. Einfache CSS-Lösungen können dieses Problem lösen, ohne eine nicht vollständig unterstützte Funktion zu verwenden. –

1

nach dem Überprüfen der Web Component-Dokumente. Ihr Beispiel von dem, was Sie tun möchten, sieht nicht wie eine Webkomponente aus. Siehe das folgende Webkomponenten-Beispiel.

im Header des Dokuments würden Sie

<link rel="import" href="web_component_name.html"></link> 

im Körper haben Sie

<my-web-component>Bob</my-web-component> 

Ihre Web-Komponente würde dann eine eigene Datei haben haben würde.

<html> 
    <template id="nameTagTemplate"> 
    <style> 
    .outer { 
     border: 2px solid brown; 
     border-radius: 1em; 
     background: red; 
     font-size: 20pt; 
     width: 12em; 
     height: 7em; 
     text-align: center; 
    } 
    .boilerplate { 
     color: white; 
     font-family: sans-serif; 
     padding: 0.5em; 
    } 
    .name { 
     color: black; 
     background: white; 
     font-family: "Marker Felt", cursive; 
     font-size: 45pt; 
     padding-top: 0.2em; 
    } 
    </style> 
    <div class="outer"> 
     <div class="boilerplate"> 
     Hi! My name is 
     </div> 
     <div class="name"> 
     <content></content> 
     </div> 
    </div> 
    </template> 
    <script> 
    var importDoc = document.currentScript.ownerDocument; 
    var nameBadgePrototype = Object.create(HTMLElement.prototype); 
    nameBadgePrototype.createdCallback = function() { 
     var shadow = this.createShadowRoot(); 
     var template = importDoc.querySelector('#nameTagTemplate'); 
     shadow.appendChild(template.content.cloneNode(true)); 
    }; 
    document.registerElement("my-web-component", { 
     prototype: nameBadgePrototype 
    }); 
    </script> 
</html> 

Ihr Beispiel von dem, was Sie versuchen zu tun und was Sie wirklich wollen, stimmen nicht überein. Nach ein paar Antworten von dir sehe ich, dass du Web Components machen willst. Dies ist nicht das, was Sie in Ihrem Beispiel zeigen, was Sie zu tun versuchen. Auch dieser Code funktioniert nur, wenn Sie die richtigen Flags in Ihrem Chrome Canary-Webbrowser aktiviert haben. Es wird standardmäßig nicht funktionieren und der Benutzer muss die richtigen Beta-Einstellungen aktivieren, damit es funktioniert. Selbst in einem Intranet würde ich die Verwendung von Web-Komponenten noch nicht empfehlen, da es immer noch sehr viel Beta ist und Sie viele Probleme haben werden, dies bei vielen internen Benutzern aufrechtzuerhalten. Benutzer finden Möglichkeiten, die Einstellungen im Browser jederzeit zurückzusetzen. Benutzer brechen alles neu und glänzend.

+0

Mein Beispiel war kein getesteter Code, es war (wie erwähnt) ein pseudoähnliches Beispiel, um zu zeigen, was ich erreichen wollte. Ich habe tatsächliche Tests von Web Components Code (mit Shadow DOM, Templates und Custom Elements) durchgeführt und die Arbeit in Chrome (nicht Beta) völlig in Ordnung. Und Polyfills für alle gängigen Browser existieren. Ich bin (wie bereits erwähnt) bewusst, dass WC noch nicht weit verbreitet ist, aber das ist für diese Anforderung irrelevant. Es geht darum herauszufinden, ob es möglich ist, em-ähnliche Schriftgrößenwerte auf die Schriftgröße der Schattenwurzel zu beziehen, genau wie Rem für das Dokumentenstammverzeichnis. Für zukünftige Verwendung. – henit

+0

Ich stimme zu, dass WC noch nicht für Produktionsumgebungen geeignet ist. Es ist jedoch ein wenig breiter unterstützt als das, was Sie gesagt haben. Shadow Dom wird in Chrome 25+ (mit unserem Webkit-Präfix von 35) unterstützt, v37 ist die aktuellste nicht-Beta-Version. Benutzerdefinierte Elemente werden in Chrome 33+ unterstützt. HTML Templates werden in Chrome 26+ und Firefox 22+ unterstützt (FF 31 ist das neueste). Das Polymer-Projekt hat JavaScript-Polyfills veröffentlicht, wodurch die Funktionen in den zwei neuesten Versionen aller gängigen Browser funktionieren. Ich habe die Polyfüllungen noch nicht selbst getestet. – henit

+0

Ich werde das testen müssen, da alles, was ich gelesen habe, es noch sehr viel noch in der Beta in Chrome gibt, zusammen mit noch nicht in Firefox implementiert werden. Wenn Sie Quellen für den aktuellen Status haben, die etwas anderes anzeigen, poste sie bitte auf dieser Seite als relevant für WC. –

Verwandte Themen