The best tutorials come from completing real projects. When the project is finished, I like to share what I have learned.
[[[[Check out Visual CSS Dictionary with all the CSS properties explained visually.]
This time, the project is mine CSS flex layout designer. I will explain how I created it from the beginning to the end and provide the example source code below.

This is the example of the flex class, we are going to codify in this tutorial.
This is what we are building in this tutorial. You can also generate multiple instances of it at will on the same page with different default parameters.
here is the Open Flex Layout Designer <click to try it live yet:
I think it's a fun project because the integrated CSS flex functionality eliminates most of the work for us. The hardest thing here is to write the "drag and drop" code, but anyway, it's not that difficult.
To create this flexible layout designer, we will briefly use jQuery for cross-browser click events and the jQuery.css method to dynamically set the CSS properties to our flex articles as they are resized.
STARTING FROM THE START. Why are you creating your application? Why is it necessary? (IS?)
It's okay if you get excited about ideas. But to write an effective software that people actually need, you never have to write a line of code without first asking if you need what you are going to create.
It always starts the same way.
Find an existing problem that needs to be solved. In my case, I was able to answer this question. This is because most of the flex tutorials I found online were too limited or contained explanations using static images.
I mean, let's go. This is flexible. The name itself alludes to the fact that things will flex. That is, resizing, resizing, changing. So why all the static image tutorials for flex?
This did not like me. I knew that to create a truly useful tool that had a high educational value, an interactive approach was delayed.
Your application idea should start with an abstract view. Usually, it's something you get excited about. But remember it your software must also solve an existing real problem.
For me, I wanted to create an instrument or a generator that does not exist yet. Something you wish existed for personal reasons.
In this case, the Examples of CSS flex layout I thought, I should have the ability to add and remove flexible items from the list dynamically.
First of all, I plan some global variables
Global variables are usually avoided by engineers and professional software developers. This is because the modular software design (you know, when you use someone else's code and define global variable names you've already used in your code) will fail if you use them in your library.
But for the purposes of this tutorial, we will use global variables to learn how to create something. We are not distributing this code as a library. We do not share it with other programmers. It will only be used on a site and will not be sent to any open source community.
Each variable is explained with a comment.
// Default width of a flexible object (when added or removed)
to allow DEFAULT_ITEM_WIDTH = & # 39; 30px & # 39 ;;
// Default height of a flexible object (when added or removed)
to allow DEFAULT_ITEM_HEIGHT = & # 39; 30px & # 39 ;;// Current position of the X and Y mouse.
window.mx = 0;
window.my = 0;
// When you click on the item,
// we monitor its vertical and horizontal width:
window.item_x = 0;
window.item_y = 0;
// A flag to indicate if an element is
// currently under resizing (or less)
window.dragging = false;
// Position of the XY mouse screen when you clicked on the last item
window.drag_x = 0;
window.drag_y = 0;
// The actual JavaScript element object of the dragged item
window.dragging_target = null;
// The ID of the item that was clicked and resized
window.dragging_id = -1;
// Width and height of the element, when clicking on
window.item_width = 0;
window.item_height = 0;
// The difference between the current position of the XY mouse
// and the position of the XY mouse while it is being dragged
window.drag_width = 0;
window.drag_height = 0;
// Attribute "data-id" of the selected item
window.item_id = 0;
// To make a copy of the instance of
// the flex object (to update its HTML when
// changing the number or size of the article)
window.flex = null;
// The 7 flexible objects that represent an instance of the flex class
window.flex1 = null;
window.flex2 = null;
window.flex3 = null;
window.flex4 = null;
window.flex5 = null;
window.flex6 = null;
window.flex7 = null;
// I do not know what it is :-) It's unused. But I hate to delete it.
window.funcs = [];
Talking about software architecture
Whenever you design an app, you will think about its structure. This is the architecture of the software. It is the structure of your application.
As a software engineer, your job is to create the most efficient structure for your code. Efficient in this case means that it is easy to change it in the long run without having to rewrite much code again.
This means that you have to resume code reuse as much as possible during the design of your application architecture.
Designing software means that you will work with component-based structures. One nested inside another. But this example of flexible application is so simple that we only have one class. The only class is our entire architecture.
The application of the real world, of course, will be much broader than this. Regarding this case, here it is not really much architecture.
The first thing you want to do is create a JavaScript class that represents the main purpose of your application. Call it elegantly. In this case, I simply chose the flex class.
Of course, it works. After all, objects from this class will be instantiated providing a flexible container.
class flex {
builder(_target,
id,
width,
height,
elements,
item_width,
item_height,
justify_content) {
// I noticed that when justify-content is set to stretch,
// and the width of the object is less than 100% of the width of the container (o
// generally, something small, like 100 px) then the stroke
// the effect will not even take place. It will seem
// flex-start. So the purpose of this line of code is to set up
// all the widths of the object (by default) to 800px, (the full size of
// flex container.) This equals all the elements in the equation equally
// container.
Self (justify_content == & # 39; stretch & # 39;)
item_width = & # 39; 800 & # 39 ;;
// Stores the name of the ID attribute of the HTML element
// (without initial "#" character)
This.tag = _target;
This.variable_name = _target;
// Get the real JavaScript object of the HTML container
This.target = document.getElementById (_target);
// Size of the flexible container
This.width = width;
This.height = height;
// Number of articles
This.items = elements;
// Create arrays that maintain the width and height of objects e
// populate them with the default values
This.items_widths = new array (elements).to fill(item_width);
This.items_heights = new array (elements).to fill(item_height);
// Default width and height of the element
This.item_width = item_width;
This.item_height = item_height;
// Set the justify-content property
This.justify_content = justify_content;
// C & # 39; is an object that is dragged / resized at this time?
This.dragging = false;
Binding methods (if you do not, they will not work)
This.setjustifycontent = This.setjustifycontent;
This.source = This.source;
// Makes the whole HTML flex in the container (dynamically
// update it)
This.incolla ();
}
// ... the functions of the class method follow ...
// (We'll get there soon)
This is the constructor of your class. A constructor allows you to pass arguments to its parameter names. Constructors are usually used to initialize the object with a set of predefined values.
- this.tag – When I create a new flexible object, I want to remember the id attribute of its HTML parent container element.
- this.variable_name – The same thing above is probably redundant but I made a copy just in case (do not do it at home.)
- this.target – The actual JavaScript object of the container's HTML element.
- this.width – The width of the container element.
- This.Height – The height of the container element.
- this.items – The number of items in this flexible container.
- this.items_widths – Series of indices 0 of width of each element in the list.
- this.items_heights – Array of indices 0 of heights of each element in the list.
- this.item_width – The default width of all items.
- this.item_height – The height of the default article of all articles.
- this.justify_content – value of justify-content for this flexible container.
- this.dragging – An item is now dragged (false by default).
- this.source – We need to associate the member function of the source class, otherwise our methods will not work outside the class.
- This.setjustifycontent– We have to tie the setjustifycontent member function of the class, otherwise it will not work.
And finally we call the Paste member function.
- this.paste ();– all default values are set, make the Flex HTML container with the elements it contains for the first time when the object is instantiated.
The flex class builder allows us to do the following:
// Initialize the 7 flex objects and assign them to window.flex[n]
window.Flex1 = newflex ("flex1", "flex-a", 800, 40, 1, & # 39; 200px & # 39 ;, & # 39; 30px & # 39 ;, & # 39; flex-start & # 39;);
window.Flex2= new flex ("flex2", "flex-b", 800, 40, 2, & # 39; 200px & # 39 ;, & # 39; 30px & # 39 ;, & # 39; flex-end & # 39;);
window.FLEX3 = new flex ("flex3", "flex-c", 800, 40, 3, "50px", "30px", "center");
window.Flex4 = new flex ("flex4", "flex-d", 800, 40, 4, "50px", & # 39; 30px & # 39 ;, space-between & # 39;);
window.Flex5= newflex ("flex5", "flex-e", 800, 40, 5, & # 39; 50px & # 39 ;, & # 39; 30px & # 39 ;, space-around & # 39;);
window.flex6= new flex ("flex6", "flex-f", 800, 40, 6, & # 39; 50px & # 39 ;, & # 39; 30px & # 39 ;, & # 39; stretch & # 39;);
window.Flex7= new flex ("flex7", "flex-g", 800, 40, 7, & # 39; 50px, & # 39; 30px & # 39 ;, space-uniform & # 39;);
The constructor instantly creates each flexible object using the new JavaScript keyword. We provide default values, so our flexible object can crunch some data as a starting point during initialization.
During the life cycle of application, these values may change. (For example, the ownership of the justification content will be changed via the onscreen shortcuts displayed just above the flexible container.)
Creation of class method functions
At this point we have provided an instantiation mechanism for our flex class. As our primary (and only) class, it will take many parameters to be able to set application defaults.
The application is still abstract right now. We have no function that gets something. And this is the key to designing your software using classes. They help to define the structure of your application before writing the code.
Once the constructor is complete, we are ready to start working on the member functions of our class (also known as methods, in some languages).
Method: flex.source () – creates the CSS and HTML source code from the class properties names
The source method is what builds the source code for the flexible layout associated with the flex object. It will take the article number, the width of each individual article and convert it into a text string that represents the HTML and CSS code to create the flex you designed using the flexible layout designer.
Oh, and of course it will also take into consideration the subject of flex justify-content property. This is what determines the unique default look of each flex block.
This method provides the code that is copied to the clipboard when the user clicks Copy to clipboard .
source () {
// Start with an empty string
to allow I = ``;
// Go through each item in the list e
// create a container of contents for this:
for (to allow i = 0; I < This.elements; i ++)
I + = `<div style = & # 39; width:` +
This.items_widths[i] +
`; height: `+
This.items_heghts[i] + `& # 39;>` + (i + 1) +
`
// Create the css style tag, put .flex class in it, create
// flex the container and insert the list (we just created above)
to allow src = ` R n r n` + I + ``;
// Return the string we have just constructed
return src;
}
We will simply call the source method whenever you need to copy the code to the integrated gluing clipboard of the browser (or operating system).
Method: flex.setjustifycontent () – sets the justification of the content value and dynamically updates the flexible HTML code
call setjustifycontent the member function will simply set a value in CSS justify-content properties on that flexible container. This is what happens when you click on one of these links above the flex container.
setjustifycontent(justify_content) {
// Set the property value
This.justify_content = justify_content;
// "Paste" HTML into the flex container (update flex)
This.incolla ();
}
This is a rather simple function, is not it? Next, let's write the add function to add items to the list. Note, all these functions go into the object in the same scope in which the constructor is located. But later in this tutorial we will write some global support functions.
insert() {
// Store widths and heights of all items
to allow copyW = This.items_widths.slice ();
to allow copyH = This.items_heights.slice ();
// Reset all the widths and heights of the objects
// to their default values
This.items_widths[this.items] =
This.justify_content == & # 39; stretch & # 39 ;?
& # 39; & # 39 ;: 800px
DEFAULT_ITEM_WIDTH;
This.items_heights[[[[This.elements]= DEFAULT_ITEM_HEIGHT;
This.items ++;
// Set all the dimensions of the elements to the values we have previously stored
for (to allow i = 0; i <copyW.length; i ++)
This.items_widths[i] = copyW[i];
for (to allow i = 0; i <copyH.length; i ++)
this.items_heights[i] = copyH[i];
// Generate HTML and update view
This.incolla ();
}
The comments here are self-explanatory.
to remove() { This.elements--; This.incolla (); }
Removing an object is as simple as decreasing the object counter. We're not actually eliminating the object's width / height arrays. This is important. We do not want to delete the item's size when the item is deleted. Because if the user decides to re-add it again, we want to preserve the previous width and height of that element. Create only a better user experience.
Finally, the paste method (somewhat embarrassingly named) is responsible for "pasting" the actual HTML code for the flex container and its elements based on the current class parameters. This is the core behind the update of the application view.
paste() {
// Start with an empty string
to allow list = ``;
// Explore all existing elements e
// create the container of the content of the element
for (to allow i = 0; I < This.elements; i ++)
list + = `<div class = "object"
id = "` + this.target + `_item_` + (i + 1) +
`" Data-id = "` + (i + 1) +
`" style = & # 39;height of the line : `+ this.items_heights[i] +
`; height : `+ this.items_heights[i] +
`; width: `+ this.items_widths[i] +
`& # 39;>` + (i + 1) +
`