Position fixed doesn't work inside relative position, CSS - javascript

I'm trying to put div with position:fixed inside div with position:relative.
This is CSS:
#wrapper {
background-color: #199eaf;
height: auto;
left: 0;
min-height: 100%;
position: relative;
text-align: left;
top: 0;
width: 100%;
}
.menu-space {
background: #fff none repeat scroll 0 0;
height: 174px;
left: 0;
overflow: hidden;
padding: 43px;
position: fixed;
top: 0;
transform: skewY(-10deg);
width: calc(100% + 100px);
z-index: 800;
}
This for some reason doesn't work as I expect. My div goes inside next div in #wrapper div (See screenshot: http://www.awesomescreenshot.com/image/445294/fb3d41bfb92a0f76d60266ed0ac4f0a9) I can make this work just if I use one of this two solution for .menu-space div
transform: skewY(-10deg) translate(0px, -101px);
or
top: -170px;
But I really don't want to use those minus values. Can someone please help me to find better solution?
This is how menu should look
http://www.awesomescreenshot.com/image/445297/e799ee584ead6007b9fe16628ccc15bc
and on scroll:
http://www.awesomescreenshot.com/image/445300/cee6600490bab7e58a479da23ac9974a
Thank you!

By default, transforms happen from the center of the element. Your skew is twisting the element from its center, causing the left side to drop and the right side to rise.
Set transform-origin: top left (or 0 0 if you prefer) and you can get rid of the negative top or translate.
.menu-space {
background: #fff none repeat scroll 0 0;
height: 174px;
left: 0;
overflow: hidden;
padding: 43px;
position: fixed;
top: 0;
transform: skewY(-10deg);
transform-origin: top left;
width: calc(100% + 100px);
z-index: 800;
}
See MDN

The reason for this is the transform: skewY(-10deg);. As per the W3C spec, if position: fixed; is used on an element inside an element with a transformation applied to it, the fixed-position element is positioned relative to that transformed element.

Related

Modal fixed position content shift

After a lot of research, I am unable to find a proper solution for the shifting to the right of fixed positioned elements, cover images, and standard content, when a modal window is open.
Note: I am looking for a general, clean solution, not an hardcoded fix that would work just on a specific layout.
Does anyone know how to fix this issue? Please refer to this example: http://codepen.io/microcipcip/pen/kXdRWK
body {
height: 2500px;
&.-modal-open {
overflow: hidden;
}
}
.fixed {
position: fixed;
top: 0;
left: 0;
width: 100%;
padding: 20px 0;
background: #FF0000;
}
.modal {
overflow-x: hidden;
overflow-y: scroll;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
opacity: 0;
transition: opacity .2s ease-in-out;
body.-modal-open & {
opacity: 1;
}
}
The solution is very simple and a pure css fix:
.-modal-open .fixed,
.-modal-open .content {
overflow-y:scroll;
}
..however, this requires that your content is styled differently. You should never use a margin for your content, but rather wrap it in a container and use padding instead.
The scrollbar's width isn't always 17px... 17px is for Firefox, but 15px for chrome, sometimes IE doesn't even have a scrollbar width depending on the code.
Here is the updated pen:
http://codepen.io/scooterlord/pen/KgKLwB
edit: forgot to say, that this is a cross-browser solution and works flawlessly everywhere I tested it. If the browser is mobile, then no change of width happens anyway from the addition/removal of the extra scrollbars and depending on the browser the newly created scrollbars for the content/fixed elements is always the same as the initial body scrollbar.
The main trick is to not use body as your content wrapper. Use a dedicated div as wrapper and place your modals outside so the scrollbars don't interfere with each other.
var $btnShow = document.querySelector('.show');
var $btnHide = document.querySelector('.hide');
var $body = document.querySelector('.modal');
$btnShow.addEventListener('click', function() {
$body.classList.toggle('-modal-open')
});
$btnHide.addEventListener('click', function() {
$body.classList.toggle('-modal-open')
});
.wrapper {
position: fixed;
top: 0;
left: 0;
bottom:0;
right:0;
overflow: auto;
}
.content {
background: url('https://www.dropbox.com/s/m16kxhb2jg5jwwh/bear-800x450.jpg?dl=0&raw=1');
background-size: cover;
background-position: center center;
height: 2500px;
width: 100%;
}
.clickme {
position: fixed;
top: 50%;
left: 50%;
padding: 10px;
border: none;
background: #000000;
color: #ffffff;
text-transform: uppercase;
transform: translate(-50%, -50%);
}
.clickme:hover {
background: grey;
cursor:pointer
}
.modal {
overflow-x: hidden;
overflow-y: scroll;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
display: none;
transition: opacity .2s ease-in-out;
z-index: 3;
}
.modal.-modal-open {
display:block;
}
.modal-content {
min-height: 1500px;
margin: 100px;
background: url('https://www.dropbox.com/s/u520y7yo711uaxi/poster2.jpg?dl=0&raw=1');
background-size: cover;
}
<div class="modal">
<div class="modal-content">Content
<button class="clickme hide">Toggle Modal HIDE!</button>
</div>
</div>
<div class="wrapper">
<div class="content">
<button class="clickme show">Toggle Modal SHOW!</button>
</div>
</div>
How about adding 17px right-margin to the body each time a modal is opened. That would emulate the space that was reserved for the scroll bar. (17px is the width of standard browser width)
body.-modal-open {
margin-right: 17px;
}
meanwhile, for for fixed element you recalculate the width;
.-modal-open .fixed {
width: calc(100% - 17px);
}
There is still one problem though, the CSS background image is still shifted, the solution is simply placing it in a div container instead of the body.

