CSS Static vs Relative Position Property [duplicate] - css

In CSS, what is the difference between static (default) positioning and relative positioning?

Static positioning is the default positioning model for elements. They are displayed in the page where they rendered as part of normal HTML flow. Statically positioned elements don't obey left, top, right and bottom rules:
Relative positioning allows you to specify a specific offset (left, top etc) which is relative to the element's normal position in HTML flow. So if I have a textbox inside a div I could apply relative positioning on the textbox to have it display at specific place relative to where it would normally be placed within the div:
There is also absolute positioning - whereby you specify the exact location of the element relative to the entire document, or the next relatively positioned element further up the element tree:
And when a position: relative is applied to a parent element in the hierarchy:
Note how our absolutely-position element is bound by the relatively-positioned element.
And lastly there is fixed. Fixed positioning restricts an element to a specific position in the viewport, which stays in place during scroll:
You may also observe the behaviour that fixed-positioned elements do not cause scroll because they are not considered to be bound by the viewport:
Whereas absolutely-positioned elements are still bound by the viewport and will cause scrolling:
..unless of course your parent element uses overflow: ? to determine the behaviour of the scroll (if any).
With absolute positioning and fixed positioning, the elements are taken out of HTML flow.

In answer to "why CSS would still implement position: static;" in one scenerio, using position:relative for a parent and position:absolute for the child limits the scaling width of the child. In a horizontal menu system, where you could have 'columns' of links, using 'width:auto' does not work with relative parents. In this case, changing it to 'static' will allow the width to be variable dependent on the content within.
I spent a good few hours wondering why I couldn't get my container to adjust based on the amount of content within it. Hope this helps!

You can see a simple overview here: W3School
Also, if I recall correctly, when declaring an element relative, it will by default stay in the same place as it otherwise should, but you gain the ability to absolutely position elements inside it relatively to this element, which I've found very useful in the past.

Position relative lets you use top/bottom/left/right for positioning. Static won't let you do this unless you use margin parameters. There's a difference between Top and margin-top.
You won't need to use static much as it's default

Relative position is relative to the normal flow. The relative position of that element (with offsets) is relative to the position where that element would have been normally if not moved.

Matthew Abbott has a really good answer.
Absolute and relative positioned items obey top, left, right and bottom commands (offsets) where static positioned items do not.
Relatively positioned items move offsets from where they would normally be in the html.
Absolute positioned items move offsets from the document or the next relatively positioned element up the DOM tree.

Static: By default the position of elements is static. If you add property such as top, bottom, right, or left nothing will be implemented.
div{
width:200px;
height:200px;
background-color:yellow;
display:inline-block;
}
#middle{
background-color:pink;
}
#static #middle{
position:static;
top:100px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<h1>Position Property</h1>
<section id="static">
<h2>Static</h2>
<div></div>
<div id="middle"></div>
<div></div>
</section>
</body>
</html>
Relative: The change in position will be relevant to that div's original place.
div{
width:200px;
height:200px;
background-color:yellow;
display:inline-block;
}
#middle{
background-color:pink;
}
#relative #middle{
position:relative;
top:100px;
left:100px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<h1>Position Property</h1>
<section id="relative">
<h2>Relative</h2>
<div></div>
<div id="middle"></div>
<div></div>
</section>
</body>
</html>
Absolute: It is positioned relative to its closest positioned ancestor, if any; otherwise, it is placed relative to the initial containing block. Source:MDN
div{
width:200px;
height:200px;
background-color:yellow;
display:inline-block;
}
#middle{
background-color:pink;
}
#absolute{
position:relative;
}
#absolute #middle{
position:absolute;
top:10px;
left:10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<h1>Position Property</h1>
<section id="absolute">
<h2>Absolute</h2>
<div></div>
<div id="middle"></div>
<div></div>
</section>
</body>
</html>
Fixed: The fixed property would stay at the same place even after we scroll the page. The position is relative to the containing block always.
div{
width:200px;
height:200px;
background-color:yellow;
display:inline-block;
}
#middle{
background-color:pink;
}
#fixed #middle{
position:fixed;
top:10px;
left:10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<h1>Position Property</h1>
<section id="fixed">
<h2>Fixed</h2>
<div></div>
<div id="middle"></div>
<div></div>
</section>
</body>
</html>

