Changing the absolute layout to utilize floats

I am seeking guidance on a project I am currently working on and would greatly appreciate any help.

Main Goal:

The objective is to create a drag and drop CMS that allows users to draw elements on a grid and rearrange them as needed. The system will record these changes in JSON format and convert them into HTML/CSS upon hitting the publish button. The resulting HTML should be clean and flexible enough to accommodate varying content lengths. The CMS should be capable of handling e-Commerce sites as well as simple informational websites.

Issue:

The conventional method of implementing a drag and drop system in HTML involves using absolute positioning with fixed widths and heights, which proves problematic when dealing with content of differing lengths. As absolutely positioned elements are detached from the document flow, they do not interact effectively with surrounding elements.

Solution Proposed:

To address this challenge, we aim to develop a system that converts absolutely positioned elements into floated elements.

Visual Representation:

In the CMS interface, users can create a layout by drawing boxes on a grid:

  1. Header (fixed height)
  2. Navigation (variable height)
  3. Image (fixed height)
  4. Main content area (variable height)
  5. List of visited items (variable height)
  6. Footer (fixed height)

Absolute Positioning:

The corresponding HTML/CSS code would resemble the following example:

... (CSS code here)
... (HTML code here)

(pressing the "publish" button will automatically convert the layout to use floating elements instead of absolute positioning)

Floated Elements Layout:

The updated HTML/CSS code would look something like this:

... (CSS code here)
... (HTML code here)

It is crucial for the user to have an intuitive experience without requiring comprehensive knowledge of floating elements, hence this conversion process needs to occur seamlessly upon publishing the changes.

While this example showcases a simplistic scenario, more complex layouts will also need to be accommodated in the system.

Comparison with Existing CMS Platforms:

Based on my research, most CMS systems either restrict users to predefined templates or utilize JavaScript to manage the positioning/heights of absolutely positioned elements (an approach I aim to avoid).

Queries:

  • Is it feasible to establish a set of guidelines for converting an absolute layout to a floated one?
  • Are there any existing CMS platforms that implement this feature?
  • Any recommendations for alternative methods to tackle this particular issue?

Your insights are much appreciated.

Answer №1

Initially: Instead of attempting to "convert" an absolute layout to float, it may be more effective to focus on using floats from the beginning and guiding the user to construct the layout accordingly.

Secondly: The tool being developed will likely require users to learn how to utilize it. Therefore, simplicity is key to ensuring that even those unfamiliar with HTML/CSS can easily navigate and employ its features. Building the tool around simple and comprehensible concepts such as blocks/containers, columns, height/width, and margin/padding would enable users to create visually appealing layouts while the tool generates the necessary code in the background.

One approach could involve:

  • blocks/containers
  • columns
  • height/width
  • margin/padding

By allowing users to create blocks with specific attributes like number of columns, content width/height, and margin/padding, they can arrange these blocks as needed and insert content effortlessly through drag-and-drop functionality.

For instance, in your example:

Header:

The user creates a block with properties:

  • width: 100%
  • height: 80px (adjustable by dragging the border)
  • number of columns: 2 (e.g., for logo and menu)

Main Section:

A new block beneath the header with properties:

  • width: 100%
  • height: adaptable
  • number of columns: 3 (col 1 and 3: 15% width, col 2: 70% width)

Footer:

Create another block with similar properties as the header.

Users can then continue nesting new blocks/columns within each section with identical attributes.

Generating Code:

Detailed information on the number of columns and their widths allows for easy creation of div elements utilizing floats/width to align them side by side. When dealing with heights, users can set fixed values or opt for adaptive height (height: auto; in CSS) to manage overflowing content.

In Conclusion:

While this idea offers a basic yet practical concept, the real challenge lies in designing the UI effectively and guiding users to construct layouts seamlessly. Consider the target audience and their potential reactions in various scenarios, leveraging your expertise in UI design to steer users in the right direction.

Answer №2

Have you heard of a website building tool known as Weebly? It offers the same functions that you seem to be seeking and it's completely free. Take a look at their features to see if it meets your requirements.

Your request is quite broad, so I've broken down the solutions into different categories:

1- If you need Drag-and-Drop functionality:

You might find what you need with this tool: Gridster

This allows users to adjust box sizes while maintaining limits.