Preserving div ratio when height is the limiting factor

I am trying to create a "slide" div that is centered in the middle of the screen with a constant aspect ratio.
Combining this trick for centering and this one for the ratio, I came up with this:
HTML
<div class="slide">
<div class="slide-content">
Percentage sized and still centered.
</div>
</div>
CSS
/* slide centered in the middle of the screen + width = 80% */
.slide {
position: fixed;
width: 80%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: red;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.2);
}
/* aspect ratio of 2:1 */
.slide:before{
content: "";
display: block;
padding-top: 50%;
}
/* stretch the content to the slide size */
.slide > .slide-content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: 40px 60px;
transition: all 0.6s ease-in-out;
}
Fiddle is here: https://jsfiddle.net/3jph853w/
It works beautifully, expect on mobile in landscape view: the trick being based on width, the div is not resized properly and part of it "overflows" outside the screen. You can see it when you resize the fiddle output vertically.
How can I fix it ? I would rather keep it css only, with additional html markup is necessary. I am open to JS, but my project is Angular based and does not use jQuery.
This might be a start
Fiddle demo 100% of viewport
Fiddle demo 80% of viewport
html, body{
margin: 0;
}
.slide{
position: absolute;
width: calc(100vh * 2);
height: calc(100vw * 0.5);
max-width: 100vw;
max-height: 100vh;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.slide-content{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: red;
padding: 40px 60px;
box-sizing: border-box;
transition: all 0.6s ease-in-out;
}
<div class="slide">
<div class="slide-content">
Percentage sized and still centered.
</div>
</div>
add text-align:center; to the bottom of .slide > .slide-content {

Centering modals that work in IE8

I am trying to center my modals and I have the following code http://jsfiddle.net/be34jkzk/4/
That is the code I have. I just want to make sure that the modal is centered and kinda responsive. I tried changing the code for modalPopupClass to something like this, but it displays it weird on IE8.
CSS:
.modalPopupClass{
display:none;
position: fixed;
top: 50%;
left: 50%;
width: 50%;
max-width: 630px;
min-width: 320px;
height: auto;
z-index: 4020;
transform: translateX(-50%) translateY(-50%);
}
Here is a technique to keep a fluid height and width div dead center vertically and horizontally. Compatible in IE8+
This is made possible with the combination of margin: auto and a tug-of-war between top: 0; left: 0; bottom: 0; and right: 0;
Use a percentage width and height (it needs a height)
Use a combination of min / max width and min / max height
Experiment to get the best results for your project.
Here is a write up on the technique over on Smashing Magazine
CSS / HTML / Demo
.dead-center {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
background: #F00;
height: 50%;
width: 50%;
min-width: 100px;
min-height: 100px
}
<div class="dead-center"></div>

fixed div and see the lower height data

I have one button, when I click in this button one div generates in the body which has this css:
div#transparentDiv {
width: 100%;
background-color: rgb(0, 0, 0);
opacity: 0.7;
height: 100%;
position: fixed;
top: 0 !important;
left: 0;
z-index: 95;
}
and one div that has none css display, remove none display and get this css
.popUp {
color: #fff;
margin: 0 auto;
position: fixed;
top: 37px;
z-index: 98;
width: 61%;
background-color: #d8d8d8;
left: 0;
right: 0;
}
now my problem is this section, my div that fixed and i can't see full content,
and when I scroll page this div fixed and don't scroll down to see the lower height
What should I do?
Without any HTML this is realy hard to answer. Try to add
overflow: scroll;
or
overflow: auto;
To your fixed div. Then you can scroll the content of your div seperatly.
If you could scroll down to see the contents of a fixed div, then it would not be fixed would it?
try this:
.popUp {
position: absolute;
}

Pure JavaScript: Center an absolute position div in body

What's the easiest and shortest way to center an absolute position div in the body without using a library like jQuery. Thank you!
Edit:
Something like http://jsfiddle.net/apfwh/ but maybe with a bit cleaner?
I think no js needed. CSS will do it (see here):
body {
background: #888;
}
.box {
width: 100px;
height: 100px;
background: #ccc;
position: absolute;
left: 50%;
top: 50%;
margin: -50px 0 0 -50px;
}
UPD
In case you don't have fixed width/height of element:
JS (when element is opened):
element.style.margitLeft = -element.offsetWidth / 2
element.style.margitTop = -element.offsetHeight / 2
CSS:
.box {
background: #ccc;
position: fixed;
left: 50%;
top: 50%;
}

Categories