Преобразование абсолютного макета для использования float
Я ищу некоторые советы по проекту, над которым я работаю, и буду благодарен за любую помощь.
Цель:
Чтобы сделать CMS перетаскивания, который позволяет пользователю рисовать элементы на сетке и перемещать их в нужную позицию. Изменения записываются в формате JSON и преобразуются в HTML/CSS, когда пользователь нажимает кнопку публикации. Итоговый HTML должен быть чистым и гибким (т.е. Обслуживать контент, который будет меняться по высоте и длине).
Система должна иметь возможность обрабатывать создание сайтов электронной коммерции, а также простых информационных сайтов.
Проблема:
Логичным способом достижения системы перетаскивания в HTML является использование позиционирования absolute
с помощью набора width
и height
s; этот метод не поддается готовому сайту, так как контент, вероятно, будет иметь переменную длину, и поскольку абсолютно позиционированные элементы вынимаются из потока документа, они не знают о них вокруг.
Решение:
Создайте систему, которая преобразует абсолютно позиционированные элементы в плавающие элементы.
Пример:
В системе CMS пользователь создает следующий макет путем рисования ячеек в сетке:
- Заголовок фиксированной высоты
- Навигация с переменной высотой
- Изображение фиксированной высоты
- Основное содержание страницы переменной высоты
- Список посещенных элементов переменной высоты
- Нижний колонтитул с фиксированной высотой
Абсолютная компоновка:
![Absolute layout]()
HTML/CSS будет примерно таким:
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>
Ответы
Ответ 1
Сначала: Я не думаю, что наилучшим подходом является "преобразование" абсолютного макета в float. Вы должны думать о плаваниях с самого начала и намекать/научить пользователя правильно строить макет.
Второй: Я считаю, что инструмент, который вы хотите построить, должен будет узнать, как его использовать. Это говорит о том, что вы хотите сделать его достаточно простым, чтобы люди, не знакомые с концепциями HTML/CSS, могли его использовать. Поэтому вам необходимо использовать этот инструмент на простых и понятных концепциях, которые пользователи могут использовать для создания "взгляда", и вы должны генерировать код позади него.
Я могу думать о:
- блоки/контейнер
- Столбцы
- высота/ширина
- маржа/заполнение
Теперь, используя эти понятия, вы можете позволить пользователю создавать блоки со свойствами: количество столбцов для ширины/ширины содержимого/заполнения. Пользователь может затем тайно блокировать блоки с этими свойствами и перетаскивать содержимое внутри них.
Вот как это могло бы работать для вашего примера:
Заголовок:
Пользователь создает блок и дает ему следующие свойства:
- ширина: 100%
- height: 80px (это можно сделать, используя границу элементов)
- количество столбцов 2 (один для логотипа и один для меню)
Главная:
Пользователь создает новый заголовок под заголовком с этими свойствами:
- ширина: 100%
- высота: адаптивная
- количество столбцов: 3 (col 1 и 3: ширина 15%, col 2 70%)
Footer
Новый блок с теми же свойствами, что и заголовок.
Затем использование может начинаться снова внутри каждого блока/столбца и может вставлять новые с теми же свойствами
Создание кода:
Вы знаете количество столбцов каждого блока и их ширину, чтобы вы могли легко создать div для каждого и использовать float/width для размещения их рядом друг с другом. Для высот: пользователь может установить фиксированную высоту, и ему не составит труда понять, что содержимое может переполняться. Поэтому, если он не хочет, чтобы он выбрал "адаптивную" высоту (height : auto;
в css).
Вывод:
Это очень общая идея и простая концепция. Основная работа будет заключаться в разработке интерфейса и тому, как вы намекаете/научите пользователя создавать макеты с помощью вашего инструмента. Имейте в виду, кого вы расстраиваетесь и как они будут реагировать в разных ситуациях. Используйте свои лучшие навыки пользовательского интерфейса, чтобы намекнуть/научить использование в правильном направлении.
Ответ 2
Здесь есть инструмент создания веб-сайта Weebly, который имеет ту же функциональность, что и вы. Это бесплатно, поэтому вы можете посмотреть, как узнать о его возможностях.
То, о чем вы просите, действительно расплывчато, поэтому я разделил ответы на несколько частей:
1- Для функции Drag-and-Drop:
Это именно то, что вы ищете: Gridster
Вы можете позволить пользователю изменять размеры ящиков при сохранении ограничений.
2- Если вы ищете чистую CSS-структуру:
3- Если вы ищете жидкостный макет, который охватывает всю страницу (по вертикали и по горизонтали):
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>
Ответ 3
Можно ли разработать набор правил для преобразования абсолютного макета в плавающий?
Невозможно, но чрезвычайно сложно реализовать.
Если это так, существуют ли существующие CMS?
Не то, что я знаю.
Любые предложения по другим способам решения этой проблемы?
Мне легче думать о макетах, как о пучке строк и столбцов, плавающих соответственно. Итак, для этого макета:
![Absolute layout]()
Я бы сгенерировал разметку HTML, подобную этой (упрощенную для понимания):
<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>
Вам нужно будет предоставить пользовательский интерфейс, в котором пользователь может:
- Добавить контент
- Добавить обертки столбцов
- Добавить столбцы внутри оберток столбцов
Затем вы можете указать строки, столбцы и/или элементы контента и использовать CSS для настройки их ширины. Вот доказательство концепции:
$(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>
Ответ 4
Это то, что я хотел бы разработать систему, которая автоматически делает это:
(псевдокод, в основном)
Это должно быть хорошей базой для начала, при условии, что вы разработали хороший пользовательский интерфейс для получения каждого вложенного DIV и своего рода "магнитной" сетки для выравнивания элементов.
Как вы думаете?
Ответ 5
Проблема с преобразованием из абсолютного позиционирования в плавающее - это то, что вы потратите много усилий на то, что, вероятно, не будет хорошо переводиться. Не было бы лучше, если бы элементы использовали плавающие с самого начала?
Я знаю, что вы не хотите, чтобы пользователям приходилось разбираться в плавании, но подумайте о том, как изображения работают в Microsoft Word - пользователь перетаскивает изображение туда, где он этого хочет, и затем может установить, как обтекает текст. Это не так сильно отличается от плавающих элементов и будет более точно представлять конечный результат, чем тот, который еще не прошел процесс перевода, который может или не может работать на 100%.
Пример:
Перетащите элемент на страницу, он занимает 100% ширину. Перетащите еще один элемент на страницу, он сидит под первым и занимает то же самое. Затем вы изменяете стиль "wrap" для обоих элементов, чтобы они плавали влево, а страница обновлялась, чтобы точно показать, что пользователь получит в конце. То, что вы жертвуете в супер гибком позиционировании, вы восполняете в лучшем пользовательском интерфейсе.
Заключение
Похоже, вы ожидаете удовлетворения потребностей своих пользователей, решив, что абсолютное позиционирование - это единственное решение, достаточно гибкое - мой совет: не создавайте функции, которые ваши пользователи не запрашивали. Дайте им интерфейс перетаскивания и перетаскивания, который вы МОЖЕТЕ построить, а затем, если они попросят больше функций, тогда выясните это. Они никогда не спросят, и вы сбережете себе головную боль.
Ответ 6
- Взгляните на рамки сетки (а не на сетку данных), есть много хороших идей, возможно, вы можете использовать некоторые из них без какой-либо настройки.
- Подумайте еще раз об абсолютном позиционировании пользователя, но я думаю, что он не подходит для CMS.
Ответ 7
Я думаю, вы должны быть осторожны: из того, что звучит так, будто вы пытаетесь построить интерфейс WYSIWYG, используя абсолютное позиционирование и размер, который в итоге превращается во что-то, что не является WYSIWYG; переменная ширина и расположение в зависимости от размера экрана.
Вы столкнулись с одной из фундаментальных проблем современного отзывчивого дизайна; веб-сайты больше не WYSIWYG. Его практически невозможно передать все разные способы, чтобы хорошо продуманный мобильный сайт выглядел в одном изображении.
Ваши пользователи должны будут соответствовать тем же ограничениям, что и дизайнеры с мобильным дизайном, поскольку эти элементы должны изящно перемещаться между размерами экрана. Обычно это означает ограничение содержимого сеткой или отдельной плоскостью (то есть столбцами или строками) или проектирование в два раза; один раз для мобильных устройств, один раз для рабочего стола.
Если сказать, что одна из немногих систем сетки, которые я видел, что работает с абсолютно позиционируемыми и размерными элементами, - это Масонная решетка. Он принимает элементы любого размера и пытается совместить их, насколько это возможно, без нарушения потока страницы. Его часто видели в журналах или портфолио, где длинная форма письменного контента встречается редко.
При наличии приличной системы правил и специальных элементов, создающих отрицательное пространство (т.е. разделители полной ширины, "пустые" блоки, боковые панели с полной высотой), вы можете дать своим пользователям инструменты для создания сайта, который очень хорошо перестраивается с использованием масонской решетки За все.