Related

Safari is not preventing the scrolling of <body style="overflow-y: hidden">

Here's the extremely simple HTML page
<body style="overflow-y: hidden">
...
</body>
The expected behavior of this page is: scrolling of a document is prevented because of overflow-y: hidden.
It works as expected (scrolling is prevented) everywhere except Safari.
Live demo: https://spotted-chime.glitch.me/
The question is: how to make Safari behave the same way as other browsers?
Just use overflow: hidden and it will work.
Alternatively, you can try using position: fixed on the <body> tag as well.
(NOTE: Using this approach, the body will scroll to the top as by default the top: 0.)
EDIT: For safari mobile devices, you need to use Javascript events. Explained in this answer.
https://stackoverflow.com/a/4770179/2860486
Position fixed is meant to create a div that stays in the same position on the screen while the content behind it is scrolled down.
fixed
The element is removed from the normal document flow, and no
space is created for the element in the page layout. It is positioned
relative to the initial containing block established by the viewport,
except when one of its ancestors has a transform, perspective, or
filter property set to something other than none (see the CSS
Transforms Spec), in which case that ancestor behaves as the
containing block. (Note that there are browser inconsistencies with
perspective and filter contributing to containing block formation.)
Its final position is determined by the values of top, right, bottom,
and left.
This value always creates a new stacking context. In printed
documents, the element is placed in the same position on every page.
Have you tried changing it to absolute?
body {
overflow-y: hidden;
}
#backdrop {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, .2);
border: 5px dashed black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello!</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="backdrop">
</div>
<div>0%</div>
<div>1%</div>
<div>2%</div>
<div>3%</div>
<div>4%</div>
<div>5%</div>
<div>6%</div>
<div>7%</div>
<div>8%</div>
<div>9%</div>
<div>10%</div>
<div>11%</div>
<div>12%</div>
<div>13%</div>
<div>14%</div>
<div>15%</div>
<div>16%</div>
<div>17%</div>
<div>18%</div>
<div>19%</div>
<div>20%</div>
<div>21%</div>
<div>22%</div>
<div>23%</div>
<div>24%</div>
<div>25%</div>
<div>26%</div>
<div>27%</div>
<div>28%</div>
<div>29%</div>
<div>30%</div>
<div>31%</div>
<div>32%</div>
<div>33%</div>
<div>34%</div>
<div>35%</div>
<div>36%</div>
<div>37%</div>
<div>38%</div>
<div>39%</div>
<div>40%</div>
<div>41%</div>
<div>42%</div>
<div>43%</div>
<div>44%</div>
<div>45%</div>
<div>46%</div>
<div>47%</div>
<div>48%</div>
<div>49%</div>
<div>50%</div>
<div>51%</div>
<div>52%</div>
<div>53%</div>
<div>54%</div>
<div>55%</div>
<div>56%</div>
<div>57%</div>
<div>58%</div>
<div>59%</div>
<div>60%</div>
<div>61%</div>
<div>62%</div>
<div>63%</div>
<div>64%</div>
<div>65%</div>
<div>66%</div>
<div>67%</div>
<div>68%</div>
<div>69%</div>
<div>70%</div>
<div>71%</div>
<div>72%</div>
<div>73%</div>
<div>74%</div>
<div>75%</div>
<div>76%</div>
<div>77%</div>
<div>78%</div>
<div>79%</div>
<div>80%</div>
<div>81%</div>
<div>82%</div>
<div>83%</div>
<div>84%</div>
<div>85%</div>
<div>86%</div>
<div>87%</div>
<div>88%</div>
<div>89%</div>
<div>90%</div>
<div>91%</div>
<div>92%</div>
<div>93%</div>
<div>94%</div>
<div>95%</div>
<div>96%</div>
<div>97%</div>
<div>98%</div>
<div>99%</div>
<div>100%</div>
<!-- include the Glitch button to show what the webpage is about and
to make it easier for folks to view source and remix -->
<div class="glitchButton" style="position:fixed;top:20px;right:20px;"></div>
<script src="https://button.glitch.me/button.js"></script>
</body>
</html>
Try this:
<head>
<style>
.forSafari::-webkit-scrollbar { width: 0 !important }
</style>
</head>
<body style="overflow-y: hidden" class="forSafari">
...
</body>
just use "position: relative" or fixed it will resolve the problem

