We press the basement to the bottom. Fixed footer Making a footer

Press the footer to the bottom of the screen. Requirements:

  • the footer is pressed to the bottom of the screen when the height of the browser window is greater than the height of the page, regardless of the content
  • the footer is in its proper place when the volume of content is greater than the height of the browser window
  • works in all popular browsers
  • reliability - does not depend on the complexity of the layout

Theory

It is good practice to fill the entire available area of ​​the browser screen with the site (at least in height for designs that are static in width).

Solution

For example, let's take a simple page consisting of two main blocks: main and footer. Let's make sure that the main block takes up the entire area of ​​the browser window, regardless of the amount of content, while pressing the footer to the bottom of the screen so that a vertical scroll bar does not appear in the browser. How we do it:

Step 1

We make 2 blocks: main (main) and basement (footer). We stretch the main container to the entire height of the browser screen (), and we rigidly specify the height of the footer ().

In this case, the total height of the site will be the height of the screen + the height of the footer.

Step 2

The note: When using block layout and floating main blocks (columns) for .hFooter, you should add : both so that the footer is located under the columns.:

HFooter ( clear: both; height: 40px; )

Tested in:

Note 1: If you have already mastered CSS a little, then the question may arise: “Why use an additional element if you can use it?”. The answer is that you can’t just use it here, because... The size of a block is equal to its width and height + the sum of the internal paddings + the sum of the border thicknesses. Link: 100% and will give the height of the site greater than the height of the screen. As a result, even if there is no content at all, the footer will be outside the “first screen”. See below for how to get around this.

Note 2. In Opera version 9.5 and higher, this example will not work when adding a doctype. Workaround options:

  • add at least one floating block to the main container tag:

    This is the main block

  • add two properties for html, body:

    Html,body ( height: 100%; float: left; width: 100%; )

  • put the styles in a separate CSS file:

update 8.12.09 - Disadvantage of this technique

This is the use of an additional empty hFooter element. In real conditions (when the content of the site is not empty and block layout is used), this can be avoided by using - this example will help clear the flow without using an additional element, and so that the content does not fit on the footer, we will write it in the columns

update 12/28/09 - problems with z-layers

In the technique described above, the footer was raised with a negative indent upward. This raises a potential problem with z-layers. For example, we need to show a popup window (let it be div class="popup"), which will be positioned relative to the main container.

[...]

Main ( position: relative; /* so that child elements are positioned relative to this block */ z-index: 1; /* z-index less than the footer so that it is visible */ ) .popup ( position: absolute; z-index : 100; [...] ) .footer ( height: 50px; margin-top: -50px; position: relative; /* so that you can set the z-index */ z-index: 2; /* greater than that main to be visible */ )

Everything is fine until the pop-up window and the basement intersect (and this situation occurs quite often) - this is where the problems begin. Despite the fact that the pop-up window has the highest z-index, it will be overlapped by the footer, because the parent popup has a z-index lower than the footer:

Option 1 - look for an opportunity to position the window not relative to main, but relative to some other child element that is located in main. Thus, we will get rid of specifying z-index for main and footer. But this option is not always possible, so let’s consider the second option of pressing the footer.

Solution 2 - Absolute Positioning

The idea is similar to solution 1:

  1. stretch the main block to the full height of the screen
  2. reserve space for the basement
  3. relative to the main block, position the basement at the very bottom using absolute positioning

[...]

Html, body ( height: 100%; ) .main ( min-height: 100%; position: relative; /* so that child elements are positioned relative to this block */ ) .footer ( height: 50px; position: absolute; left: 0 ; bottom: 0; width: 100%; ) * html .footer ( bottomy:expression(parentNode.offsetHeight % 2 ? style.bottom="-1px" : style.bottom="0px"); /* hack for e6, which has a jamb with an offset of 1px */ )

This approach will solve the problem with pop-up windows, because... both footer and popup will have a common parent, which means there will be no surprises with z-layers.

Not long ago I was asked to show how to press the footer to the bottom. A similar problem arises only with block layout. And, unfortunately, there is no optimal option, but in this article I will show how I press the footer to the bottom I'm designing websites.

Let's say there is one HTML code:





To press the footer to the bottom, must be applied to this HTML code next CSS code:

