2022 Layout. Part 2: Practice
The situation was as follows.
The company was redesigning the site and said it needed to be as flexible as possible. First, to be able to update the design easily, and second, to make a few more subsections based on ready-made functionality (kind of a SaaS feature for customers).
The first design arrives (I had to change it a lot because of the NDA, but it was something similar).
We have something interesting here.
1) There are sections divided by principle:
The header is always the same.
So, we take the header and content text to the typography (Components/Typography, or whatever name you like as long as it semantically explains what it is).
Then we have a bunch of different sections. You can’t see it in such a small picture, but most sections have the same indents, and half of them are also the same height.
It turns out that you also need an entity that sets the same rules for sections, such as common indents and common minimum height. I called this type of entity “containers”. In particular, for the BasicSection.
So, we already have a Typography with a header and Containers with a BasicSection.
Great, let’s create such sections.
I guess it’s a little confusing in styles, isn’t it?
Let me explain.
We remember from the previous article that we have rhythm in design. So we took 10px as the basis for all indents on the site.
Because all the indents are multiples of 10.
The indent on the side of the page — 90px, the indent between the buttons, labels, form — 10px or 20px, etc.
Then it is 10px ($offset-basic) that all the indents will be counted from. The $offset-basic itself should not be used anywhere, because it is only a reference point and does not relate to the semantics of the site.
Let’s move on.
The height of the section, in our opinion, is equal to the height of the screen (100vh). It seems to make sense, but when I add a header to the site it turns out that there is a scroll bar. This is because we have a 100vh + 150px (for example) block of header height. In order not to lose the context we have just discovered, I suggest that we write this logic into the section height variable.
Why is it important?
I’ve often seen records in the header component, height: 150px, and in the height section height: 95vh.
It seems accurate, but where did the 5vh go? Why 150px = 5vh? And other questions.
Where? For example, open the Forbes website (https://www.forbes.com).
Similar logic of the magic numbers: 3%, 31.8%.
Well, yes, I understand that the remaining block is most likely occupies 97% and 68.2%, or not just one remaining block, but two remaining blocks.
Okay, fine, I don’t get it.
I think that we are done with the height formula, let’s move on.
Next came this wonderful section (white) for which there is both a mobile design and a tablet design. What should we do about it?
The indents in each section have been changed here. In the mobile version there is almost no background, in the tablet version there is not much background, and in the desktop version it fills, as far as I understand, all the free space.
Here, following the logic of the first article, we go to the designer and clarify if we understand everything correctly, not to make assumptions, but to know exactly what is needed.
Okay, what do we do with the information we get?
The first thing that comes to mind is simply inserting values into each media query.
I hope you won’t be surprised by the variable widths of the screens…
It’s pretty readable, in my opinion.
Global variables from html are substituted into the component. In future they can be reused in other components or sections (with a different height).
Moving on to the next sections.
The indent between elements and the indent from the header is clearly visible.
So, for the label we need to add an indent on the right side equal to one $offset-basic, and for the header on the bottom we need to add an indent equal to two $offset-basic.
The only thing about indents, I recommend reading this article to understand why you shouldn’t add indents to the left and top.
I’ll add media queries, because we have a different layout for different devices…
To be honest, it’s not very readable anymore.
Yes, spreading it out over different files would be better.
For example, to state global variables in main.scss and use them in media queries within components.
To put media queries in mixins.scss as something like @include mobile, @include tablet.
We get the following:
Actually, it’s quite good. Well. Not quite good. But it’s tolerable. But it will be for every element, every tag. It looks like a really weird duplication of code…
Now I really want to talk about readability.
Let’s compare the 3 different versions of the code I often see and the one above.
Let’s watch it closely.
The first (#1) version is a simple copying from Figma or somewhere else.
The second (#2) version is the standard unification of variables.
When we have colors as $red, $black or $alpha, $beta, and the indents are simply multiplied (at best, sometimes just new variables are created and there are 1000 variables in the project at once).
The third (#3) version is kind of readable, but honestly, not very good either. There is some idea in the variable name ($[property]-[element]-[media-query]), but it looks too excessive.
Finally, the “silver bullet” that I suggest.
The coding option we were looking for!
We put the variables that we change from each component into one global component — html tag.
We add css-variables.
Now our classes look like this.
All of them. All the sections, all the headers, buttons, labels — everything is in the project.
Because they will be created in the same way.
But what do media queries look like?
The code became separated into files. The components now only contain information about the indent type (its semantic value), and the variables.scss file contains information about how indents differ depending on the device.
To continue the article, I made a template based on the create-react-app, so you can follow the developments on your own by “poking” into the code and finding out whether you are comfortable with it or not (https://github.com/DrBoria/cra-scss).
I added some variables, for example for the typography.
To understand the font size, I suggest you read this article.
The next task — design editing — was quite more difficult.
Well, not really “edits”. The design has changed completely.
Some sections can only be rewritten from scratch, some are similar but need to be completely modified.
The homepage is almost unchanged — only the indents between sections (from the menu to the header) and colors are different.
But the services are completely different. The only thing that is similar is the structure of the cards. And not even that very much.
And you think that’s a problem? The change took 20 minutes at the most.
1. We change the two columns to a complex system of columns, as in grid template areas.
2. Since we now have two types of cards — images and text — I put them in a separate component.
3. For indents between cards, we add a grid-gap equal to the indent between elements.
4. Alright, now we can go make some coffee. We didn’t even have to rewrite the structure in jsx (I put the cards into a separate component just for beauty, but there were less than 20 lines anyway…)
I promised earlier that there would be three designs.
Now we have white version…
As we can see, the logic is completely different.
On the top (black) we have, let’s call it, overlay. On the bottom one (white) we have the text and the photos.
The photos themselves come in different order, different structures.
It’s basically the same page, but for a different theme.
We place the photos with the grid (I think there’s not much point in showing how to do it).
The main questions are how to add different logic depending on the topic and how to organize the colors.
In this project, I divided the colors into basic and theme-related colors.
The basic ones are selection (pink, purple), text color in selected elements (always white) and disabled — for form elements.
All the other colors went into the themes.
Next, to understand which theme is currently enabled, I added a css variable –theme with the name of the theme (‘dark’ and ‘light’ respectively)
which I looked for in the components where it was needed using the following logic.
In contrast to the data-attribute approach, this method allows you to override the theme, not only in the root component, but also in the nested ones.
The redefinition itself is carried out with the ThemeProvider.
By accessing the current theme directly in the jsx component, I added overlay logic (baseplates under the text in the dark theme) and card placement (2 or 3 rows).
To summarize everything, I want to outline the pros and cons of this approach.
It’s basically the same as with the comments. If you write detailed and clear comments where they are really needed, if you remember to update them every time after the logic has changed, then it will give you a huge advantage in code support.
I’d say the bigger the project becomes, the easier it will be to write.
It’s the same thing here. If after learning new information from the designer, you are not too lazy to update all the variables that are associated with it, if you try to make the logic in the code similar to that in the head of the customer, then, after a while, the project will not need a designer — it will be faster to make than to draw.
If you forget to update comments, or when you hear about new requirements from a customer you get lazy and create another variable instead of updating an existing one, this approach will make your code too complicated.
Once again, I would like to remind you that the developer is the person who converts customer’s thoughts into machine language.
Write a clear code, I hope support will now be a pleasure for you!