Cette série d'articles est indexée sur NgateSystems.com. Vous y trouverez également une fonction de recherche par mot-clé très utile.
Dernière révision : 24 novembre
Le post 4.2 a révélé que si vous souhaitez que votre application Web apparaisse dans les recherches sur le Web, vous devez vous assurer que :
Si votre logiciel est principalement destiné aux utilisateurs d'ordinateurs de bureau, c'est une énorme nuisance - mais c'est la vie. Voyons comment vous pourriez résoudre le problème de manière systématique.
La conception réactive utilise la capacité « intégrée » du style CSS pour tester la largeur du périphérique d'affichage et ajuster le formatage en conséquence. Tout cela se produit automatiquement dans le navigateur - mais vous devez toujours fournir des instructions explicites sur ce qui se passe à chaque "point d'arrêt" (la largeur de l'écran à laquelle un nouveau style spécifique à la largeur doit être appliqué).
Le style CSS standard que vous avez utilisé jusqu'à présent dans cette série permet d'obtenir ces effets adaptatifs en utilisant une technique appelée « requêtes multimédias ». Mais dans cet article, je vais vous présenter une « bibliothèque ouverte » appelée Tailwind. Ceci est fait sur mesure pour un style réactif et présente de nombreux avantages supplémentaires.
Voici un exemple de style Tailwind qui contraint un titre centré à 95 % de la largeur de l'écran sur des écrans jusqu'à 768 px de large. Au dessus de cette largeur, le titre centré est contraint à 60% de la largeur de l'écran :
<h1> <p>Previously in this series, you've seen styles applied to HTML elements like <p> by adding> <p>The essence of Tailwind is that it provides a system of single-purpose "utility classes", each of which applies a specific set of styles to an element. The class names are chosen judiciously to provide a meaningful and practical expression of styling intentions. The example below styles a <p> element with 4rem padding on all four sides and a background color of light gray.<br> </p> <pre class="brush:php;toolbar:false"><div> <p>Here, in bg-blue-500, bg says that this is a background style, blue sets the background colour to blue and 500 sets the colour "intensity" to a mid-value on a scale of 100 (light) to 900 (dark).</p> <p>This is fine in its way, but the system may only become of interest to you when I tell you that you can make the tailwind utility classes responsive by simply adding a prefix to the style.</p> <p>Tailwind recognizes the following screen-width "breakpoints":</p> <div><table> <thead> <tr> <th>Prefix</th> <th>Screen Size</th> <th>Minimum Width</th> </tr> </thead> <tbody> <tr> <td>sm</td> <td>Small devices</td> <td>640px</td> </tr> <tr> <td>md</td> <td>Medium devices</td> <td>768px</td> </tr> <tr> <td>lg</td> <td>Large devices</td> <td>1024px</td> </tr> <tr> <td>xl</td> <td>Extra large devices</td> <td>1280px</td> </tr> <tr> <td>2xl</td> <td>2x Extra large devices</td> <td>1536px</td> </tr> </tbody> </table></div> <p>A style class such as "bg-gray-200" might thus be made to apply only to screens larger than 640px by specifying it as "sm:bg-gray-200".</p> <p>The "This div has padding on all sides." example above could thus be made to display its paragraph with a blue background on screens with a maximum width of 640px and green on screens larger than this by styling it as follows:<br> </p> <pre class="brush:php;toolbar:false"><p> <p>Because classes to the right take precedence, this makes the default background blue and overrides this with green when the screen is large enough. </p> <p>For a fuller account of the Tailwind system and instructions on how to istall this in your project please see the Tailwind Website.</p> <h3> 3. Adaptive design for Server-side rendered webapps </h3> <p>Responsive design won't help you achieve more drastic effects where the desktop and mobile versions of a webapp are seriously different. Whereas a <strong>responsive design</strong> adjusts a standard pattern"fluidly" to accommodate different screen sizes, an <strong>adaptive</strong> design is prepared to give screen widths tailor-made solutions. </p> <p>Expanding on the "tailoring" theme, you might think of responsive design as creating a single suit made of stretchable fabric that fits anyone. By contrast, adaptive design is like creating multiple tailored suits for different body types.</p> <p>So if, for example, you felt that the mobile customers for your webapp were completely different from your desktop fans, you might want to give each community a tailor-made design (while delivering both under the same URL). </p> <p>Conceptually, the obvious way to express this arrangement would be a displayIsMobile boolean guiding the display of MobileLayout and DesktopLayout components, as follows:<br> </p> <pre class="brush:php;toolbar:false">{#if displayIsMobile} <MobileLayout /> {:else} <DesktopLayout /> {/if}
Mais vous allez maintenant demander "Comment ce booléen displayIsMobile doit-il être initialisé ?"
Lorsqu'un serveur reçoit une requête de navigateur pour myURL/myPage, la première chose qui s'exécute est généralement une fonction load() dans un fichier page.server.js exécutant côté serveur pour fournir les données initiales pour la page. Lorsque page.svelte pour myPage - exécutant également côté serveur - reçoit ces données, il souhaitera effectuer un rendu initial de sa section "modèle" et renvoyer un bloc de code HTML au navigateur. Mais pour ce faire, il lui faut une valeur pour displayIsMobile.
Si vous utilisiez "côté client", la réponse serait simple : utilisez l'objet "window" pour inspecter window.width et définir displayIsMobile en conséquence. Mais dans ce cas, ni le fichier page.server.js ni le fichier page.svelte, exécutés côté serveur comme ils le font, ne peuvent interroger directement le client.
Une option pourrait consister à choisir une valeur par défaut appropriée pour displayIsMobile et à renvoyer un affichage par défaut. Vous pouvez ensuite utiliser une fonction onMount() sur le client pour inspecter ses propriétés de fenêtre et restituer l'affichage par défaut de manière plus appropriée. Cependant, deux conséquences s'ensuivraient :
Donc, si vous voulez faire un bon travail, vous devez devez trouver un moyen de configurer displayisMobile de manière appropriée sur le serveur. De cette façon, vous enverrez une page entièrement rendue au client le plus rapidement possible, optimisant à la fois les performances et le référencement.
Si vous avez lu le message 3.5, vous vous souviendrez que les « en-têtes » qui accompagnent une requête du serveur peuvent être utilisés pour transmettre des informations utiles. Les en-têtes de la demande d'un navigateur pour la page myURL/myPage peuvent-ils dire quelque chose d'utile ?
Heureusement, la réponse est « oui, ils le font ». Par exemple, l'en-tête de l'agent utilisateur browser-requests inclut un composant « Moteur et navigateur » qui peut être utilisé pour vous indiquer que la demande provient d'un navigateur mobile plutôt que d'un navigateur de bureau. Mais l’en-tête de requête de l’agent utilisateur a ses racines dans le passé le plus sombre de l’informatique et sa fonctionnalité a eu du mal à équilibrer plusieurs intérêts concurrents.
Le principal problème ici est qu'une description trop précise de l'environnement utilisateur (l'en-tête comprend également des détails sur le navigateur de l'utilisateur, le type et la version du système d'exploitation, etc.) peut être utilisée pour identifier et suivre les utilisateurs lorsqu'ils naviguent sur le site. la toile. Ce problème reste non résolu.
Voici un exemple de "user-agent" :
<h1> <p>Previously in this series, you've seen styles applied to HTML elements like <p> by adding> <p>The essence of Tailwind is that it provides a system of single-purpose "utility classes", each of which applies a specific set of styles to an element. The class names are chosen judiciously to provide a meaningful and practical expression of styling intentions. The example below styles a <p> element with 4rem padding on all four sides and a background color of light gray.<br> </p> <pre class="brush:php;toolbar:false"><div> <p>Here, in bg-blue-500, bg says that this is a background style, blue sets the background colour to blue and 500 sets the colour "intensity" to a mid-value on a scale of 100 (light) to 900 (dark).</p> <p>This is fine in its way, but the system may only become of interest to you when I tell you that you can make the tailwind utility classes responsive by simply adding a prefix to the style.</p> <p>Tailwind recognizes the following screen-width "breakpoints":</p> <div><table> <thead> <tr> <th>Prefix</th> <th>Screen Size</th> <th>Minimum Width</th> </tr> </thead> <tbody> <tr> <td>sm</td> <td>Small devices</td> <td>640px</td> </tr> <tr> <td>md</td> <td>Medium devices</td> <td>768px</td> </tr> <tr> <td>lg</td> <td>Large devices</td> <td>1024px</td> </tr> <tr> <td>xl</td> <td>Extra large devices</td> <td>1280px</td> </tr> <tr> <td>2xl</td> <td>2x Extra large devices</td> <td>1536px</td> </tr> </tbody> </table></div> <p>A style class such as "bg-gray-200" might thus be made to apply only to screens larger than 640px by specifying it as "sm:bg-gray-200".</p> <p>The "This div has padding on all sides." example above could thus be made to display its paragraph with a blue background on screens with a maximum width of 640px and green on screens larger than this by styling it as follows:<br> </p> <pre class="brush:php;toolbar:false"><p> <p>Because classes to the right take precedence, this makes the default background blue and overrides this with green when the screen is large enough. </p> <p>For a fuller account of the Tailwind system and instructions on how to istall this in your project please see the Tailwind Website.</p> <h3> 3. Adaptive design for Server-side rendered webapps </h3> <p>Responsive design won't help you achieve more drastic effects where the desktop and mobile versions of a webapp are seriously different. Whereas a <strong>responsive design</strong> adjusts a standard pattern"fluidly" to accommodate different screen sizes, an <strong>adaptive</strong> design is prepared to give screen widths tailor-made solutions. </p> <p>Expanding on the "tailoring" theme, you might think of responsive design as creating a single suit made of stretchable fabric that fits anyone. By contrast, adaptive design is like creating multiple tailored suits for different body types.</p> <p>So if, for example, you felt that the mobile customers for your webapp were completely different from your desktop fans, you might want to give each community a tailor-made design (while delivering both under the same URL). </p> <p>Conceptually, the obvious way to express this arrangement would be a displayIsMobile boolean guiding the display of MobileLayout and DesktopLayout components, as follows:<br> </p> <pre class="brush:php;toolbar:false">{#if displayIsMobile} <MobileLayout /> {:else} <DesktopLayout /> {/if}
Je pense qu'il est assez facile de voir les problèmes que vous rencontreriez en analysant ce gâchis !
Mais il existe d’autres options. Une initiative récente de Google a proposé que les navigateurs fournissent un nouvel en-tête beaucoup plus simple appelé sec-ch-ua-mobile. Celui-ci contient une chaîne simple qui vous indique si le navigateur attend ou non une réponse mobile (voir Sec-CH-UA-Mobile pour plus de détails).
Cependant, même si l'en-tête sec-ch-ua-mobile est désormais disponible sur Chrome et Edge, les autres navigateurs ne prendront pas nécessairement en charge l'initiative. Dans tous les cas, l'en-tête sec-ch-ua-mobile ne vous donne pas suffisamment de détails pour affiner votre réponse et servir, disons, une version "tablette" explicite.
Tout cela est très fastidieux, mais cela peut vous suffire pour conclure que vous êtes heureux d'opter pour sec-ch-ua-mobile comme premier port d'escale et l'agent utilisateur comme solution de secours. Dans ce cas, voici du code pour donner à un fichier page.svelte une variable displayIsMobile.
De manière confuse, cela commence par un nouveau type de fichier Svelte appelé fichier hooks.server.js.
Bien que vous pourriez mettre le code pour définir displayIsMobile pour un fichier page.svelte dans une fonction load(), toutes les pages page.svelte n'en auront pas un. Et même si c'était le cas (et vous pouvez toujours en créer un, bien sûr), vous constateriez que vous deviez dupliquer le code displayIsMobile dans toutes fonctions load().
En revanche, le fichier hooks.server.js est une sorte de fonction "super" load() que Svelte lance pour chaque requête soumise au serveur. Il s'exécute avant l'exécution de toute autre activité. Cela en fait l'endroit idéal pour inspecter l'en-tête sec-ch-ua-mobile et créer une valeur pour displayIsMobile.
Le code ci-dessous montre comment displayIsMobile peut être construit par un fichier hooks.server.js. Il montre également comment cette valeur peut être communiquée au fichier page.svelte en attente.
<h1> <p>Previously in this series, you've seen styles applied to HTML elements like <p> by adding> <p>The essence of Tailwind is that it provides a system of single-purpose "utility classes", each of which applies a specific set of styles to an element. The class names are chosen judiciously to provide a meaningful and practical expression of styling intentions. The example below styles a <p> element with 4rem padding on all four sides and a background color of light gray.<br> </p> <pre class="brush:php;toolbar:false"><div> <p>Here, in bg-blue-500, bg says that this is a background style, blue sets the background colour to blue and 500 sets the colour "intensity" to a mid-value on a scale of 100 (light) to 900 (dark).</p> <p>This is fine in its way, but the system may only become of interest to you when I tell you that you can make the tailwind utility classes responsive by simply adding a prefix to the style.</p> <p>Tailwind recognizes the following screen-width "breakpoints":</p> <div><table> <thead> <tr> <th>Prefix</th> <th>Screen Size</th> <th>Minimum Width</th> </tr> </thead> <tbody> <tr> <td>sm</td> <td>Small devices</td> <td>640px</td> </tr> <tr> <td>md</td> <td>Medium devices</td> <td>768px</td> </tr> <tr> <td>lg</td> <td>Large devices</td> <td>1024px</td> </tr> <tr> <td>xl</td> <td>Extra large devices</td> <td>1280px</td> </tr> <tr> <td>2xl</td> <td>2x Extra large devices</td> <td>1536px</td> </tr> </tbody> </table></div> <p>A style class such as "bg-gray-200" might thus be made to apply only to screens larger than 640px by specifying it as "sm:bg-gray-200".</p> <p>The "This div has padding on all sides." example above could thus be made to display its paragraph with a blue background on screens with a maximum width of 640px and green on screens larger than this by styling it as follows:<br> </p> <pre class="brush:php;toolbar:false"><p> <p>Because classes to the right take precedence, this makes the default background blue and overrides this with green when the screen is large enough. </p> <p>For a fuller account of the Tailwind system and instructions on how to istall this in your project please see the Tailwind Website.</p> <h3> 3. Adaptive design for Server-side rendered webapps </h3> <p>Responsive design won't help you achieve more drastic effects where the desktop and mobile versions of a webapp are seriously different. Whereas a <strong>responsive design</strong> adjusts a standard pattern"fluidly" to accommodate different screen sizes, an <strong>adaptive</strong> design is prepared to give screen widths tailor-made solutions. </p> <p>Expanding on the "tailoring" theme, you might think of responsive design as creating a single suit made of stretchable fabric that fits anyone. By contrast, adaptive design is like creating multiple tailored suits for different body types.</p> <p>So if, for example, you felt that the mobile customers for your webapp were completely different from your desktop fans, you might want to give each community a tailor-made design (while delivering both under the same URL). </p> <p>Conceptually, the obvious way to express this arrangement would be a displayIsMobile boolean guiding the display of MobileLayout and DesktopLayout components, as follows:<br> </p> <pre class="brush:php;toolbar:false">{#if displayIsMobile} <MobileLayout /> {:else} <DesktopLayout /> {/if}
Alors maintenant, displayIsMobile se trouve dans l'objet événement pour la requête du navigateur. Cet événement est un objet complexe construit par SvelteKit pour représenter la requête en cours. Il contient des propriétés telles que :
Comme vous l'imaginez, puisque l'événement sera désormais disponible partout où vous en aurez besoin, event.locals est exactement ce dont vous avez besoin pour fournir un accueil à displayIsMobile.
La forme de l'argument {event, réponse} de handle() peut vous laisser perplexe. Ceci est un exemple de syntaxe de « déstructuration ». Cela vous permet d'extraire directement des propriétés spécifiques d'un objet sans référencer l'objet lui-même. Imaginez qu'il existe un super-objet args qui contient un événement et une réponse comme propriétés. Alors au lieu d'utiliser le conventionnel
User-Agent: Mozilla/4.9 Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
"syntaxe de déstructuration" permet d'écrire ceci comme
// src/hooks.server.js export async function handle({ event, resolve }) { let displayIsMobile; console.log("event.request.headers['sec-ch-ua-mobile']: ", event.request.headers.get('sec-ch-ua-mobile')); // First, try to get the mobile flag from the 'sec-ch-ua-mobile' header. This is a string header // and its value is '?1' if the user agent is a mobile device, otherwise it is '?0'. if (event.request.headers.get('sec-ch-ua-mobile') !== undefined) { displayIsMobile = event.request.headers.get('sec-ch-ua-mobile') === '?1' ? true : false; } else { // Otherwise, try the 'user-agent' header. For robust mobile detection, you might consider using // the ua-parser-js library. It provides consistent results across various edge cases. if (event.request.headers.get('user-agent') !== undefined) { displayIsMobile = event.request.headers.get('user-agent').toLowerCase().includes('mobile'); } else { displayIsMobile = false } } // Put displayIsMobile into event.locals. This is an object provided by SvelteKit that is specific to a // particular browser request and which is acessible in every page and layout. In brief, event.locals lets // you pass data throughout the lifecycle of a request in SvelteKit. It provides a convenient way to share // computed values or state without needing to repeat logic or fetch data multiple times. event.locals.displayIsMobile = displayIsMobile; // Proceed with the request. In SvelteKit, resolve(event) is crucial for handling the request lifecycle. // It processes the current request and generates the final response that will be sent back to the client. const response = await resolve(event); return response; }
Essentiellement, il s'agit d'une manière de référencer les propriétés (args.event, etc.) d'un objet args sans connaître le nom de l'objet parent (args). Cela conduit à un code plus strict et plus résilient.
Quoi qu'il en soit, cela dit, avec displayIsMobile étant désormais présent dans l'objet événement pour la requête du navigateur, la chose évidente à faire est d'utiliser une fonction load() dans un fichier page.server.js pour l'extraire et le renvoyer. à page.svelte.
function handle(args) { const event = args.event; const resolve = args.resolve; // ... (code referencing variables "event" and "resolve") }
Voici donc enfin le fichier page.svelte très simple pour livrer une page adaptative
function handle({ event, resolve }) { // ...(code referencing variables "event" and "resolve") }
J'espère que vous avez apprécié ça !
En résumé, la séquence complète est :
Une fois la page hydratée, la réactivité est purement une préoccupation côté client. Un SvelteKit {#if popupIsVisible dans la section modèle de votre code sera devenu une fonction compilée qui bascule les éléments DOM en fonction de popupIsVisible.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!