Подтвердить что ты не робот

Преобразование абсолютного макета для использования 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>
4b9b3361

Ответ 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

Это то, что я хотел бы разработать систему, которая автоматически делает это:
(псевдокод, в основном)

  • получить window.width и window.height того, что пользователь визуализирует на своем экране
  • рассчитать процент для каждого элемента с простой формулой:

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

  • получить каждый элемент, который не является 100% шириной, чтобы вести себя как встроенный элемент с помощью display:inline-block;

Это должно быть хорошей базой для начала, при условии, что вы разработали хороший пользовательский интерфейс для получения каждого вложенного DIV и своего рода "магнитной" сетки для выравнивания элементов.

Как вы думаете?

Ответ 5

Проблема с преобразованием из абсолютного позиционирования в плавающее - это то, что вы потратите много усилий на то, что, вероятно, не будет хорошо переводиться. Не было бы лучше, если бы элементы использовали плавающие с самого начала?

Я знаю, что вы не хотите, чтобы пользователям приходилось разбираться в плавании, но подумайте о том, как изображения работают в Microsoft Word - пользователь перетаскивает изображение туда, где он этого хочет, и затем может установить, как обтекает текст. Это не так сильно отличается от плавающих элементов и будет более точно представлять конечный результат, чем тот, который еще не прошел процесс перевода, который может или не может работать на 100%.

Пример:

Перетащите элемент на страницу, он занимает 100% ширину. Перетащите еще один элемент на страницу, он сидит под первым и занимает то же самое. Затем вы изменяете стиль "wrap" для обоих элементов, чтобы они плавали влево, а страница обновлялась, чтобы точно показать, что пользователь получит в конце. То, что вы жертвуете в супер гибком позиционировании, вы восполняете в лучшем пользовательском интерфейсе.

Заключение

Похоже, вы ожидаете удовлетворения потребностей своих пользователей, решив, что абсолютное позиционирование - это единственное решение, достаточно гибкое - мой совет: не создавайте функции, которые ваши пользователи не запрашивали. Дайте им интерфейс перетаскивания и перетаскивания, который вы МОЖЕТЕ построить, а затем, если они попросят больше функций, тогда выясните это. Они никогда не спросят, и вы сбережете себе головную боль.

Ответ 6

  • Взгляните на рамки сетки (а не на сетку данных), есть много хороших идей, возможно, вы можете использовать некоторые из них без какой-либо настройки.
  • Подумайте еще раз об абсолютном позиционировании пользователя, но я думаю, что он не подходит для CMS.

Ответ 7

Я думаю, вы должны быть осторожны: из того, что звучит так, будто вы пытаетесь построить интерфейс WYSIWYG, используя абсолютное позиционирование и размер, который в итоге превращается во что-то, что не является WYSIWYG; переменная ширина и расположение в зависимости от размера экрана.

Вы столкнулись с одной из фундаментальных проблем современного отзывчивого дизайна; веб-сайты больше не WYSIWYG. Его практически невозможно передать все разные способы, чтобы хорошо продуманный мобильный сайт выглядел в одном изображении.

Ваши пользователи должны будут соответствовать тем же ограничениям, что и дизайнеры с мобильным дизайном, поскольку эти элементы должны изящно перемещаться между размерами экрана. Обычно это означает ограничение содержимого сеткой или отдельной плоскостью (то есть столбцами или строками) или проектирование в два раза; один раз для мобильных устройств, один раз для рабочего стола.

Если сказать, что одна из немногих систем сетки, которые я видел, что работает с абсолютно позиционируемыми и размерными элементами, - это Масонная решетка. Он принимает элементы любого размера и пытается совместить их, насколько это возможно, без нарушения потока страницы. Его часто видели в журналах или портфолио, где длинная форма письменного контента встречается редко.

При наличии приличной системы правил и специальных элементов, создающих отрицательное пространство (т.е. разделители полной ширины, "пустые" блоки, боковые панели с полной высотой), вы можете дать своим пользователям инструменты для создания сайта, который очень хорошо перестраивается с использованием масонской решетки За все.