HTML (
height: 100%;
}
body (
height: auto !important; //Required if there is a lot of content in main
height: 100%;
min-height: 100%;
}
#main (
padding-bottom: 50px;
}
#footer (
bottom: 0;
height: 50px;
position: absolute;
}

Everything is transparent here, but I’ll just say that the line “ height: auto !important;" allows you to take into account that if the content in main will be greater than the height of the page, then the height will be greater than 100% . Without it, the footer will simply fit over the content and will always be in the same place.

Unfortunately, the solution is not very beautiful, but others, in my opinion, are even worse. In general, when there is little content, I simply leave the background color of the site at the bottom. But sometimes the customer still asks push the basement down, and then I use the method described in this article.

Every layout designer sooner or later is faced with the need to press the footer of a website to the bottom of the page. There are several ways on the Internet to solve this problem. I will show you some of them that I myself use in practice.

The simplest html markup:

Method #1

The Footer is pushed to the bottom by positioning it absolutely and stretching the height of the parent blocks (html , body and wrapper) to 100%. In this case, the content block needs to specify a bottom margin that is equal to or greater than the height of the footer, otherwise the latter will cover part of the content.

* ( margin: 0; padding: 0; ) html, body ( height: 100%; ) .wrapper ( position: relative; min-height: 100%; ) .content ( padding-bottom: 90px; ) .footer ( position : absolute; left: 0; bottom: 0; width: 100%; height: 80px; )

Method #2

The Footer is pressed down by pulling the content block and its “parents” to the full height of the browser window and lifting the footer up through a negative margin (margin-top) to get rid of the vertical scroll that appears. In this case, it is necessary to indicate the height of the basement, and it must be equal to the amount of indentation. Thanks to the box-sizing: border-box property, we prevent the box with the content class from exceeding 100% height. That is, in this case min-height: 100% + padding-bottom: 90px equals 100% of the browser window height.

* ( margin: 0; padding: 0; ) html, body, .wrapper ( height: 100%; ) .content ( box-sizing: border-box; min-height: 100%; padding-bottom: 90px; ) . footer ( height: 80px; margin-top: -80px; )

Method #3

This method is good because, unlike other methods (except for the 5th), the height of the footer does not matter. Here we emulate the behavior of a table by turning the wrapper block into a table and the content block into a table row (display: table and display: table-row properties, respectively). Thanks to this, and the fact that the content block and all its parent containers are set to 100% height, the content is stretched to its full height, minus the footer height, which is determined automatically - table emulation prevents the footer from extending beyond the height of the browser window.

*( margin: 0; padding: 0; ) html, body ( height: 100%; ) .wrapper ( display: table; height: 100%; ) .content ( display: table-row; height: 100%; )

Method #4

This method is unlike any of the previous ones, and its peculiarity is the use of the CSS function calc() and the vh unit of measurement, which are only supported by modern browsers. Here you need to know the exact height of the footer. 100vh is the height of the browser window and 80px is the height of the footer. And using the calc() function we subtract the second value from the first, thereby pressing the footer to the bottom.

* ( margin: 0; padding: 0; ) .content ( min-height: calc(100vh - 80px); )

Method #5

This is perhaps the best method of all the ones presented, but it only works in modern browsers. As in the third method, the height of the footer does not matter.

* ( margin: 0; padding: 0; ) html, body ( height: 100%; ) .wrapper ( display: flex; flex-direction: column; height: 100%; ) .content ( flex: 1 0 auto; ) .footer (flex: 0 0 auto; )

Method #6

A whole library for different cases (using Flexbox)

Hi all!

The site looks aesthetically pleasing if all its elements are in place. However, there are often cases when everything seems to be normal, but something is still wrong... For example, if the page is short, the footer is not pressed to the bottom of the page, but is located where it should be - after the main block of the site. It doesn't look very nice.

Therefore, today we will talk to you about how to press the site footer to the bottom border of the browser window.

So, we will set the following requirements for the basement:

  • the footer is pressed to the bottom of the screen when the height of the browser window is greater than the height of the page, regardless of the content;
  • the footer is in its proper place when the volume of content is greater than the height of the browser window;
  • works in all popular browsers;
  • reliability - does not depend on the complexity of the layout.

For example, let's take a simple page consisting of two main blocks: main and footer. Let's make sure that the main block takes up the entire area of ​​the browser window, regardless of the amount of content, while pressing the footer to the bottom of the screen so that a vertical scroll bar does not appear in the browser. How we do it:

