Hello, reader! I have been building websites since 2011. Like most of the designers of that time, I studied on my own from video lessons. During this time, I was mistaken more than once with the choice of positioning a block, choosing a tag for an element and of course with the name of classes. In this article I want to share my mistakes.
The first block on the page is a full-panel top-panel that contains a menu and search. First, let's look at the general structure of the block:
<div class="header"> <header id="header" class="wrapper"> <div class="menu_block"> <!-- menu --> </div> <div class="search_block"> <!-- search --> </div> </header> </div>
The first thing that catches your eye, looking at it, is the use of a div element with the class header and a header element with the header identifier. I am sure that 100% of web designers, having looked at this code, will not understand where the cap really is. Therefore, you need to reverse the elements as follows:
<header id="header" class="header"> <div class="wrapper"> <div class="menu_block"> <!-- menu --> </div> <div class="search_block"> <!-- search --> </div> </div> </header>
Next, we need to determine what the header identifier is used for. To do this, in CSS we find the following cascades:
.header{..} #header{...} #header .search_block{...}
I don’t know what state I was in, doing CSS cascades using the header class and header identifier, but as they say, “You’ll not throw out the words from a song”. Not only is the creation of two CSS cascades meaningless in this case, and using id in CSS makes it impossible for you to reuse CSS, and this in turn leads to duplication. Therefore, we will only use the header class. I will change our code as follows:
<header class="header"> <div class="wrapper"> <div class="menu_block"> <!-- menu --> </div> <div class="search_block"> <!-- search --> </div> </div> </header>
.header{..} .header .search_block{...}
But to be honest, I have big doubts that this is the header of the site. I am more inclined to think that this is the top panel. Therefore, I advise you to rename the header class to top-panel.
<div class="top-panel"> <div class="wrapper"> <div class="menu_block"> <!-- menu --> </div> <div class="search_block"> <!-- search --> </div> </div> </div>
.top-panel{..} .top-panel .search_block{...}
Go ahead in our structure and meet the div with the wrapper class:
<div class="top-panel"> <div class="wrapper"> <!-- menu and search --> </div> </div>
And to complete the picture CSS:
.wrapper{ margin: 0 auto; width: 940px; padding: 0 10px; }
The word wrapper can be translated as a wrapper . Not quite clear what she wraps? And this block is not a wrapper at all. So with this class I got excited.
This element serves to center and indicate the width of our site. In fact, this is the main block of the page, in which all the rest are placed. Therefore, it would be logical to call it main-container .
<div class="top-panel"> <div class="main-container"> <!-- menu and search --> </div> </div >
Now let's take a closer look at the menu, which has the following structure:
<div class="menu_block"> <ul class="menu"> <li class="menu_item"><a href="#" class="item"> </a></li> <li class="menu_item"><a href="#" class="item"> </a></li> <li class="menu_item"><a href="#" class="item"></a></li> <li class="menu_item"><a href="#" class="item"></a></li> <li class="menu_item"><a href="#" class="item"></a></li> <li class="menu_item"><a href="#" class="item"></a></li> <li class="menu_item"><a href="#" class="item"></a></li> </ul> </div>
And the following CSS:
.menu_block{...} .menu{...} .menu_item{...} .item{...} .item:hover{...}
The first thing you want to ask is, looking at this code, why does the ul tag nesting in a div? The ul tag, like the div tag, refers to block elements, so in this case the ul tag does not need to be wrapped with a div tag.
<ul class="menu_block menu"> <li class="menu_item"><a href="#" class="item"> </a></li> ... </ul>
Further, I had a very bad habit of adding “explanations” to classes like _block, _list, etc. This method does not help your code be more transparent . This is an extra tautology, which is meaningless and can easily break. Therefore, I will change the code as follows:
<ul class="menu"> <li class="menu_item"><a href="#" class="item"> </a></li> ... </ul>
.menu{...} .menu_item{...} .item{...} .item:hover{...}
Next, look at the link with the item class. This class name is very general. If six months later I was asked why I was using this class, I would not answer. I wouldn’t answer even when this layout was created if I hadn’t looked in HTML. Remember that the class name should reflect the meaning of the element.
Now we change the code:
<ul class="menu"> <li class="menu__item"><a href="#" class="menu__link"> </a></li> ... </ul>
.menu{...} .menu__item{...} .menu__link{...} .menu__link:hover{...}
Now, if even at 4 nights they call me and ask why the menu __ menu class is there, then I will answer to style the links in the menu.
Now consider a search with the following structure:
<div class="search_block"> <form class="search"> <input type="text" class="search_field" placeholder=" "> <button type="submit" class="search_icon"> <img src="http://images/search_icon.png" alt=" "> </button> </form> </div>
As you can see, here, as before, there is a manifestation of my illness of tautology and the extra nesting of the block element form in the block div. I hope that now you know how to solve such problems, so I will leave it to you. You must train! But if you do not want the answer in the next paragraph.
In addition to the errors listed above, there are several more in this snippet. First, the name attribute is not specified for the input field.
The second is the search_icon class name for the search button. Again, if they ask me what this element is for, I will not give you the right answer again. Therefore, we will change the class to search__button.
Third, the use of a decorative icon with a magnifying glass in HTML. Why is this a mistake? Because, all the inserted images on the page using the img tag will be indexed by search robots. I don’t see much sense in indexing the elements of decor, therefore, I advise you to leave in HTML only the images that relate to the page content.
Now change the HTML.
<form class="search"> <input type="text" class="search__field" name="query" placeholder=" "> <button type="submit" class="search__button"></button> </form>
Everything seems to be fine now ... But, stop! We now have a completely empty button! This is a very bad tone in the layout. If we don’t load the CSS or the user visits the site using electronic readers, they simply won’t see it or hear it. Therefore, we need to add the word "Find", which we will hide using the text-indent property.
<form class="search"> <input type="text" class="search__field" name="query" placeholder=" "> <button type="submit" class="search__button"></button> </form>
We now turn to CSS.
.top-panel .search{...} .top-panel .search .search_field{...} .top-panel .search .search_field:focus{...} .top-panel .search .search_button{...}
As you can see now, I have indicated the entire nesting chain in the CSS selector. I constantly encounter such errors. Let's take a closer look at this error.
First, we are used to reading from left to right with you, and therefore we think that the browser will first find an element with the top-panel class, and then inside it an element with the search class. But, in fact, the opposite is true! Browsers read the CSS selector from right to left, so first he will find elements with the search class, and only then they will find ancestors with the top-panel class.
Secondly, all start-up designers think that they are making the site and nobody else will touch it. And he will live in this state all his life. But, in fact, the layout in its original form lives exactly up to the moment when programmers touch it.
But, this is half the trouble. If you impose a little bit visited site, then sooner or later you will have to make changes on it. Suppose you want to move the search block to another place on the page. For example, in the basement. With the current implementation, you will need to change both HTML and CSS. This is all because the nesting of elements is indicated. You will have to duplicate CSS properties.
To solve this problem, we need to change the CSS as follows:
.search{...} .search__field{...} .search__field:focus{...} .search__button{...}
It's simple! Now we can move the search, the search field and even the button wherever we want.
We now turn to the consideration of menu positioning and search. By design, it is clearly visible that the menu is pressed to the left side of the main container, and the search to the right one. Obviously, you want to use float elements. The current implementation looks like this:
.top-panel{ background-color: #ededed; min-width: 960px; height: 40px; } .menu{ float: left; } .search{ float: right; }
What is the mistake here? Due to the fact that the element with the class top-panel has a height of 40 pixels, the blocks look as it should. But, if we inspect an element with a main-container class with the help of a web inspector, we will see that its height is zero. This is a side effect when using float elements. What can be done with this? According to the logic of the novice layout designer, you just need to set the height. And so something like this will appear:
.top-panel{ background-color: #ededed; min-width: 960px; } .top-panel .main-container{ height: 40px; }
The main problem is not even in the cascade nesting, but in the fact that a fixed value is indicated for the height of the element with the class main-container . In the layout, the height of the block should be adjusted to the content of the element. Therefore, it can not be fixed.
Well, you can not set the height, but how to fix this situation? There is a very simple and reliable way. This is to add an element with the clear property and the value of both behind the float elements or to the end of the parent block, as in our case.
To add such an element, we use the pseudo-element: after.
.clearfix:after{ content: ""; display: block; clear: both; }
And the HTML will look like this:
<div class="top-panel"> <div class="main-container clearfix"> <ul class="menu"> <!-- menu --> </ul> <form class="search"> <!-- search --> </form> </div> </div>
CSS will change as follows:
.top-panel{ background-color: #ededed; min-width: 960px; } .menu{ float: left; } .search{ float: right; }
And now, let's think about the next question. We have already said that with proper layout, blocks can be freely moved around the page. But, with the current implementation, we will not achieve such universality due to the float property. How to be? We know for sure that the top menu bar is on the left and the search is on the right. Therefore, it is possible to create additional classes in which we will write float:
<div class="top-panel"> <div class="main-container clearfix"> <ul class="menu top-panel__menu"> <!-- menu --> </ul> <form class="search top-panel__search"> <!-- search --> </form> </div> </div>
CSS will change as follows:
.top-panel{ background-color: #ededed; min-width: 960px; } .top-panel__menu{ float: left; } .top-panel__search{ float: right; }
To style the block I use the following CSS:
.top-panel__menu{ float: left; } .menu{ width: 620px; padding: 12px 0; list-style: none; } .menu__item{ display: inline-block; } .menu__link{ color: #353743; font-size: 14px; margin-right: 15px; text-decoration: none; } .menu__link:hover{ text-decoration: underline; }
What mistakes I see here.
First, the menu padding is set at the top and bottom equal to 12 pixels. This is necessary in order to make indents from the edge of the block. It seems all is well. But, if we look at the top panel as a whole, we will see that the search also has indentation from above. Therefore, it is better to set the total indent to the parent block. For example, .top-panel. And in the menu, add missing values ​​using the already-margin, since this will already have an external indent:
.top-panel{ background-color: #ededed; min-width: 960px; padding-top: 7px; padding-bottom: 7px; } .top-panel__menu{ float: left; } .menu{ width: 620px; margin-top: 5px; margin-bottom: 5px; list-style: none; }
Secondly, in this case, the menu does not need to specify the width. You remember that layout in its initial state does not live long? There may be more menu items on a live site, so it must be freely expanded.
Thirdly, the indents between menu items are for some reason given to the links, although it is more logical to do this for the li elements. Like a little thing? But in the layout there are no trifles!
The modified CSS menu now looks like this:
.top-panel{ background-color: #ededed; min-width: 960px; padding-top: 7px; padding-bottom: 7px; } .top-panel__menu{ float: left; } .menu{ margin-top: 5px; margin-bottom: 5px; list-style: none; } .menu__item{ display: inline-block; margin-right: 15px; } .menu__link{ color: #353743; font-size: 14px; text-decoration: none; } .menu__link:hover{ text-decoration: underline; }
To style the block I use the following CSS:
.top-panel__search{ float: right; } .search{ padding: 5px 0; } .search__field{ width: 135px; height: 25px; background-color: #D2D2D2; padding: 0 10px; font-size: 12px; transition: width 0.9s 0s; vertical-align: middle; } .search__field:focus{ width: 200px; outline: none; } .search_button{ position: relative; right: 4px; top: 1px; background: none; vertical-align: middle; }
Due to the fact that I added padding to an element with the top-panel class, we have increased the distance from the top edge of the panel to the search. Therefore, I will remove it from the search class.
Also, earlier, we changed the layout of the search button, therefore, at this stage it is different from the design. We need to set the button sizes and add a magnifying glass icon using the backgorund property. You also need to set text-indent to hide the text:
.search_button{ width: 25px; height: 25px; position: relative; right: 4px; top: 1px; text-indent: -9999px; background: url("../images/search_icon.png") no-repeat 0 0; vertical-align: middle; }
Now we analyze errors. The first thing that catches your eye is the use of the position in the button. If we disable position: relative in the web inspector, we will see the distance between the input field and the button. It appeared because both the input field and the button are line block elements.
To solve this problem, I simply set the float property with the value left and remove the position from the button:
.search__field{ width: 135px; height: 25px; background-color: #D2D2D2; padding-right: 10px; padding-left: 10px; font-size: 12px; transition: width 0.9s 0s; float: left; vertical-align: middle; } .search_button{ width: 25px; height: 25px; float: left; text-indent: -9999px; background: url("../images/search_icon.png") no-repeat 0 0; vertical-align: middle; }
Next, add the previously created clearfix class to the element with the search class:
<form class="search clearfix"> <input type="text" class="search__field" name="query" placeholder=" "> <button type="submit" class="search__button"></button> </form>
And it seems like it works. But! We now have one of my favorite mistakes that I encounter even among experienced web designers. Let's look again at the CSS input fields and buttons:
.search__field{ width: 135px; height: 25px; background-color: #D2D2D2; padding-right: 10px; padding-left: 10px; font-size: 12px; transition: width 0.9s 0s; float: left; vertical-align: middle; } .search_button{ width: 25px; height: 25px; float: left; text-indent: -9999px; background: url("../images/search_icon.png") no-repeat 0 0; vertical-align: middle; }
In both classes, there is a vertical-align property, with which you can align line-block elements along the vertical axis. But! Now we have block elements! The float property affects the flow of elements and makes them block. It must always be remembered. Therefore, I remove the vertical-align elements.
.search__field{ width: 135px; height: 25px; background-color: #D2D2D2; padding-right: 10px; padding-left: 10px; font-size: 12px; transition: width 0.9s 0s; float: left; } .search_button{ width: 25px; height: 25px; float: left; text-indent: -9999px; background: url("../images/search_icon.png") no-repeat 0 0; }
When I started writing an article, I did not think that the description of my mistakes would occupy such a volume of text. Therefore, if you want to continue to analyze the errors of the next block, then write me about it in the comments.
Source: https://habr.com/ru/post/307210/
All Articles