2- In search of a minimal CSS Framework:

3- Seeking a responsive layout covering the entire page (both vertically & horizontally):

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>

Just remember, making these adjustments may impact the mobile user experience negatively.

Answer №3

Can an absolute layout be converted to a floated one using a set of rules?

It is not impossible but challenging to implement.

Are there any existing CMS platforms that can perform this conversion?

I am not aware of any.

Do you have any suggestions for alternative approaches to address this issue?

I prefer viewing layouts as rows and columns, appropriately floated. For example:

The HTML markup generated could look like this (simplified for clarity):

<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>

A user interface should allow users to:

  1. Add content
  2. Add column wrappers
  3. Add columns within column wrappers

You can then assign names to the rows, columns, and/or content elements, adjusting their widths with CSS. Here is a sample implementation:

$(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>

Here is a demonstration of your layout created using this tool:

Answer №4

In order to create a system that automagically accomplishes this task, one could devise the following approach:
(rough pseudo code)

  1. Obtain window.width and window.height of the user's screen visualization.
  2. Calculate a percentage for each element using a simple formula:

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

  3. Select every element that is not 100% width and make them behave like inline elements by adding
    display:inline-block;

This method serves as a solid foundation to build upon, assuming a well-designed UI to identify nested DIVs and a type of "magnetic" grid for aligning items.

What are your thoughts on this concept?

Answer №5

Instead of going through the trouble of converting from absolute positioning to floated, why not start with elements that use floating right away? While the idea of users having to understand floating may seem daunting, consider how images are handled in Microsoft Word - users can easily drag and place the image where they want it, adjusting text wrapping as needed. This concept is similar to floating elements and provides a more accurate representation of the final result without the need for extensive translation processes.

For example:

Imagine dragging an element onto the page, taking up 100% width. Add another element below it, also occupying the same width. By changing the "wrap" style of both elements to float left, the page instantly reflects the end result for the user. While this may sacrifice some flexibility in positioning, it ultimately enhances the user experience.

In conclusion:

Rather than assuming absolute positioning is the only flexible solution your users need, consider providing a drag-and-drop UI first. Build what they ask for and address additional features if requested later on. By avoiding unnecessary features, you can save yourself from unnecessary headaches down the road.

Answer №6

  1. Consider exploring various grid frameworks for inspiration, as they offer a plethora of innovative concepts that may be integrated without much modification.
  2. Revisit the notion of user input being absolutely positioned, keeping in mind its compatibility with a CMS platform.

Answer №7

It's important to approach building a WYSIWYG interface with caution, as using absolute positioning and fixed sizes can lead to unexpected results when viewed on different screen sizes. This challenge highlights the shift in modern responsive design, where what you see is not always what you get. Designers must adapt to create websites that elegantly transition between various devices.

Users now face similar constraints to designers, navigating content that must gracefully adjust to fit different screens. Embracing grid systems or designing separate layouts for mobile and desktop can help maintain consistency across platforms.

A notable exception is the Masonry Grid, a flexible solution for arranging elements of varying sizes without disrupting the page layout. Popular among magazine and portfolio sites, this tool thrives in environments with limited written content.

By leveraging smart rules and incorporating special elements for creating negative space, users can effectively utilize Masonry Grid to construct adaptable websites that seamlessly rearrange themselves based on content needs.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to create collapsible navigation bars in your website

As someone exploring client-side development, I may be misusing the term "collapsible" in my title. What I aim to accomplish in my web application is allowing users to collapse header bars into small chevrons and expand them back when necessary. I am on t ...

Tips for postponing the removal of a class in a Bootstrap 4 dropdown mega menu?

Currently, I am facing a challenge in toggling a class on a navbar toggle button. The issue arises when the cursor hovers over the dropdown menu, causing the class to be quickly removed and the menu to disappear. It seems like the solution lies in implemen ...

The jquery plugin fails to acknowledge the specified parameters during the function call

My plugin has default settings, but when I try to change them in the calling script, the changes are not being reflected. The defaults always seem to take precedence. What am I doing wrong here? This is the calling script in my .html file: $('.input ...

Unable to retrieve parameter while making a POST request

Need some help with attribute routing. I'm having trouble getting parameters from the HTTP body. The ConnectionID Class includes a property named CValue. $('#btn').click(function () { $.ajax({ type: "POST", url: "http:// ...

Issue with setState function within setInterval

My current challenge involves updating the value of stateValue with the value of i within a setInterval. However, I am encountering an issue where only the value of i changes and does not update the stateValue as intended within the setInterval. updateV ...

What is the recommended element for managing data in React?

Let's consider a scenario where we have 2 main components: class App extends React.Component { state = { comments: [1, 2, 3, 4] } render() { return ( <Comments /> ) } } class Comments extends React.Component { rende ...

The issue with Google Maps API not loading is being caused by a problem with the function window.handleApiReady not being

Having trouble with the Google Maps API, specifically encountering an error during page load that says window.handleApiReady is not a function, even though it definitely exists. Examining the code snippet below reveals its usage as a callback function: ...

Activating an Ajax-filled dropdown when the previous dropdown remains unchanged but a selection has been made

I am working with three dropdowns: the first one is populated from the server, the second one is filled via ajax based on a change in the first dropdown, and the third one is also filled via ajax based on a change in the second dropdown. Below is the code ...

What is the best way to execute a function within testing procedures?

As a Java Developer looking to expand my skill set to include NodeJS, I find myself wondering about running functions with tests in NodeJS. In Java, it's simple to run a function and verify its functionality with tests like this: @Autowired So ...

Generating a Transform stream with ExcelJS to produce xlsx files

Currently, I am utilizing the ExcelJS module and creating a wrapper to suit my specific needs. This wrapper implements the Transform Stream API, and surprisingly, the node version being used is 0.10.40. The ExcelJS module offers a stream API, and based on ...

Ways to execute additional grunt tasks from a registered plugin

I am currently in the process of developing a custom Grunt plugin to streamline a frequently used build process. Normally, I find myself copying and pasting my GruntFile across different projects, but I believe creating a plugin would be more efficient. Th ...

The preflight response does not allow the access-control-request-methods request header field due to restrictions set in the access-control-allow-

I'm facing CORS issues while trying to make a POST request from my website to a remote server. Despite searching online, I couldn't find a solution that fits my specific problem. Below are the parameters for my ajax request: var params = { ...

Using Jquery to add a list after parsing JSON data stored in localStorage

I've been stuck on this issue for quite some time now. The problem I'm facing involves checking the localStorage to see if there's a cached JSON string available. If there is, I load it and convert it back into a JSON object. If not, I make ...

The return type of a server-side component in NextJS 14 when it is asynchronous

When using NextJS 14, I encountered a problem with the example provided in the documentation. The example is within the Page component, typically typed as NextPage. However, this type does not support the use of async await server components. In my case, ...

What is the best way to implement jQuery after new elements have been added to the DOM?

I'm currently working on a Sentence Generator project. The program is designed to take a list of words and retrieve sentences from sentence.yourdictionary.com based on those words. The first sentence fetched from the website is displayed using the cod ...

Is it possible to merge several blobs into one zip file using JSzip?

When attempting to download multiple images as a single ZIP file, the result is receiving separate zip files instead. The console log shows that the 'urls[]' array contains different arrays. const fileURLs = window.URL.createObjectURL(result);// ...

The VueJS dynamic grid view

Currently, I am working on a project in VueJS using vue cli 3. I am facing an issue with implementing MasonryJS into my Vue project. The challenge lies in grasping how to integrate this masonry layout into my Vue application. ; (function(window) { // J ...

Error in Node.js child_process: unable to access the property '_writableState' as it is undefined

I'm currently working on integrating ffmpeg's functionality into a Node.js API by utilizing the child_process library. However, I encounter an error when trying to pass data to ffmpeg's stdin pipe, specifically getting a TypeError: Cannot re ...

What is causing this image to be off-center both vertically and horizontally on the table?

Currently, I have a small 20px by 20px image displaying in the top left corner of an empty table: <table width="100px"> <tr> <td width='100%' align='center' valign='center'> <img i ...

Managing code requiring document.title in Next.js with Static Site Generation (SSG)

Currently, I have 2 dynamic SSG pages located under /blog/[slug]. Within these pages, I am rendering a component using next/link. When I click on these links to navigate to another slug, I encounter an issue. The problem arises when I want to execute some ...