CSS Tricks: Responsive Flexbox Grid

I recently was asked to complete a little exercise for a job I am interviewing for. It was fairly simple – Build a responsive grid layout and e AJAX for adding and removing elements, dynamically. We are going to focus mainly on the responsive layout but will also cover the AJAX bit as well, just because it was my first exposure to AJAX, having always used fetch(), and I really liked it!

If you need to, you can reference my full code on codepen – Flexbox Grid w/ AJAX.

The rules:

  1. There will be 2 ‘top-level’ components: A button for adding boxes and a grid container.
  2. Each box will be 300×300 with 20px space around all boxes. Each box will have an X button in the top right corner.
  3. Clicking the Add Box button, will add a new element to the page and send out an AJAX request to an external JSON file. After successful receipt, the contents of JSON object will be inserted inside of the newly created box and aligned both vertically and horizontally.
  4. Clicking the X button will delete that specific box from the page.

1. Top Level Components

First, we will create our html elements. There will be 2 main divs, both will be containers. The first for our Add Box button and the second will be our flexbox grid container div. It should look like this:

1.png

You should now see a tiny button up on the top left corner of your page. Let’s add some styling to get things going!

2. Building the Grid

2

This one is fairly simple. We are going to center the text of the button inside of the container and add some space between it and the grid as well as the top of the page. Secondly, the button will have some basic styling.

Now onto the important part of this post – the responsive grid. Flexbox is really awesome because it takes a lot of the functionality that we used to have to manually set, things like floats, and just does it for us behind the scenes.

In order to make your component a flex component, we first need to set 2 values: display and flex-wrap. Your styling for the grid-container class div should look like this:

3.png

Setting the display value to flex will designate this parent component as a flex parent. Additionally, setting the flex-wrap value to wrap will make it so that new elements that do not fit on a line will be pushed to the next line – perfect for responsive design and browser resizing!

Now, we want to add some boxes in this grid. Now, these boxes will only be generated when we click on the Add Box button (more on that in a bit), but for now, let’s throw the child div in the grid just to test out how it works. Our child component will look something like this. (We can delete this when we get to the next step)

4.png

I will explain later why I decided to use 2 classes for the child component, it will make sense once we get to the jQuery portion of the page. Now, let’s add some styling to this child component so that it behaves how we want it to inside of this grid.

5.png

When we set the display and flex-wrap of the parent component, we sealed the deal on all the children of that container. There is nothing left to do, unless you plan on nesting more components inside of that child. We will be doing just that. Since we want to center some text inside each box, we should make each box, also a flex parent component (parent to its child – the <h3> tag). To achieve this, we set the display to flex and instead of using flex-wrap, since we only want to center some text, we can use another property, align-items by setting that to center. Finally, to set the size of the box, we explicitly set the width and height.

Let’s set the properties for the children component of this box. The X button in the top right and the text which will be returned from our AJAX request.

6.png

We set the width of the h3 tag to be 100% of its container so that when we use text-align: center on its parent, it will actually center the text. As for the button? Did you notice how the parent component has a position: relative property? That is so we can set our X button in a specific spot of the box. To do this, we set the parent’s position to relative and the position of the child to absolute. Since we want it in the top right, we set top: 0 and right: 0.

3. Setting up the AJAX Script

This part was a little confusing to me at first, but a little internet digging and it all made sense – let’s take a look. To do this, we are going to be using jQuery. The way it works is such that, we set some jQuery functions to run only when there is a click event on an element with an id of insert idWe gave our button the id of add-box. So let’s check out the script!

Inside of your <head> tag, we will be putting our script, which starts with the opening tag, <script>. In order for our function to get going we need to begin it with the following line of code, $(document).ready(function () {. This will get the ball rolling, it basically says – As soon as the page is rendered and ready to go, you may proceed onto the next line of this script – but not before. Our next line of code will be used to initiate our script, only when there is a click event on our Add Box button. It will look like this.

7.png

In jQuery, you always need to start things off with the money sign, $. For those still unfamiliar, the translation of this line is as follows: When there is a click event on any element on the page with an id of add-box, run the following function (or block of code). Let’s look at the next few lines.

8.png

The JSON that we are sending our AJAX request to has 100 different objects. To keep things interesting, I wanted each call to be to a random object in that JSON. To do this, I setup some variables. min and max are simply setting integer values to each variable (you need integers!). Then, I set a variable x to be equal to a random number between 10-100. Then, the next line is our actual AJAX call!

In the past you had to explicitly state a whole bunch of stuff for your AJAX call with regards to what type of request it was (POST, GET etc.) and what you wanted to do with the data and all sorts of other nonsense. jQuery really simplified all of that with this little command, $.getJSON. Nice and simple! Just run that and you will get your response.

I made sure to use backticks instead of quotation marks for the URL path because I wanted to pass in a variable of x into the post number. If we were to throw a debugger in after this line and then run on our console, data we would get a return value equal to that JSON object in it’s entirety.

Next thing is where I originally got stuck on. Since, we want to add and delete box elements with the click of a button, we should only have these elements being created through the script, and not the markdown. The issue I originally had was only having 1 class for that element. The effect of this was felt later on when I appended the AJAX return data to all elements with that class, which was all boxes on the page. This resulted in a messy feedback loop of doom

Screenshot at Aug 16 17-39-16.png

To fix this, I knew that the id object of the JSON would correspond to the random number generated with the variable x that I created earlier. So, I decided to create a string interpolated classname which would be box plus the number of the data.id which would give us something like box1 or box23. This way, when I appended the return data, I wouldn’t be appending it to an element with a class of box, instead it would be to an element with the class of box + num. Thereby solving the feedback loop from hell issue. The resulting code looked like this:

11

Here, you can see me defining id to be equal to data.id this gives me access to a mutual number that matches the posts/x number as well as the data.id. Then, I define a variable el as being equal to this div that I now want to create. In jQuery, this is done as a string, which may feel slightly counter intuitive. At any rate, we then want to take this newly defined variable and prepend (put in the beginning) it to our flexbox grid. The syntax is as follows: $(".grid-container").prepend(el);. The translation is as follows: Take the variable, el, and prepend it to any element on the page with a class of grid-container. Nice and simple!

4. Removing Individual Elements

Now that we have our element created, we will take the returned data from our AJAX call and throw it inside of this newly created element. First, we define a variable and assign it to data.title. Then, we use string interpolation to throw in the variable, id, which we still have access to because we are scoped to this function, and we are then appending a string (really an <h3> element) to any element with that class. Success! We now can press our button and it will create new boxes with content positioned perfectly in the center of each one! Nice, let’s work on removing next.

Remember the X button that we positioned in the top right corner of all the boxes? Well, now we need to create some jQuery that will remove that element, and it is sooo simple.

12.png

Same as before, when you click on any element with the id of remove then remove the entire element. But wait! I know what you’re thinking. If we remove ALL parent elements with a child element having an id of remove, then we will be removing all the elements and not just that one. The way we solve this is with a reserved word, this. The keyword this, will scope the function to this particular instance. It intuitively knows which element we are talking about because of where it is coming from. So, it only deletes the one we actually want deleted, and not all of them.

That’s it! The final product of the script should look like this. Pay attention to the order of functions here, originally this caused a few minor headaches for me.

13.png

Conclusion

There you have it, a fully responsive, snappy little app that will dynamically create and remove content from your page as you choose. There are so many really excellent resources online for using Flexbox and I will link to them down at the bottom. I think it is important to not use Front End frameworks like Bootstrap or Foundation as frequently, if at all, simply because they have a tendency to become a crutch. Until next time, happy coding!

Resources:

Submit a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s