Step 1

We make 2 blocks: main (main) and basement (footer). We stretch the main container to the entire height of the browser screen (min-height), and strictly specify the height of the footer (height).

In this case, the total height of the site will be the height of the screen + the height of the footer.

Step 2

We use a negative margin (margin-top) to “enter” the main block so that the height of the site is only 100% of the screen height.

With this arrangement of blocks and with a sufficient amount of content (for example, text) in the main block, it is possible to overlay the content in the main block on the footer:

Step 3

To avoid this potential problem, add an empty block at the end of the main block, the height of which is no less than the height of the footer (or better yet, a little more so that there is some space between the content and the footer):

Now, if there is a lot of content, it will move the empty block down. And this will lower the footer, preventing content from fitting onto it.

Let's see what it looks like in code:

<html > <head > <title > The footer is pressed to the bottom</title> <style type = "text/css" >* (margin: 0; padding: 0;) /* reset padding */ body ( background: #fff;) html,body ( height: 100%; /* set the height of the document body */).main ( /* main block , which should stretch to the footer */ background: #999; /* background color of the main block (for clarity) */ min-height: 100%; /* set the minimum height of the main block */) * html .main ( /* hack for ie6 */ height: 100%; /* for ie6, because it does not understand min-height */).hFooter ( /* this is a spacer in the main block - we reserve space for the basement */ height: 40px; /* height our footer */).footer ( /* footer */ background: #0000CC; /* footer background color (for clarity) */ color: #fff; height: 40px; /* footer height */ margin-top: -40px ; /* make a negative indent in height equal to the height of the footer to clearly fit into the screen size */)</style> </head> <body > <div class = "main" > This is the main block<div class = "hFooter" > </div> <div class = "footer" > This is the basement</div> </body> </html>

Note: when using block layout and floating main blocks (columns) for .hFooter, you should add clear: both so that the footer is located under the columns.:

.hFooter ( clear : both ; height : 40px ; )

If you have already mastered a little, then the question may arise: “Why use an additional element when you can use padding-bottom?”

The answer is that you can’t just use it here, since the size of the block is equal to its dimensions + the width of the internal padding + the width of the borders. A combination of min-height: 100% and padding-bottom will give the site height greater than the screen height. As a result, even if there is no content at all, the footer will be off-screen.

The disadvantage of this technique is the use of an additional empty hFooter element. In real conditions (when the content of the site is not empty and block layout is used), this can be avoided by using this technique to help clear the flow without using an additional element, and to prevent the content from interfering with the footer, we will write padding-bottom in the columns.

Problems with z-layers

In the technique described above, the footer was raised with a negative indent upward. This raises a potential problem with z-layers. For example, we need to show a pop-up window (let it be a div), which will be positioned relative to the main container.

<div class = "main" > [...] <div class = "popup" > [...] </div> </div> <div class = "footer" > [...] </div>
.main ( position : relative ; z-index : 1 ; /* z-index less than that of the footer so that it is visible */) .popup ( position : absolute ; z-index : 100 ; [ ...] ) .footer ( height : 50px ; margin-top : -50px ; position : relative ; /* so you can set z-index */ z-index: 2; /* more than main to be visible */}

Everything is fine until our pop-up window and footer intersect (and this situation occurs quite often) - this is where the problems begin. Despite the fact that the pop-up window has the highest z-index, it will be overlapped by the footer, because the parent popup has a z-index lower than the footer:

In this case, you need to look for an opportunity to position the window not relative to main, but relative to some other child element that is located inside main. Thus, we will get rid of specifying z-index for main and footer. But this option is not always possible, so let’s consider the second option of pressing the footer.

Solution 2 - absolute positioning

The idea is similar to solution 1:

  • We stretch the main block to the entire height of the screen;
  • We reserve space for the basement;
  • Relative to the main block, we position the basement at the very bottom using absolute positioning.

HTML: relative ; /* so that child elements are positioned relative to this block */) .footer ( height : 50px ; position : absolute ; left : 0 ; bottom : 0 ; width : 100% ; ) * html .footer ( bottomy : expression(parentNode.offsetHeight % 2 ? style.bottom= "-1px" : style.bottom= "0px" ) ; /* hack for e6, which has a jamb with an offset of 1px */}

