254

How can I relatively position an element, and have it not take up space in the document flow?

Web_Designer
  • 72,308
  • 93
  • 206
  • 262

6 Answers6

355

What you're trying to do sounds like absolute positioning. On the other hand, you can, however, make a pseudo-relative element, by creating a zero-width, zero-height, relatively positioned element, essentially solely for the purpose of creating a reference point for position, and an absolutely positioned element within that:

<div style="position: relative; width: 0; height: 0">
    <div style="position: absolute; left: 100px; top: 100px">
        Hi there, I'm 100px offset from where I ought to be, from the top and left.
    </div>
</div>
Nightfirecat
  • 11,432
  • 6
  • 35
  • 51
  • 1
    how would you inherit the width in this case? since the relative div width is 0, the absolute div wouldn't be able to inherit the width properly if they're both in a container – Alex Feb 20 '17 at 06:24
  • @AlexH Unfortunately, this method does not offer a way to do that. I'd advise attempting FredK's negative-position/negative-margin method in this case. – Nightfirecat Feb 24 '17 at 21:51
135

Add a margin equal to the pixels that you moved:

Example

.box {
    position: relative;
    top: -30px; 
    margin-bottom: -30px;
}
Fred K
  • 13,249
  • 14
  • 78
  • 103
  • 9
    somehow makes more sense to me than the other answer – markasoftware Nov 03 '13 at 04:44
  • 2
    Does this work? I'm trying it in chrome and doesn't seem to work. I'm using it to position navigation buttons from slidesjs, so that can be messing with it also. – Petruza Feb 19 '14 at 17:49
  • 2
    I tried this with `left: -25px; margin-right: -25px;` and it still offsets the sibling elements horizontally by 2-3 pixels for some reason. – Mike May 20 '15 at 22:38
  • Include the use of `float:right;` when you want to make this relative to the right side of the screen so that the values of right or left can be smaller and more manageable. – Damian Green Feb 26 '16 at 05:46
  • 2
    bear in mind for positive `top:` values you need to have `margin-bottom:` equal to the minus of the element height not the displacement – Mr Heelis Aug 29 '18 at 10:55
  • This is the only answer that worked when relative element is inside overflow container with scrolling. (Answers that put element inside invisible absolute div do not work, since it will not scroll with the overflow) – Michal Minich Oct 24 '18 at 20:07
  • For me the trick was to add margin equal to the width of the element, not the pixels I moved it. So, my element had width 40px but I moved it -70px, so I had to add a margin-right of -40px to make the other elements appear as if the element wasn't there. – Mierpo May 28 '20 at 07:25
  • This answer also works for css `::before` elements. – Lazerbeak12345 Nov 06 '20 at 16:34
38

From reading up a little, it seems you can absolute position an element as long as the parent element is relatively positioned. That means if you have the CSS:

.parent { 
    position: relative; 
}
.parent > .child {
    position: absolute;
}

Then the child element won't take up any space in the document flow at all. You can then position it using one of the "left", "bottom", etc, properties. The relative positioning on the parent shouldn't usually affect it because it will be positioned at its original position by default if you don't specify "left", "bottom", etc.

http://css-tricks.com/absolute-positioning-inside-relative-positioning/

jeteon
  • 3,471
  • 27
  • 40
5

You simply take that element off the document flow by setting position: absolute, and leave it's breaking point move freely with the dynamic flow of content by not specifying the left top right and bottom style properties which will be forcing it to use the relative endpoint of the flow dynamically. This way the absolutely positioned element will follow the document flow while removing itself from taking up the space.

No dummy wrappers are needed.

Bekim Bacaj
  • 5,707
  • 2
  • 24
  • 26
  • a simple exmple code might help much more instead of reading and understanding the whole paragrah. Althought the concept is clear – MR_AMDEV Jun 05 '19 at 04:43
  • 2
    This only works in the restricted case scenario where we indeed do not intend to use coordinates to shift the absolute element anywhere. This feels unnatural since it will most likely overlap with the next elements of the flow. John T. made an example [here](https://stackoverflow.com/a/49435312/5034260) but suggested setting one of the coordinates to shift it to the side if we so wanted. The relative wrapper solution is precisely to be able to use relative coordinates, so the need for it depends on what OP really wanted. – Link-akro May 15 '21 at 13:04
2

@Bekim Bacaj had the perfect answer for me, even though it may not be exactly what the OP was looking for (although his question leaves room for interpretation). That being said, Bekim didn't provide an example.

<h1>Beneath this...</h1>
<style>
    .HoverRight {
        background: yellow;
        position: absolute;
        right: 0;
    }
</style>
<div class="HoverRight">Stuff and Things!</div>
<p>but, top = same as this paragraph.</p>

The example above sets up an element that...

  • uses pure and simple CSS and nothing else
  • is vertically positioned as if it was in the flow (default top setting)
  • is horizontally positioned at the right edge of the page (right: 0)
  • does not take up any space, yet will move naturally as the page scrolls (position: absolute)
John T.
  • 451
  • 6
  • 6
  • The resulting coordinate depends on its innermost positioned parent (i mean with the position property, not coordinates), which in your example is the body, but may be different. Yet another wrapper or annoying coordinate computation might creep on this. – Link-akro May 15 '21 at 13:10
  • I haven't tested but I think you're right; my oversimplified solution may only work in this simplest form, but not so much when deeply buried in a pile of elements as in a normal web page. Ah, CSS, why are you so frustrating? – John T. May 17 '21 at 14:29
0

For me the given solutions did not worked fine. I want to see a h3, than text and after that Bootstrap-panels, vertical-synchroneous to this panels i want to see other panels on the right side,

I managed this with a height:0 wrapper and after that position:relative;left:100% .

<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">

    <div class="row">
        <div class="col-md-9">
            <div class="col-md-12">
                <h3> hello </h3>
            </div>
            <div class="col-md-12">
                <span> whats up? </span>
            </div>
            <div style="height:0" class="col-md-12">
                <div style="left:100%" class="col-md-3">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <h3 class="panel-title">Panel title</h3>
                        </div>
                        <div class="panel-body">
                            <p>Panel Body</p>
                        </div>
                    </div>
                </div>
            </div>

            <div class="col-md-12">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">Panel title</h3>
                    </div>
                    <div class="panel-body">
                        <p>Panel Body</p>
                    </div>
                </div>
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">Panel2 title</h3>
                    </div>
                    <div class="panel-body">
                        <p>Panel Body</p>
                    </div>
                </div>
            </div>

        </div>
        <div class="col-md-3">
            <!--placeholder-->
        </div>

    </div>
</div>
Reiner
  • 1,621
  • 1
  • 16
  • 22