Conversion de la mise en page absolue pour utiliser des flotteurs

Je suis à la recherche de conseils sur un projet sur lequel je travaille et je serais reconnaissant de toute aide.

Objectif:

Pour faire glisser et déposer un CMS qui permet à un utilisateur de dessiner des éléments sur une grille et de les déplacer dans la position souhaitée. Les modifications sont enregistrées au format JSON et converties en HTML / CSS lorsque l'utilisateur appuie sur un bouton de publication. Le HTML résultant doit être propre et flexible (c.-à-d. Pour le contenu qui varie en hauteur / longueur). Le système devrait être capable de gérer la création de sites de commerce électronique ainsi que des sites d'information simples.

Problème:

La manière logique d'obtenir un système de glisser-déposer en HTML consiste à utiliser absolute positionnement absolute avec une width et une height s; Cette méthode ne se prête pas au site fini puisque le contenu est susceptible d'avoir des longueurs variables et que les éléments absolument positionnés sont retirés du flux du document, ils ignorent les éléments qui les entourent.

Solution:

Créez un système qui convertit les éléments absolument positionnés en éléments flottants.

Exemple:

Dans le système CMS, l'utilisateur crée la disposition suivante en dessinant des cases sur une grille:

  1. En-tête de hauteur fixe
  2. Navigation de hauteur variable
  3. Image d'une hauteur fixe
  4. Contenu principal de la page de hauteur variable
  5. Liste des objets visités de hauteur variable
  6. Pied de page de hauteur fixe

Disposition absolue:

Disposition absolue