This approach will solve the problem with pop-up windows, because... both footer and popup will have a common parent, which means there will be no surprises with z-layers.

The disadvantage of both methods is that both methods are only suitable for a basement with a fixed height.

That's all for today. Now you know how to press the footer to the bottom of the screen in different ways and what problems may arise.

Subscribe to updates and look forward to new interesting publications. Bye.

  • Tutorial

Everyone who is accustomed to fully-designed website pages prefers the look of something “nailed” (sticky) to the bottom of the page footer. But there are two problems on the Internet: input fields that do not grow downwards and footers that are not nailed (to the bottom of the window). For example, when we open short pages like habrahabr.ru/settings/social, it immediately strikes the eye that the information intended to be at the bottom of the viewing window sticks to the content and is located somewhere in the middle, or even at the top of the window when the bottom is empty.

So, instead of .
This guide for beginner layout designers will show how to make a “nailed” footer in 45 minutes, correcting the shortcomings of even such a respected publication as Habr, and compete with it in the quality of execution of your promising project.

Let's look at the implementation of one type of nailed footer, taken from the network, and try to understand what is happening. css-tricks.com/snippets/css/sticky-footer
CSS:
* ( margin:0; padding:0; ) html, body, #wrap ( height: 100%; ) body > #wrap (height: auto; min-height: 100%;) #main ( padding-bottom: 150px; ) /* must be the same height as the footer */ #footer ( position: relative; margin-top: -150px; /* negative value of footer height */ height: 150px; clear:both;) /* CLEAR FIX*/ .clearfix:after (content: "."; display: block; height: 0; clear: both; visibility: hidden;) .clearfix (display: inline-block;) /* Hides from IE-mac \*/ * html .clearfix (height: 1%;).clearfix (display: block;) /* End hide from IE-mac */
HTML:

It is unlikely that everyone, even those who know CSS, will, looking at this code, understand the principles and confidently edit a complex project. Any step to the side will lead to side effects. The discussion and construction of the footer below is intended to provide more understanding of the rules of CSS.

Let's start with theory

The usual implementation of a nailed footer relies on the unique CSS2 property that elements are immediate children of BODY- maintain percentage height ( height:100% or another) relative to the window, if all their parents have the same percentage height, starting from the tag HTML. Previously, without doctypes, but now in Quirks Mode, percentage heights of elements are supported at any level, and in modern doctypes - only within percentage-defined elements. Therefore, if we make a content block (let's call it #layout) having 100% height, it will scroll as if it were a window. All (streaming) content is placed in it, except the footer and maybe the header.

The footer is placed after this block and given 0 pixels of height. In general, you can follow #layout place as many blocks as you like, but they should all be either 0 pixels high or outside the flow of the document (not position: static). And there is another important trick that is usually used. It is not necessary to make the height equal to 0. You can make the height fixed, but subtract it from the main block using the property margin-bottom: -(height);.

In human terms, styles create an empty “pocket” at the bottom, into which the footer is inserted, and it always ends up either stuck to the bottom border of the window, or to the bottom border of the document, if the height of the document is greater than the height of the window. There are many footer implementations on the Internet and on Habré, with varying degrees of success in all browsers. Let’s continue to build it ourselves, using Habr’s layout as a “workhorse”.

Because the bottom of the block #layout- this is a pocket, for the footer it should be empty, not displaying page objects. And here we encounter another limitation - we cannot create an empty pocket at the expense of padding V #layout, because then it will become more than 100%. It won't save you either margin- emptiness must be created using the properties of nested elements. Plus, it is necessary to ensure that floating elements do not crawl under the block border, which is done, for example, by the block

, Where .clear(clear:both). It is important that either this " height" was fixed, either in the same relative units, or we would calculate it during page changes. It is usually convenient to combine this alignment block with setting it to the required height.

Let's look at the structure of our test subject's pages. The easiest way to do this is to open the Firebug window or a similar window (Developer Tools (Ctrl-F12)) in Chrome.

...Top advertising block...

Let's move on to a working example

Which ones do we see? layout flaws in terms of implementing the effect of a nailed footer? We see that
1) The footer on the site is located inside a block with id=layout, which does not have a percentage height. According to theory, he, the parents and the content block.content-left need to set the height to 100%. Problems arise with the latter - it is not suitable for this. Consequently, one interlayer block is missing or the footer is not at the right level. Besides,
2) The height of the footer is variable (depending on the number of elements in the list and the font size, this can be seen not from the HTML, but from the CSS). AND
3) above #layout there is an advertising block with a fixed height of 90px;
4) there are no alignment blocks either in the footer or (generally speaking) in the block #layout(yes, but above the block .rotated_posts; however, perhaps it should be classified as a footer).

