Is there something about CSS that doesn't allow you to specify both top and bottom or left and right values?
Take this example:
div {
width: 100px;
height: 100px;
}
.first {
background-color: blue;
position: relative;
left: 100px;
right: 50px;
}
.second {
background-color: yellow;
}
<div class="first"></div>
<div class="second"></div>
Try removing right: 50px and the position will remain the same. What's going on?
In your example, the element has a fixed width to 100px and you are specifying both left and right properties. On MDN, you can read (emphasis mine) :
When both the right CSS property and the left CSS property are
defined, the position of the element is overspecified. In that case,
the left value has precedence when the container is left-to-right
(that is that the right computed value is set to -left)[...]
So in your example the right value is ignored. For the bottom property, the same rule applies as the element's height is fixed.
Note that this rule only applies for non static positioning
You can combine left/right and top/bottom, but if width/height is also present, their value take precedence, which makes some sense, as how can it be both at a certain right/bottom position and have a certain width/height.
This sample shows how it behaves.
body {
margin: 0;
}
.first, .second {
width: 50px;
height: 50px;
}
.first {
background-color: yellow;
}
.second {
background-color: blue;
position: absolute;
left: 50px;
right: 50px;
top: 50px;
bottom: 50px;
}
.third {
background-color: green;
position: absolute;
left: 100px;
right: 100px;
top: 100px;
bottom: 50px;
}
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
From MDN:
When both the right CSS property and the left CSS property are
defined, the position of the element is overspecified. In that case,
the left value has precedence when the container is left-to-right
(that is that the right computed value is set to -left), and the right
value has precedence when the container is right-to-left (that is that
the left computed value is set to -right).
Related
This question already has answers here:
Why aren't my absolutely/fixed-positioned elements located where I expect?
(3 answers)
Closed 1 year ago.
html {
scroll-behaivor: smooth;
padding: 0;
margin: 0;
}
#skip-to-main-content {
position: absolute;
transform: translatey(0);
display: block;
background: grey;
width: 100%;
}
.box {
height: 100px;
width: 100px;
background: green;
margin-top: 200px;
}
<div id="skip-to-main-content">Skip to main content</div>
<div class="box"></div>
With the transform: translatey(0) I was expecting the div "skip-to-main-content" to be positioned at the top of the page. However, it's positioned at the top of the div "box".
If I change from translateY(0) to top: 0. Then it appears at the top of the page. How come translateY is acting differently? It's almost like translateY is not honoring the position absolute. I thought the position: absolute would have take it own of the regular flow.
Thanks.
The transform property will apply relative transformation. It is usually used for animation more than positionning, and doesn't work in pair with position property.
Remove your absolute positioning and use relative. Then you can use transform: translateY(50%) translateY(-50%); to place at the top of the page.
html {
scroll-behaivor: smooth;
padding: 0;
margin: 0;
}
#skip-to-main-content {
position: relative;
transform: translateY(50%) translateY(-50%);
display: block;
background: grey;
width: 100%;
}
.box {
height: 100px;
width: 100px;
background: green;
margin-top: 200px;
}
<div id="skip-to-main-content">Skip to main content</div>
<div class="box"></div>
(Note: typo in the code given in the question - translatey.)
transform: translateY moves the element relative to where it is positioned.
If you see translateY(-50%) that means the element will be moved upwards by half of its own height.
If you see translateY(0) [as in the question] that means the element isn't moved at all.
If you see translateY(50px) that means the element moves down by 50px from its original position.
Note that in any translation the element moves visually but it does not move within the overall content, this translation does not effect the positioning of other elements.
To get an absolutely positioned element to go to the top of the page, as is described in the question, it needs to have top: 0 set AND that will be relative to the first ancestor that has position set. So be careful that none of the parents/grandparents that you don't want it to be positioned in have position relative or absolute set. In this special case the system will go 'all the way up' as there is no intervening positioned element.
Taking the given code, and as it's an SO snippet realising that there will be a body element encompassing the content of the page, we position the element in relation to that:
html {
scroll-behaivor: smooth;
padding: 0;
margin: 0;
}
#skip-to-main-content {
position: absolute;
top: 0;
display: block;
background: grey;
width: 100%;
}
.box {
height: 100px;
width: 100px;
background: green;
margin-top: 200px;
}
<div id="skip-to-main-content">Skip to main content</div>
<div class="box"></div>
I want to set a width of ::before pseudo-element to 80%. If I use positioning then everything works, but if I don't use it then everything fails.
Could you explain me why percentage width doesn't work without positioning? If you can please add some references to the specification
.positioned {
position: relative;
height: 15px;
background-color: aquamarine;
margin-bottom: 10px;
}
.positioned::before {
position: absolute;
content: "";
background: red;
width: 80%;
height: 100%;
}
.not-positioned {
height: 15px;
background-color: aquamarine;
margin-bottom: 10px;
}
.not-positioned::before {
content: "";
background: red;
width: 80%;
height: 100%;
}
<div class="positioned"></div>
<div class="not-positioned"></div>
First, it's not about percentage values. You will have the same result even with pixel values and both width and height aren't working.
Pseudo elements are inline elements and their width/height is only defined by their content and the width/height set with CSS will be ignored.
In CSS, ::before creates a pseudo-element that is the first child of the selected element. It is often used to add cosmetic content to an element with the content property. It is inline by default. ref
width
This property does not apply to non-replaced inline elements. The content width of a non-replaced inline element's boxes is that of the rendered content within them ref
The 'height' property does not apply. The height of the content area should be based on the font ... ref
By making the pseudo element position:absolute you will now consider the rules that applies to Absolutely positioned element in order to calculate width and height. You will also notice that the element will have a computed value of block within display.
You should also pay attention to the use of positioned element which means either relative, absolute, fixed or sticky BUT making the element position:relative will keep it an inline level element and you still cannot use width/height.
.positioned {
position: relative;
height: 15px;
background-color: aquamarine;
margin-bottom: 10px;
}
.positioned::before {
position: relative;
content: "";
background: red;
width: 80%;
height: 100%;
}
.not-positioned {
height: 15px;
background-color: aquamarine;
margin-bottom: 10px;
}
.not-positioned::before {
content: "";
background: red;
width: 80%;
height: 100%;
}
<div class="positioned"></div>
<div class="not-positioned"></div>
This said, you can simplify you code by considering gradient if you want to achieve the same visual:
.positioned {
position: relative;
height: 15px;
background:
linear-gradient(red,red) left/80% 100% no-repeat,
aquamarine;
margin-bottom: 10px;
}
<div class="positioned"></div>
What is the idiomatic way to position an element (X) to the left of an other element (inline-box 2), independent of its size, using standard CSS & HTML?
It is okay if it appears over other elements.
I have found a solution: to position an element to the left of another one, no matter their sizes, make it its child, and then absolute-position it right: 100%.
100% means the width of its parent, so 100% from the right will put it just left of it!
Using left: -100% wouldn't work, because it means: offset the left of the element left of the parent by the parent's width, however we want to offset by the width of the child element, itself.
CSS-only demo:
/* The important parts */
#box2 {
position: relative;
}
#x {
position: absolute;
right: calc(100% + 5px);
top: -1px;
}
/* Just styling */
#box1, #box2 {
border: 1px solid blue;
width: 200px;
margin-right: 10px;
display: inline-block;
}
#x {
border: 1px solid orangered;
width: 100px;
height: 150px;
}
<div id="container">
<div id="box1">box1</div>
<div id="box2">box2
<div id="x">X</div>
</div>
</div>
I'm working with this JS Fiddle: http://jsfiddle.net/BY3tz/1/
Notice when you remove the position, left, and top properties from the dotParent CSS class, the black dot is centered within the box.
I'm looking for a way to keep the black dot centered (vertically and horizontally) while leaving the 3 properties mentioned above in place so that I can change the left and top properties to position the box anywhere, and the black dot will remain centered.
Is this possible? Can anyone see what I'm doing wrong with my dot class?
Some tweaks to the .dot class:
.dot {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50px;
margin-left: -5px; // Half of the width * (-1)
margin-top: -5px; // Half of the height * (-1)
top: 50%;
left: 50%;
background: #000;
-webkit-border-radius: 50px;
-webkit-background-clip: padding-box;
background-clip: padding-box;
}
http://jsfiddle.net/BY3tz/2/
Added dot wrapper so .dot is relative to new wrapper,
<div class="dotParent">
<div class="dot-wrapper">
<div class="dot"></div>
</div><!-- end dot-wrapper -->
</div>
New Styles.
.dot-wrapper {
position:relative;
width:100%;
height:100%;
}
Added to .dot class
.dot {
position:absolute;
top:45%;
left:45%;
}
http://jsfiddle.net/BY3tz/5/
Change the position attribute in the dotParent div to "Relative". Since its the parent Div, it needs to be positioned as Relative in order for its children to take it as a reference point.
.dotParent {
position: relative;
top: 150px;
left: 50px;
height: 68px;
width: 68px;
border: 1px solid Black;
}
http://jsfiddle.net/BY3tz/6/
I have 2 ids on my page as;
<div id="a">
<div id="b"></div>
</div>
With styling;
#a {
height: 25px;
width: 100px;
background-color: #9DBA6A;
}
#b {
height: 25px;
width: 25px;
background-color: #FF7E00;
}
I want to stick div b on div a's bottom with some -ve margin or padding and I want to remain its position like that when div a's height changes. The layout cannot be altered.
Here is a diagram;
You can see my fiddle here and the complete layout here.
Check out this fiddle... http://jsfiddle.net/23gCd/
I've kept your <div id="b"></div> inside your <div id="a"></div>. It will stay below #a no matter the height, but if #b's height changes, you'd have to change it in the CSS.
CSS
#a {
height: 25px;
width: 100px;
background-color: #9DBA6A;
position: relative;
}
#b {
height: 25px;
width: 25px;
background-color: #FF7E00;
position: absolute;
bottom: -25px;
}
Adding the position: relative property to #a allows us to absolutely position #b relative to where #a is. So you can offset #b -25px from the bottom; if the height of #b changes, you'd have to change that offset as well.
I have tried this in your fiddle and it worked:
#a {
height: 10px;
width: 100px;
background-color: #9DBA6A;
position : relative;
}
#b {
height: 25px;
width: 25px;
background-color: #FF7E00;
position : absolute;
bottom : -25px;
}
greetings
Mh, I don't know a solution for doing this with plain css if the height is not hardcoded. But if the height is hardcoded, just use margin-top: 25px; on b...
How would you want to change the height of a? Or would you remove the height: 25px; in your production code?
Another way is setting position:relative on parent (that's not bad!) and position:absolute on child. The positions of child will be computed according to parent so bottom:0 will stick it to bottom.
See http://jsfiddle.net/shP3D/12/