CSS subsclass without parent class

I have two items
One with classes:
navbar__item dropdown-wrap navbar__item-layout
and two with classes:
navbar__item dropdown-wrap
I want like to hide item two without hide item one.
It's pretty simple using the :not(X) directive where X is the selector you don't want the styling rules to apply.
Let's take the following:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<h2 class="navbar__item dropdown-wrap navbar__item-layout">Hello</h2>
<h2 class="navbar__item dropdown-wrap">Hello 2</h2>
</body>
</html>
And the CSS:
.navbar__item.dropdown-wrap:not(.navbar__item-layout) {
font-size: 11em;
}
This should work in your case! :)
What are we doing here?
We are telling the CSS style processor that we want to apply the style rules to items with the classes .navbar__item .dropdown-wrap but at the same time, the element can't contain the class .navbar__item-layout. You can go pretty complex by using :nth-child or parent, etc.
You can do that by using :nth-child (see more here).

Avoid that an absolute positioned element push the boundaries of the page width

I have an absolute positioned div with an image inside it. It is positioned using top and left, and the width of the element is relative, I am using percentages. I am using Bootstrap as responsive framework.
The trouble is, that I can not avoid horizontal scroll, either computer and smartphone is doing horizontal scrolling.
I thought that in absolute positioning this doesn't affect. But it is making the viewport bigger so the horizontal scrolling is appearing.
I have not idea what to do to solve this, or where to start.
You can put
overflow-x: hidden;
on the body tag.
This avoids horizontal scrolling by mistake caused by absolute positioned elements somewhere.
Use this 'meta' tag in your :
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
and then your will look more or less like this :
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1 user-scalable=no">
<title>Menu Page</title>
<link rel="stylesheet" href="css/style.css">
</head>

CSS Viewport Height evaluated before minimal-ui applies on the very first load on mobile safari

When using viewport height with the minimal-ui the very first time the page load the height is evaluated with the address bar so even if I set a div with a height of 100vh the acutal height of the div is viewport height minus the height of the address bar.
In this example, on the very first load I can see the purple div after the address bar is hidden. If I reload the page or access the page without deleting the cache, the red div occupy the full height of the viewport without taking in consideration the address bar which is the behavior I'm expecting on the first load.
Any ideas why?
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui">
<title></title>
</head>
<body style="margin: 0; padding: 0;">
<div style="background-color: red; height: 100vh;">
Hello
</div>
<div style="background-color: purple; height: 50px;">
World
</div>
</body>
</html>
Thank you!

Google Chrome positioning issue

I have a problem positioning some text in google chrome, I am trying to position
"Get Directions" and "Contact" side by side. This works fine in IE,Firefox and Opera but not Chrome. I know I should probably use floats but does anyone have any idea why isn't this working correctly?
(CSS)
#main_container2{
background-color: white;
position:relative;
left: 0%;
top:0%;
width:950px;
height:985px;
font-family:arial;
font-size:36pt;
}
(HTML)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href='green_machine.css'>
<title> test</title>
</head>
<body bgcolor="black">
<div id="main_container2">
<p></p>
<font style="position:absolute;top:5%;left:6%;">Get Directions</font><p></p>
<font style="position:relative;top:5%;left:56%;">Contact</font><br>
</div>
</body>
</html>
You use:
<font style="position:absolute;top:5%;left:6%;">Get Directions</font><p></p>
<font style="position:relative;top:5%;left:56%;">Contact</font><br>
First element position: absolute and second element position: relative
Just set the both to absolute or relative
PS
I would have made it into a ul and li's
And either use float or display inline
First off, you don't need the left and top arguments on the main-container div, by default a positioned element is anchored top left.
To fix your problem though, you should try switching the second font tags position to absolute. Since the parent has a position (defined or not) the children's position will be within the parents container. Since you are trying to put them side by side, you should use position absolute on both elements.

Resources