Point 4 - you will have to draw it with a script.
It would seem easy to deal with the third point by adding #layout(margin-top:-90px;) But remember that this block may not exist - it is suppressed by banner cutting, or advertisers suddenly decide not to show it. There are a number of pages on the site where it is not. Therefore the dependence margin-top from an ad block is a bad idea. It's much better to place it inside #layout- then he won’t interfere with anything.

The first point is that in order for the nailed footer to work at all, you need to place a block of footer under #layout. However, with the help of javascript you can implement other nailed footer schemes, but in any case you need JS or initially correct layout to do without it.

Since we cannot be stronger than the latest website layout designer who “slapped” the footer inside the content, we will put aside the idea of ​​​​properly placing the footer on our future website (which, therefore, will be “cooler” than Habr!), and we will dissect Habr with javascript (userscript) to the correct one condition. (Let’s say right away that it is not the layout designer or switcher who is to blame, but the type of site, of course, determines the strategic decision of the project management.) This way we will not achieve the ideal, because in the first second or two during the loading process the page will have an incorrect layout. But what is important to us is the concept and the opportunity to surpass in quality the most popular website in the IT world.

Therefore, in the right place in the script (early, at the end of the page loading), we’ll write transfers of the DOM blocks of advertising and footer to the right places. (Let’s be prepared for the fact that, due to user scripts, the solution will be more complicated than a pure solution.)
var dQ = function(q)(return document.querySelector(q);) //for shortening var topL = dQ("#topline"), lay = dQ("#layout"), foot = dQ("#footer" ); if(topL && lay) //banner - inside the content block lay.insertBefore(topL, lay.firstChild); if(lay && foot && lay.nextSibling) //moving the footer lay.parentNode.insertBefore(footer, lay.nextSibling);
We have placed the blocks in their places - now all that remains is to assign the necessary properties to the elements. The footer height will have to be set exactly, simply because we already know it by the time the user script is active (end of page loading). Due to the trigger point of the userscript, as mentioned above, a jump in the display of the footer on the page is inevitable. You can try to put on a “good face”, but with a “bad game”? For what? The “bad game” of the site allows you to create a concept without extra effort, which will be enough to assess the quality and will not be needed for the “correct game” on your project.
if(foot)( //block-aligner

in the footer h.apnd_el((clss:"clear", appendTo: footer)); var footH = foot.offsetHeight; //...and measure the height of the footer ) if(topL && lay && footer && lay.nextSibling)( //aligning block of the required height in the content ("layout") h.apnd_el((clss:"clear", css:( height: (footH ||0) +"px"), appendTo: lay)); lay.style.minHeight ="100%"; h.addRules("#layout(margin-bottom:-"+ footH +"px !important)html, body (height:100%)"); )
Here we allowed ourselves to use a self-written function h.apnd_el, which does roughly the same thing as in jQuery -
$("
").css((height: footH ||0)).appendTo($(footer))
And then - another typical function of implementing CSS rules - h.addRules. You can't do without it here, because you need to declare a rule with " !important" - precisely because of the peculiarities of the priorities of styles from the user script.

With these pieces of code, we will be able to see the nailed footer in the userscript (after jumping down) and fully understand how to build the page layout. Using a jumping design on a daily basis is unpleasant, so it is recommended to do it solely for demonstration and testing. In the HabrAjax user script, I installed a similar script, closing it with the “underFooter” setting (check the box in the list of settings before “footer nailed to the bottom”), starting with version 0.883_2012-09-12.

Does nailing the footer affect the need to update ZenComment styles if they are installed? Yes, it does. Due to the complex chain of style priorities, in which styles inserted by the user script have the lowest priority, we had to slightly adjust the user styles for possibilities working with nailed footer. If you do not update your user styles (to 2.66_2012-09-12 +), the footer will not work accurately.

Block rotated_post (three popular posts from the past) looks more logical with a footer, so in the real script it is also moved to the footer.

The second point (from the list of layout shortcomings) is a discussion purely for Habr (it does not apply to user script and partially repeats the previous ones).

Pages have an issue that prevents them from making a nailed footer using pure CSS - an undefined footer height depending on the default font sizes in the browser. To implement a footer using CSS, you need to select the relative heights of the fonts, but they may not work if the user’s computer does not have the required fonts. Therefore, the solution must include a JavaScript that can adjust the approximate position of the footer to the exact position using transitions. Or, after looking at the acceptability of the solution made in a user script on different platforms, make a calculated installation of a nailed footer - first observations show that the solution is practical.

Conclusion: it is possible to fully design a layout on Habré, but for this you need a layout designer who clearly understands the behavior of the layout and places the blocks in the correct order. (Currently the footer and top banner are “in the wrong place” and not in such a way that you can just style the footer nailed down.) You can do without JS if you set the height of the footer in relative units, taking some room for font uncertainty.

Implementation

If you enable HabrAjax 0.883+, we will see the “nailed footer” working. It adapts in height using scripts. It allows you to evaluate how much better pages with a nailed footer look compared to regular ones. ZenComment user styles are compatible with scripts, but for the nailed footer to work correctly with them, you need to install ZenComment version 2.66_2012-09-12 +.

Facts about implementation behavior

Shamanism with footer, styles and scripts is shamanism (only supported by theory). The behavior is slightly different in different browsers, but in some places it is unexpected. Without user scripts and rearranging blocks, the results will be different. This is what experiments with implementation in user script yielded.

1) Firefox - unexpected lack of footer jumps. It’s strange that they are not there - rendering occurs after the footer is placed at the bottom.

2) Chrome - it surprised me with “wandering scrolling” - empty spaces at the bottom are added to the page with a period of once a second - something wrong is happening with the calculation of heights. The solution is to write html,body(height:100%) in the user style, but there is no guarantee that it will always work. It is more reliable to check whether the document does not exceed the height of the window, and if it does not, then move the footer, otherwise - nothing. Jumping is okay, it exists.

