I have div of variable width which I want to center using this code:
div {
background: red;
max-width: 400px;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
https://jsfiddle.net/xooqvyqL/1/
this works well for centering, however the problem becomes when you shrink window size down (lets say you view it on smaller screen/mobile) then you get like a 'padding' around the element taking space, which is not wanted behavior.
This is different as if was like this:
https://jsfiddle.net/xc4w4aph/5/
Note: this is not centered because of variable width (I would use negative margin if it was known width or javascript but I want to do this with pure css) but just for demo purposes if you shrink window size on this example you dont get any kind of 'padding' outside the div taking space.
I am missing something with translate? I dont want this 'padding' behavior.
Because you have set the div to position absolute, it collapses and the margins are reset and the div no longer has a default width of 100%
To restore the maximum, but restricted width, add width:100% before the max-width and everything goes back to normal.
JSfiddle Demo
div {
background: red;
width: 100%;
max-width: 400px;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facilis sint enim molestias modi officia fuga corporis, ipsa dicta tenetur, aut dignissimos, perspiciatis cumque assumenda, voluptas harum quis qui cum eligendi voluptatibus dolore! Quos hic
architecto odio repudiandae aliquid quisquam quidem beatae voluptatem sint praesentium. Tempore eveniet dolorum aspernatur, asperiores neque.</p>
</div>
Use this css code :
*{
margin:0;
padding:0;
}
div {
background: red;
max-width: 400px;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
Related
I want to be able to scroll the parent div, but have some kind of box in the center that shows the currently visible content relative to the scroll. theres probably a fancy term for it but it espaces me.
i saw a website that does something similar to this : https://www.heetch.com/ with the div that contains the phone being scrolled, only the content in the phone screen is being moved.
but im trying to do that without js, maybe with css perspectives ?
body
{
margin: 0;
}
.parent
{
width: 100vw;
height : 100vh;
background-color : "red";
display : grid;
justify-content: center;
justify-items: center;
align-items: center;
overflow-x: hidden;
overflow-y: auto;
}
.screen
{
border: solid 1px black;
width: 500px;
height: 300px;
position: sticky;
top: 50%;
transform: translateY(-50%);
z-index: 10;
box-shadow: 0px 0px 0px 2000px white;
}
.text
{
z-index: 4;
position: sticky;
width: 500px;
height: 300px;
}
<html>
<body>
<div class="page">
<div class="parent">
<div style="margin-top: 500px;"></div>
<div class="screen"></div>
<div class="text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt fugit rerum nostrum eius! Optio, alias obcaecati minus laborum, officia quas eius quisquam a, voluptates ratione porro labore rem sapiente adipisci velit. Nobis reprehenderit, eligendi accusantium provident asperiores rem maiores inventore rerum, impedit deleniti at minus commodi esse natus voluptas cupiditate, neque dolorem libero labore repudiandae sint eius blanditiis. Consectetur repudiandae accusantium ipsum at voluptatum eum. Repellat voluptate quo porro modi repellendus, dicta nam! Eligendi dolor porro officiis blanditiis dolore facilis eveniet dolorum, inventore aspernatur cumque nemo? Velit dolore, autem minus culpa aperiam deserunt dolorum quis sit vel at porro nostrum!</div>
<div style="margin-bottom: 500px;"></div>
</div>
</div>
</body>
</html>
update 1 :
after some tinkering around i figured out what they were doing, basicaly it is to have a box centered, have it have a z index superior to the text, and then somehow hide anything outside its border but without using overflow hidden, in my case im using box shadow.
its doing what i wanted, but i somehow dont feel like this hack im doing is the right thing to do.
I'm trying to make a layout with a fixed navbar, a fixed-size content area, and a scrollable sidebar. This is a pretty standard setup (though usually the sidebar is fixed while the content scrolls, but that's just semantics), but it's important that the content's box doesn't overflow the overall container, since I'm filling it with an image that gets an object-fit applied so it can scale happily within the viewport while maintaining its aspect ratio.
I actually have a functioning version of it using grid (embedded and linked below). The problem there is that if I want the sidebar to go away, I have to change the styling on the parent divs, which is messy (but doable) in the component system I'm using. Ideally I'd be able to simply set the sidebar to display: none and the content would fill the space.
I've tried converting the whole thing to flexbox, and making the second row into a nested grid, but I can't seem to do either of those while retaining the overall height lock.
Here's the working grid (and a CodePen).
html,
body {
margin: 0;
}
.wrapper {
height: 100vh;
display: grid;
grid-template-columns: 1fr 150px;
grid-template-rows: auto 1fr;
}
nav {
height: 50px;
grid-row: 1;
grid-column: 1 / span 2;
background-color: darkseagreen;
}
.content {
background-color: salmon;
position: relative;
}
img {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
object-fit: contain;
}
.sidebar {
overflow-y: scroll;
background-color: cornflowerblue;
}
<div class="wrapper">
<nav>Navbar should stay fixed</nav>
<div class="content">
<img src="http://placehold.it/640x360">
</div>
<div class="sidebar">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro repudiandae, laboriosam dolorum mollitia fugit autem officiis explicabo minima! Maxime ea a unde alias laboriosam vel pariatur delectus. A, quas ratione?</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque temporibus sunt, nesciunt et assumenda asperiores fuga aperiam nulla voluptas reprehenderit iusto molestias blanditiis corrupti, nobis ab id dolorum obcaecati ullam!</div>
</div>
</div>
Is there a way to craft this so the second row becomes a flexbox while keeping its height from expanding, so I could collapse the sidebar without having to re-layout a whole grid? (If there's a more clever way to get the img scaling I'm attempting, I'm open to that, too.)
Simply update the template to grid-template-columns: 1fr auto; and make the width of sidebar to be equal to 150px;
html,
body {
margin: 0;
}
.wrapper {
height: 100vh;
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: auto 1fr;
}
nav {
height: 50px;
grid-row: 1;
grid-column: 1 / span 2;
background-color: darkseagreen;
}
.content {
background-color: salmon;
position: relative;
}
img {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
object-fit: contain;
}
.sidebar {
overflow-y: scroll;
background-color: cornflowerblue;
width:150px;
}
<div class="wrapper">
<nav>Navbar should stay fixed</nav>
<div class="content">
<img src="http://placehold.it/640x360">
</div>
<div class="sidebar" style="display:none;">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro repudiandae, laboriosam dolorum mollitia fugit autem officiis explicabo minima! Maxime ea a unde alias laboriosam vel pariatur delectus. A, quas ratione?</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque temporibus sunt, nesciunt et assumenda asperiores fuga aperiam nulla voluptas reprehenderit iusto molestias blanditiis corrupti, nobis ab id dolorum obcaecati ullam!</div>
</div>
</div>
This question already has answers here:
One flex/grid item sets the size limit for siblings
(6 answers)
Closed 6 years ago.
I'm trying to create a flexbox layout that does something I thought would be a little easier, but I'm having trouble finding the right way to do it.
I want to have a row of items with dynamic height that allows one child to grow as tall as need be, but limits the height of the other item so that content is cut off.
I want to use flexbox, so browser issues associated with that are not an issue, but I would like to avoid any use of JavaScript in the solution.
Any ideas? This might be a trivial problem, but I'm having trouble finding anything with the search terms I've been using. Thanks!
Here's a CodePen demo in case you'd like to modify it for use in your answer.
This is my reference flexbox layout:
.row {
display: flex;
}
.info {
flex: 0 0 200px;
}
.description {
flex: 1 1 auto;
}
<div class="row">
<div class="info">This should grow dynamically</div>
<div class="description">This should be limited in height by the .info div</div>
</div>
Flexbox can't do that natively but it is possible.
You will need an inner element inside the second child which is positioned absolutely.
Here the extra content is/can be hidden with overflow:hidden...or revealed by adding overflow:auto.
.wrapper {
display: flex;
width: 80%;
margin: 1em auto;
border: 2px solid red;
}
.child {
flex: 1;
border: 2px solid green;
}
.child:nth-child(2) {
position: relative;
overflow: auto;
/*overflow: hidden; */ /* removed for demo purposes */
}
.inner {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<div class="wrapper">
<div class="child">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis tenetur, laboriosam! Ab facilis, officia id delectus eaque expedita quia, incidunt eligendi aut, minus temporibus tenetur.</div>
<div class="child">
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae molestiae, libero inventore nobis et veritatis, laborum vitae, vel eaque omnis ad adipisci quia velit blanditiis qui. Cum voluptas quisquam itaque possimus accusamus repellendus quia iure
asperiores. Unde, rerum nihil maiores nisi, iusto voluptate id cumque incidunt, perspiciatis facilis perferendis explicabo.
</div>
</div>
</div>
This question already has answers here:
Fixed position but relative to container
(31 answers)
Closed 4 years ago.
I am relatively new to CSS. I have run into a problem where I am trying to fix an element next to its parent element. I am able to do so with the following code:
Parent element:
#search_results{
position:relative;
}
Child element:
.total {
position: fixed;
top:10px;
width:250px;
left: 75%;
/*overflow: hidden;*/
margin-left: -125px;
}
This works fine until the browser window is resized. When that occurs, the fixed element overlaps its parent element. You can see my problem here:
Twittiment
I am trying to fix the child element to the top of the page and the right-hand side of the parent element. Any ideas?
Edit:
You can use position: sticky; which can be relative to the parent element.
body > div {
height: 300px;
background-color: #ddd;
overflow: auto;
margin-top: 70px;
}
div > div {
height: 1000px;
position: relative;
}
span {
display: block;
height: 20px;
background-color: tomato;
position: sticky;
top: 0;
}
<div>
<div>
<span>This is a relatively sticky header</span>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus voluptas pariatur ullam, dolores veritatis vero possimus nisi corrupti, provident aspernatur harum ab aliquam expedita assumenda, blanditiis aliquid id consequuntur distinctio.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus voluptas pariatur ullam, dolores veritatis vero possimus nisi corrupti, provident aspernatur harum ab aliquam expedita assumenda, blanditiis aliquid id consequuntur distinctio.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus voluptas pariatur ullam, dolores veritatis vero possimus nisi corrupti, provident aspernatur harum ab aliquam expedita assumenda, blanditiis aliquid id consequuntur distinctio.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus voluptas pariatur ullam, dolores veritatis vero possimus nisi corrupti, provident aspernatur harum ab aliquam expedita assumenda, blanditiis aliquid id consequuntur distinctio.</p>
</div>
</div>
Old Answer:
As per CSS Spec, the element positioned fixed is fixed to the viewport and not the containing element.
So the short answer is NO, you cannot have a fixed position element relative to it's parent element. You can use position: absolute; instead and tweak the top left right bottom parameters on the run using jQuery/JS.
Of course you can, just need an extra div!
<div class="fixed-wrapper">
<div class="close-wrapper">
<div class="close"></div>
</div>
</div>
body
background: gray
height: 8000px
.fixed-wrapper
position: fixed
top: 20px
left: 0
right: 0
.close-wrapper
max-width: 1200px
position: relative
.close
background: #fff
width: 30px
height: 30px
position: absolute
right: 0
border: 1px solid #515151
&:before,&:after
width: 25px
height: 1px
background: #515151
content: ''
position: absolute
top: 50%
left: 50%
display: block
#include transform(translate(-50%, -50%) rotate(45deg))
&:after
transform: translate(-50%, -50%) rotate(-45deg)
See this fiddle I made for you :-)
http://codepen.io/marinagallardo/pen/mJyqaN
The best way to achieve this is to give parent element a transform css.
eg:
.relative{
transform: translateX(0); // this will act like relative parent
}
.fixed{
position: fixed;
left:0;
top:0;
width:100%; // width will be relative to the width of .relative
}
What you want to use is position:absolute . This places the child element according to it's parent element.
Some readings here : http://www.w3schools.com/cssref/pr_class_position.asp
I don't know if there is an issue, but I was wondering why the overflow:hidden does not function on fixed parent/children element.
Here's an example:
CSS and HTML:
.parent{
position:fixed;
overflow:hidden;
width:300px;
height:300px;
background:#555;
}
.children{
position:fixed;
top:200px;
left:200px;
width:150px;
height:150px;
background:#333;
}
<div class="parent">
<div class="children">
</div>
</div>
Live demo: jsFiddle
You could consider using CSS clip: rect(top, right, bottom, left); to clip a fixed positioned element to a parent. See demo at http://jsfiddle.net/lmeurs/jf3t0fmf/.
Beware, use with care!
Though the clip style is widely supported, main disadvantages are that:
The parent's position cannot be static or relative (one can use an absolutely positioned parent inside a relatively positioned container);
The rect coordinates do not support percentages, though the auto value equals 100%, ie. clip: rect(auto, auto, auto, auto);;
Possibillities with child elements are limited in at least IE11 & Chrome34, ie. we cannot set the position of child elements to relative or absolute or use CSS3 transform like scale.
See http://tympanus.net/codrops/2013/01/16/understanding-the-css-clip-property/ for more info.
EDIT: Chrome seems to handle positioning of and CSS3 transforms on child elements a lot better when applying backface-visibility, so just to be sure we added:
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
to the main child element.
Also note that it's not fully supported by older / mobile browsers or it might take some extra effort. See our implementation for the menu at bellafuchsia.com.
IE8 shows the menu well, but menu links are not clickable;
IE9 does not show the menu under the fold;
iOS Safari <5 does not show the menu well;
iOS Safari 5+ repaints the clipped content on scroll after scrolling;
FF (at least 13+), IE10+, Chrome and Chrome for Android seem to play nice.
EDIT 2014-11-02: Demo URL has been updated.
Because a fixed position element is fixed with respect to the viewport, not another element. Therefore since the viewport isn't cutting it off, the overflow becomes irrelevant.
Whereas the position and dimensions of an element with
position:absolute are relative to its containing block, the position
and dimensions of an element with position:fixed are always relative
to the initial containing block. This is normally the viewport: the
browser window or the paper’s page box.
ref: http://www.w3.org/wiki/CSS_absolute_and_fixed_positioning#Fixed_positioning
2016 update:
You can create a new stacking context, as seen on Coderwall:
<div style="transform: translate3d(0,0,0);overflow:hidden">
<img style="position:fixed; ..." />
</div>
Which refers to http://dev.w3.org/csswg/css-transforms/#transform-rendering
For elements whose layout is governed by the CSS box model, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.
As an alternative to using clip you could also use {border-radius: 0.0001px} on a parent element. It works not only with absolute/fixed positioned elements.
on parent element add clip-path: inset(0 0 0 0);
If you want to hide overflow on fixed-position elements, the simplest approach I've found is to place the element inside a container element, and apply position:fixed and overflow:hidden to that element instead of the contained element (you must remove position:fixed from the contained element for this to work). The content of the fixed container should then be clipped as expected.
In my case I was having trouble with using object-fit:cover on a fixed-position element (it was spilling outside the bounds of the page body, regardless of overflow:hidden). Placing it inside a fixed container with overflow:hidden on the container fixed the issue.
Fixed position elements are positioned relative to the browser window, so the parent element is basically irrelevant.
To get the effect you want, where the overflow on the parent clips the child, use position: absolute instead: http://jsfiddle.net/DBHUv/1/
I had a similar, quite complex problem with a fluid layout, where the right column had a fixed width and the left one had a flexible width. My fixed container should have the same width as the flexible column. Here is my solution:
HTML
<div id="wrapper">
<div id="col1">
<div id="fixed-outer">
<div id="fixed-inner">inner</div>
</div>
COL1<br />Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</div>
<div id="col2">COL2</div>
</div>
CSS
#wrapper {
padding-left: 20px;
}
#col1 {
background-color: grey;
float: left;
margin-right: -200px; /* #col2 width */
width: 100%;
}
#col2 {
background-color: #ddd;
float: left;
height: 400px;
width: 200px;
}
#fixed-outer {
background: yellow;
border-right: 2px solid red;
height: 30px;
margin-left: -420px; /* 2x #col2 width + #wrapper padding-left */
overflow: hidden;
padding-right: 200px; /* #col2 width */
position: fixed;
width: 100%;
}
#fixed-inner {
background: orange;
border-left: 2px solid blue;
border-top: 2px solid blue;
height: 30px;
margin-left: 420px; /* 2x #col2 width + #wrapper padding-left */
position: absolute;
width: 100%;
}
Live Demo: http://jsfiddle.net/hWCub/
This isn't the exact answer but a handy trick to work around the issue if your use case makes sense. The accepted answer is correct.
A simple hack is to use z-index on the parent relative container in conjunction with another hiding element below and/or above.
example
body {
margin: 0px;
padding: 0px;
}
.parent {
background-color: blue;
height: 500px;
padding: 30px;
position: relative;
text-align: center;
z-index: 1;
}
.child {
padding: 10px;
position: fixed;
top: 100px;
}
.sibling {
background: white;
min-height: 500px;
padding: 30px;
position: relative;
z-index: 2;
}
<div class="parent">
<button class="child">
Click Me
</button>
</div>
<div class="sibling">
<h1>Some Header</h1>
<p>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora
incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate
velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</p>
</div>