Le HTML / CSS serait quelque chose comme ceci:

 body { background-color: #999999; font-family: verdana, arial, helvetica, sans-serif; font-size: 70%; margin: 15px 0; padding: 0; } #mainContainer { background-color: #FFFFFF; height: 500px; margin: 0 auto; position: relative; width: 916px; } .contentBlock { border: 1px solid orange; box-sizing: border-box; color: orange; font-size: 2em; text-align: center; } .contentBlock:after { content: ""; display: inline-block; height: 100%; vertical-align: middle; } #contentBlock1 { height: 120px; left: 0; position: absolute; top: 0; width: 916px; } #contentBlock2 { height: 100px; left: 0; position: absolute; top: 140px; width: 136px; } #contentBlock3 { height: 100px; left: 0; position: absolute; top: 260px; width: 136px; } #contentBlock4 { height: 220px; left: 156px; position: absolute; top: 140px; width: 604px; } #contentBlock5 { height: 220px; left: 780px; position: absolute; top: 140px; width: 136px; } #contentBlock6 { height: 120px; left: 0; position: absolute; top: 380px; width: 916px; } 
 <div id="mainContainer"> <div class="contentBlock" id="contentBlock1">1</div> <div class="contentBlock" id="contentBlock2">2</div> <div class="contentBlock" id="contentBlock3">3</div> <div class="contentBlock" id="contentBlock4">4</div> <div class="contentBlock" id="contentBlock5">5</div> <div class="contentBlock" id="contentBlock6">6</div> </div> 

L'utilisateur accède maintenant au bouton de publication et la mise en page sera convertie pour utiliser le float s au lieu absolute positionnement absolute . Le HTML résultant ne peut pas utiliser absolute positionnement absolute car, si le contenu en 2 ou 4 se développe, ils passent sous / sous 3 et 6. Les Float conservent les éléments dans le flux et sont conscients les uns des autres, de sorte que les éléments suivants répondent au contenu dynamique dans 2 Et 4:

Disposition flottante:

Disposition flottante

Le HTML / CSS serait quelque chose comme ceci:

 body { background-color: #999999; font-family: verdana, arial, helvetica, sans-serif; font-size: 70%; margin: 15px 0; padding: 0; } #mainContainer { background-color: #FFFFFF; margin: 0 auto; width: 916px; } .contentBlock { border: 1px solid orange; box-sizing: border-box; color: orange; font-size: 2em; text-align: center; } .contentBlock:after { content: ""; display: inline-block; height: 100%; vertical-align: middle; } #contentBlock1 { margin-bottom: 20px; height: 120px; } #contentBlock2 { height: 100px; margin-bottom: 20px; width: 136px; } #contentBlock3 { height: 100px; margin-bottom: 20px; width: 136px; } #contentBlock4 { float: left; height: 220px; margin-bottom: 20px; margin-left: 20px; width: 604px; } #contentBlock5 { float: left; height: 220px; margin-bottom: 20px; margin-left: 20px; width: 136px; } #contentBlock6 { clear: left; height: 120px; } #contentContainer1 { float: left; width: 136px; } 
 <div id="mainContainer"> <div class="contentBlock" id="contentBlock1">1</div> <div id="contentContainer1"> <div class="contentBlock" id="contentBlock2">2</div> <div class="contentBlock" id="contentBlock3">3</div> </div> <div class="contentBlock" id="contentBlock4">4</div> <div class="contentBlock" id="contentBlock5">5</div> <div class="contentBlock" id="contentBlock6">6</div> </div> 

On ne peut pas s'attendre à ce que l'utilisateur comprenne comment fonctionnent les éléments flottants, de sorte que ce processus devrait être automatique lorsque les modifications sont publiées.

Cet exemple particulier est assez simple, bien que des mises en page plus avancées devraient également être traitées.

Quels autres systèmes CMS:

Pour autant que je puisse le dire, la plupart des systèmes CMS réparent l'utilisateur dans un modèle défini ou construisons la page en utilisant JavaScript pour définir les hauteurs / position des éléments absolument positionnés (ce que j'aimerais éviter).

Mes questions:

  • Est-il possible de concevoir un ensemble de règles pour convertir une mise en page absolue vers une version flottante?
  • Dans l'affirmative, existe-t-il un CMS existant qui le fait?
  • Des suggestions sur d'autres façons d'aborder cette question?

Merci.

Premièrement: je ne pense pas que "convertir" une mise en page absolue pour flotter est la meilleure approche. Vous devriez penser des flotteurs dès le début et suggérer / enseigner à l'utilisateur de construire la mise en page en conséquence.

Deuxièmement: je crois que l'outil que vous souhaitez construire aura besoin des utilisateurs pour apprendre à l'utiliser. Cela dit, vous voulez le rendre assez simple pour les personnes qui ne sont pas familières avec les concepts HTML / CSS pour pouvoir l'utiliser. Vous devez donc fonder l'utilisation de cet outil sur des concepts simples et compréhensibles que les utilisateurs peuvent utiliser pour créer le «look» et vous pour générer le code derrière celui-ci.

Je peux penser à:

  • Blocs / conteneur
  • Des colonnes
  • hauteur largeur
  • Rembourrage de marge

Maintenant, en utilisant ces concepts, vous pouvez permettre à l'utilisateur de créer des blocs avec des propriétés: nombre de colonnes pour la largeur / la hauteur du contenu / la rembourrage. L'utilisateur peut alors nicher définitivement indéfiniment avec ces propriétés et filtrer-déposer le contenu en eux.

Voici comment cela pourrait fonctionner pour votre exemple:

Entête :

L'utilisateur crée un bloc et lui donne ces propriétés:

  • Largeur: 100%
  • Hauteur: 80px (cela peut être fait en faisant de la bordure des éléments)
  • Nombre de colonnes 2 (une pour le logo et une pour le menu)

Principale :

L'utilisateur crée un nouveau bloc sous l'en-tête avec ces propriétés:

  • Largeur: 100%
  • Hauteur: adaptatif
  • Nombre de colonnes: 3 (col 1 et 3: 15% largeur, col 2 70% largeur)

Bas de page

Nouveau bloc avec les mêmes propriétés que l'en-tête.

L'utilisation peut recommencer à l'intérieur de chaque bloc / colonne et peut nouer de nouveaux avec les mêmes propriétés

Générer le code:

Vous connaissez le nombre de colonnes de chaque bloc et de leurs largeurs afin que vous puissiez facilement créer un div pour chacun et utiliser des flotteurs / largeurs pour les positionner côte à côte. Pour les hauteurs: l'utilisateur peut définir une hauteur fixe et il ne sera pas difficile pour lui de comprendre que le contenu peut déborder. Donc, s'il ne veut pas qu'il choisisse la hauteur «adaptative» ( height : auto; dans css ).

Conclusion :

C'est une idée très générale et un concept simple. Le travail principal sera consacré à la conception de l'interface utilisateur et à la façon dont vous suggérez / apprenez à l'utilisateur à créer des mises en page avec votre outil. Gardez à l'esprit ce que vous désirez et comment ils réagiront dans différentes situations. Utilisez vos meilleures compétences en assurance-chômage pour indiquer / enseigner l'utilisation dans la bonne direction.

Il existe un outil de création de site Web appelé Weebly qui a la même fonctionnalité que vous recherchez. C'est gratuit, de sorte que vous pouvez en apprendre davantage sur ses fonctionnalités.

Ce que vous demandez est vraiment vague, alors j'ai divisé les réponses en plusieurs parties:

1- Pour la fonction Drag-and-Drop:

C'est exactement ce que vous recherchez: Gridster

Vous pouvez laisser l'utilisateur redimensionner les cases tout en conservant les contraintes.

2- Si vous recherchez un cadre CSS propre:

  • Bootstrap de Twitter
  • Fondation
  • et beaucoup plus

3- Si vous recherchez une disposition fluide qui couvre toute la page (verticalement et horizontalement):

 html, body {height:100%; margin:0px; padding:0px;} .wrapper {position:relative; height:100%; width:100%; display:block;} .header {position:relative; height:22%; width:100%; display:inline-block; margin-bottom:3%; background:red;} .footer {position:relative; height:22%; width:100%; display:inline-block; margin-top:3%; background:green;} .content {position:relative; height:50%; width:100%; display:inline-block;} .content .left_sidebar {float:left; width:17%; height:100%; position:relative; margin-right:3%; background:yellow;} .content .right_sidebar {float:right; width:17%; height:100%; position:relative; margin-left:3%; background:purple;} .content .middle {float:left; width:60%; height:100%; position:relative; background:cyan;} /** * @info Clearfix: clear all the floated elements */ .clearfix:after {visibility:hidden; display:block; font-size:0; content:" "; clear:both; height:0;} .clearfix {display:inline-table;} /** * @hack Display the Clearfix as a block element * @hackfor Every browser except IE for Macintosh */ /* Hides from IE-mac \*/ * html .clearfix {height:1%;} .clearfix {display:block;} /* End hide from IE-mac */ 
 <div class="wrapper"> <div class="header">Header</div> <div class="content"> <div class="left_sidebar">Left Sidebar</div> <div class="middle">Middle</div> <div class="right_sidebar">Right Sidebar</div> <div class="clearfix"></div> </div> <div class="footer">Footer</div> </div> 

Est-il possible de concevoir un ensemble de règles pour convertir une mise en page absolue vers une version flottante?

Pas impossible mais extrêmement difficile à mettre en œuvre.

Dans l'affirmative, existe-t-il un CMS existant qui le fait?

Non pas que je sache.

Des suggestions sur d'autres façons d'aborder cette question?

Je trouve plus facile de penser aux mises en page comme un tas de lignes et de colonnes, a flotté de manière appropriée. Donc, pour cette mise en page:

Disposition absolue

Je générerai un marquage HTML similaire à celui-ci (simplifié pour la compréhension):

 <div class="box">Content 1</div> <div class="row"> <div class="col"> <div class="box">Content 2</div> <div class="box">Content 3</div> </div> <div class="col"> <div class="box">Content 4</div> </div> <div class="col"> <div class="box">Content 5</div> </div> </div> <div class="box">Content 6</div> 

Vous devrez fournir une interface utilisateur où un utilisateur peut:

  1. Ajouter du contenu
  2. Ajouter des enveloppes de colonnes
  3. Ajouter des colonnes à l'intérieur des enveloppes de colonnes

Vous pouvez ensuite nommer les lignes, les colonnes et / ou les éléments de contenu et utiliser CSS pour ajuster leur largeur. Voici une preuve de concept:

 $(function() { $(".insertable").draggable({ revert: "invalid" }); $(".insertzone").droppable({ activeClass: "acceptable", drop: handleInsert, accept: ".insertable-box, .insertable-row" }); $(".removezone").droppable({ activeClass: "acceptable", drop: handleRemove, accept: ".removable" }); function handleInsert(event, ui) { ui.draggable.css({ left: 0, top: 0 }); var $div = $("<div class='removable'></div>").appendTo(this).draggable({ revert: "invalid" }); if (ui.draggable.hasClass("insertable-box")) { $div.addClass("box").text("Lorem ipsum dolor sit amet."); } if (ui.draggable.hasClass("insertable-row")) { $div.addClass("row").droppable({ activeClass: "acceptable", drop: handleInsert, greedy: true, accept: ".insertable-col" }); ; } if (ui.draggable.hasClass("insertable-col")) { $div.addClass("col").addClass(ui.draggable.find("select").val()).droppable({ activeClass: "acceptable", drop: handleInsert, greedy: true, accept: ".insertable-box, .insertable-row" }); } } function handleRemove(event, ui) { ui.draggable.remove(); } }); 
 /* INTERFACE */ body { font: medium/1 monospace; } select { font: inherit; margin: -1em 0; border: 0; padding: 0; } .insertzone { margin: 1em 0; box-shadow: 0 0 .25em #CCC; } .removezone { margin: 1em 0; box-shadow: 0 0 .25em #CCC; } .insertable { cursor: move; display: inline-block; padding: 1em 4em; background-color: #CCC; } .removable { cursor: move; } .acceptable { background-color: #FEA !important; } .insertzone .box { background-color: #EFD; } .insertzone .row { background-color: #FEE; } .insertzone .col { background-color: #FFD; } .insertzone .box:after { display: block; padding: 1em; text-align: center; content: "box"; color: #CCC; margin-bottom: -1em; } .insertzone .row:after { display: block; padding: 1em; text-align: center; content: "row"; color: #CCC; } .insertzone .col:after { display: block; padding: 1em; text-align: center; content: "col"; color: #CCC; min-width: 8em; } .insertzone:after { display: block; padding: 1em; text-align: center; content: "Drag here to insert"; } .removezone:after { display: block; padding: 1em; text-align: center; content: "Drag here to remove"; } /* LAYOUT */ .box { margin: 1em 0; padding: 1em; } .row { margin: 1em 0; } .row:after { display: block; clear: both; content: ""; } .col { float: left; } .col > * { margin-left: .5em; margin-right: .5em; } .col:first-child > * { margin-left: 0; } .col:last-child > * { margin-right: 0; } .col > *:first-child { margin-top: 0; } .col > *:last-child { margin-bottom: 0; } .col-10 { width: 10%; } .col-20 { width: 20%; } .col-30 { width: 30%; } .col-40 { width: 40%; } .col-50 { width: 50%; } .col-60 { width: 60%; } .col-70 { width: 70%; } .col-80 { width: 80%; } .col-90 { width: 90%; } 
 <link rel="stylesheet" href="//code.jquery.com/ui/1.9.2/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.min.js"></script> <script src="//code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script> <div class="insertzone"></div> <div class="removezone"></div> <div> <div class="insertable insertable-box">box</div> <div class="insertable insertable-row">row</div> <div class="insertable insertable-col">col <select> <option value="col-10">10%</option> <option value="col-20">20%</option> <option value="col-30">30%</option> <option value="col-40">40%</option> <option value="col-50" selected>50%</option> <option value="col-60">60%</option> <option value="col-70">70%</option> <option value="col-80">80%</option> <option value="col-90">90%</option> </select> </div> </div> 

C'est ce que je voudrais concevoir un système qui fait automatiquement partie de cela:
(Pseudo-code, surtout)

  1. Obtenez window.width et window.height de ce que l'utilisateur visualise sur son écran
  2. Calculez un pourcentage pour chaque élément avec une formule simple:

    Var elWidth = (element.width / window.width) * 100
    Var elHeight = (element.height / window.height) * 100

  3. Obtenez chaque élément qui n'a pas une largeur de 100% pour se comporter comme un élément en ligne avec
    display:inline-block;

Ce devrait être une bonne base pour commencer, pourvu que vous ayez conçu une bonne IU pour dériver toutes les DIV imbriquées et une sorte de grille "magnétique" pour aligner les éléments.

Qu'est-ce que tu penses?

Le problème avec la conversion du positionnement absolu vers le flottement est que vous consacrez beaucoup d'efforts à quelque chose qui ne se traduira probablement pas bien. Ne serait-il pas préférable que les éléments utilisent flottant dès le départ?

Je sais que vous ne voulez pas que les utilisateurs aient à comprendre flotter, mais pensez à la façon dont les images fonctionnent dans Microsoft Word – l'utilisateur entraîne l'image vers l'endroit où ils le souhaitent, et peut ensuite définir comment le texte l'enveloppe. Ce n'est pas tellement différent des éléments flottants et présentera plus précisément le résultat final que quelque chose qui n'a pas encore traversé un processus de traduction qui peut ou non fonctionner à 100%.

Exemple:

Faites glisser un élément sur la page, cela nécessite 100% de largeur. Faites glisser un autre élément sur la page, il se trouve sous le premier et reprend le même. Vous modifiez alors le style "enveloppement" des deux éléments afin qu'ils flottent à gauche, et la page se présente pour afficher exactement ce que l'utilisateur obtiendra à la fin. Ce que vous sacrifiez dans un positionnement super flexible, vous compliquez dans une meilleure expérience utilisateur.

Conclusion

Il semble que vous anticipez les besoins de vos utilisateurs en décidant que le positionnement absolu est la seule solution suffisamment souple: mon conseil est: ne pas créer des fonctionnalités que vos utilisateurs n'ont pas demandé. Donnez-leur une interface utilisateur qui vous permet de construire, puis, s'ils demandent plus de fonctionnalités, retrouvez-le. Ils pourraient ne jamais demander, et vous vous épargnerez un mal de tête.

  1. Regardez les cadres de la grille (pas de grille de données), il y a beaucoup de bonnes idées, peut-être que vous pouvez utiliser certaines d'entre elles sans aucune personnalisation.
  2. Pensez une fois de plus à l'entrée de l'utilisateur absolument positionné, mais je pense qu'il ne convient pas à un CMS.

Je pense que vous devriez être prudent: de ce que cela ressemble à vous, vous essayez de créer une interface WYSIWYG en utilisant un positionnement et une taille absolus qui se transforme en quelque chose qui n'est pas WYSIWYG à la fin; Largeurs variables et positionnement en fonction de la taille de l'écran.

Vous avez rencontré l'un des problèmes fondamentaux du design moderne et réactif; Les sites Web ne sont plus WYSIWYG. Il est pratiquement impossible de transmettre toutes les différentes façons dont un site mobile bien conçu apparaîtra dans une seule image.

Vos utilisateurs devront se conformer aux mêmes contraintes que les concepteurs avec la conception mobile, dans la mesure où les éléments doivent s'écouler gracieusement entre les tailles d'écran. Cela signifie généralement limiter le contenu à une grille ou à un seul plan (c.-à-d. Des colonnes ou des lignes), ou en concevoir deux fois; Une fois pour mobile, une fois pour le bureau.

Cela étant dit, l'un des rares systèmes de grille que j'ai vu qui fonctionne avec des éléments absolument positionnés et de taille est la grille de maçonnerie . Il faut des éléments de toute taille et essaie de les intégrer le mieux possible sans casser le flux de la page. Il est souvent utilisé dans des sites de revues ou de portefeuille où le contenu écrit de longue durée est rare.

Avec un système de règles correct et des éléments spéciaux qui créent un espace négatif (par exemple, des diviseurs à largeur totale, des blocs "vides" et des barres latérales pleine hauteur), vous pouvez donner à vos utilisateurs les outils nécessaires pour créer un site qui se réorganise assez bien en utilisant la grille de maçonnerie pour tout.