3) Opera - no jumps (v. 12.02) when the page first loads, but a hasty reload may show a footer jump. Otherwise it behaves no less correctly than Fx.

Well, you will have to specially teach Chrome to behave correctly (with a script) and roll out the version in this form for display. Therefore, the section in the user script is a little more complicated than the one given in the article.

It should be recalled that this is not a full-fledged implementation - it does not take into account, for example, cases of window resizing by the user. You can also find rare (in practice) combinations of changing footer heights before and after moving, where the logic begins to fail without leading to inconvenience. The shortcomings were left deliberately, because a balance was maintained between the complexity of improvement and the temporary nature of the solution.

As a result, we got a completely workable operating scheme, at least for fast desktop computers. If incorrect behavior of the footer is detected, the “underFooter” setting should be disabled.

What pages is this useful for?

On a standard website, without user styles, even short question and answer pages turn out to be longer than 1500px, which in most cases is unnoticeable with horizontal monitors. But even with ordinary monitors, you often come across personal user pages with a height of about 1300 pixels, where the unattached footer appears in all its glory. The number of pages in the user settings is also not very long.

If you use ZenComment user styles, they greatly reduce the required page height, and the HabrAjax user script may not show some or all of the side blocks in the sidebar. Therefore, with scripts and styles, the effect of an unattached footer is noticeably more often observed. Therefore, it is logical that the footer fix appeared in HabrAjax for the first time. But a regular website also has a number of pages where a nailed footer would be useful.

Will there be support?

The behavior of the site over the past year shows that the developers (and therefore the management) began to introduce features that previously existed only in user scripts and user styles. For example, at the beginning of the year I wrote where I collected many small wishes. Six months later, I returned to it and was pleased to note (right in the text; you can see the “UPD” and dates) that a number of features described as wishes had already been implemented into the site.

Next, let's look at the “arrows” instead of squares for rating comments. They appeared in almalexa usernames (“Prettifier”) 3 years ago and were adopted into ZenComment 2 years ago. About 2-3 months ago they appeared on the site. One begins to believe that after some time the arrows will be spaced some distance apart, as is done in ZenComment (one arrow to the left of the number, the second to the right) in order to miss less. Add tags