CSS - How to place absolute div correctly - html

I have the following code:
.menu{
border: solid red;
border-width: 1px 1px 0px 1px;
background-color:black;
color:white;
width: 60px;
}
.dropdown{
position:absolute;
background-color: grey;
width:100px;
}
.dropdown ul{
list-style:none;
padding:10px;
margin: 0;
}
.zoom{
zoom:300%;
}
<div class="menu zoom">
Click me
<div class="dropdown">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
How can I place my dropdown menu to the same x position as the parent, without removing the border? I already tried 'box-sizing: border-box', but somehow it doesn't work.

Set position: relative on parent element and on child set position left to same negative value as left border width of parent element.
.menu {
border: solid red;
border-width: 1px 1px 0px 1px;
background-color: black;
color: white;
width: 60px;
position: relative;
}
.dropdown {
position: absolute;
background-color: grey;
width: 100px;
left: -1px;
}
.dropdown ul {
list-style: none;
padding: 10px;
margin: 0;
}
.zoom {
zoom: 300%;
}
<div class="menu zoom">
Click me
<div class="dropdown">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>

Keeping the parent as positon:relative and giving the child position:absolte with top:100%; and left:-1px ( where -1 is taken because the width of border is 1 from left)
Here is the working snippet:
.menu {
border: solid red;
border-width: 1px 1px 0px 1px;
background-color: black;
color: white;
width: 60px;
position: relative;
}
.dropdown {
position: absolute;
background-color: grey;
width: 100px;
left: -1px;
top:100%
}
.dropdown ul {
list-style: none;
padding: 10px;
margin: 0;
}
.zoom {
zoom: 300%;
}
<div class="menu zoom">
Click me
<div class="dropdown">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>

Related

Possible to have one border overlap/cancel out another border?

I have two lists sitting side-by-side. In the full code there will be the ability to select one of the list items from the MainList which will show the relevant list items from the SubList. What I would like is for the border-right of the MainList to overlap the border-left of the SubList to make it look like the SubList items are being shown as a result of the selection in the MainList.
ul {
list-style: none;
}
.BigContainer {
border: 2px solid #d50f67;
border-radius: 5px;
margin: 10px 0;
padding: 5px;
overflow: auto;
}
.MainListContainer {
width: 50%;
float: left;
}
.MainListItem {
border-bottom: 1px solid #ddd;
border-right: 1px solid white;
padding: 5px;
z-index: 2;
}
.MainListItem:last-of-type {
border: none;
}
.SubListContainer {
width: 45%;
float: left;
border: 1px solid #ddd;
border-radius: 5px;
}
.SubListItem {
padding: 5px;
z-index: 1;
}
<div class="BigContainer">
<div class="MainListContainer">
<ul class="MainList">
<li class="MainListItem">List Option A</li>
<li class="MainListItem">List Option B</li>
<li class="MainListItem">List Option C</li>
</ul>
</div>
<div class="SubListContainer">
<ul class="SubList">
<li class="SubListItem">Sub-Option 1</li>
<li class="SubListItem">Sub-Option 2</li>
<li class="SubListItem">Sub-Option 3</li>
<li class="SubListItem">Sub-Option 4</li>
<li class="SubListItem">Sub-Option 5</li>
</ul>
</div>
</div>
So, the border-right of the MainList would be white/transparent to basically erase a portion of the SubList border. I appreciate that, at the moment, making this happen would remove more of the SubList border than desired, but I will code the selection process properly to ensure only the selected item has the relevant border styling applied.
Add selected class to the selected item, then add
.selected:after{
content:"";
position: absolute;
right:-2px;
top:0;
width: 1px;
height: 100%;
background-color: white;
}
This will be placed right where you want it to. Note that MainListItem needs to have a position: relative; for the position to work.
.selected:after{
content:"";
position: absolute;
right:-2px;
top:0;
width: 1px;
height: 100%;
background-color: white;
}
ul {
list-style: none;
}
.BigContainer {
border: 2px solid #d50f67;
border-radius: 5px;
margin: 10px 0;
padding: 5px;
overflow: auto;
}
.MainListContainer {
width: 50%;
float: left;
}
.MainListItem {
border-bottom: 1px solid #ddd;
border-right: 1px solid white;
padding: 5px;
z-index: 2;
position: relative;
}
.MainListItem:last-of-type {
border: none;
}
.SubListContainer {
width: 45%;
float: left;
border: 1px solid #ddd;
border-radius: 5px;
}
.SubListItem {
padding: 5px;
z-index: 1;
}
<div class="BigContainer">
<div class="MainListContainer">
<ul class="MainList">
<li class="MainListItem">List Option A</li>
<li class="MainListItem selected">List Option B</li>
<li class="MainListItem">List Option C</li>
</ul>
</div>
<div class="SubListContainer">
<ul class="SubList">
<li class="SubListItem">Sub-Option 1</li>
<li class="SubListItem">Sub-Option 2</li>
<li class="SubListItem">Sub-Option 3</li>
<li class="SubListItem">Sub-Option 4</li>
<li class="SubListItem">Sub-Option 5</li>
</ul>
</div>
</div>

Why do my list items overlap?

I want my list items to be displayed next to each other but for some reason they always overlap. Can someone tell me how to fix this?
#background {
height: 1000px;
background-image: url("https://static.pexels.com/photos/33045/lion-wild-africa-african.jpg");
background-position: center center;
background-size: cover;
}
#menu {
background-color: white;
border: 2px solid grey;
}
ul {
list-style: none;
background-color: white;
}
li {
display: inline-block;
padding: 5px 10px 5px 10px;
border: 2px solid grey;
overflow: none;
position: fixed;
background-color: white;
}
<div id="background">
<div id="menu">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
Thank you in advance!
You need to remove position: fixed in 'li' element, because if you giving every 'li' element position fixed that will make your item always overlap.
May be you can try update your 'ul' and 'li' element style like this code bellow:
ul {
list-style: none;
position: fixed;
}
li {
display: inline-block;
padding: 5px 10px 5px 10px;
border: 2px solid grey;
overflow: none;
background-color: white;
}
That's because you have define position: fixed for li tags.
#background {
height: 1000px;
background-image: url("https://static.pexels.com/photos/33045/lion-wild-africa-african.jpg");
background-position: center center;
background-size: cover;
}
#menu {
background-color: white;
border: 2px solid grey;
}
ul {
list-style: none;
background-color: white;
}
li {
display: inline;
padding: 5px 10px 5px 10px;
border: 2px solid grey;
overflow: none;
//position: fixed;
background-color: white;
}
<div id="background">
<div id="menu">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
Take out the position: fixed. This fixes an element within the browser viewport and removes it from the flow. Not what you want.
https://developer.mozilla.org/en-US/docs/Web/CSS/position
fixed
The element is removed from the normal document flow; no space is created for the element in the page layout. Instead, it is positioned relative to the screen's viewport and doesn't move when scrolled. Its final position is determined by the values of top, right, bottom, and left.
give position fixed to ul and you will get list item properly
#background {
height: 1000px;
background-image: url("https://static.pexels.com/photos/33045/lion-wild-africa-african.jpg");
background-position: center center;
background-size: cover;
}
#menu {
background-color: white;
border: 2px solid grey;
}
ul {
list-style: none;
background-color: white;
position: fixed;
padding:5px;
}
li {
display: inline-block;
padding: 5px 10px 5px 10px;
border: 2px solid grey;
overflow: none;
background-color: white;
}
<div id="background">
<div id="menu">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>

CSS position relative forcing the height of element

I have two (almost) clone elements (#container and #container-shadow). The same css rules are supposed to be applied equally to them. However, the second .box3 div element is four times the height it should be. Why is that?
codepen -> http://codepen.io/thiagoh/pen/aJwbOZ
CSS code
#container {
position: relative;
top: -90px;
left: 400px;
float: left;
}
#container-shadow div,
#container div {
width: 280px;
box-sizing: border-box;
position: relative;
}
.box3 {
background-color: lightgray;
line-height: 24px;
padding: 4px;
border: 1px solid black;
}
.box4 {
background-color: darkgray;
border: 1px solid black;
border-top: 0px;
padding: 0;
left: 10px;
}
.box4 ul {
padding: 0;
margin: 0;
}
.box4 li {
list-style: none;
line-height: 24px;
padding: 4px;
border-bottom: 1px solid lightgray;
}
HTML code
<div style="height: 100px;"></div>
<div id="container">
<div class="box3">
</div>
<div class="box4">
<ul>
<li>line 1</li>
<li>line 2</li>
<li>line 3</li>
<li>line 4</li>
</ul>
</div>
</div>
<div id="container-shadow">
<div class="box3">
why this element is this height?
</div>
<div class="box4">
<ul>
<li>line 1</li>
<li>line 2</li>
<li>line 3</li>
<li>line 4</li>
</ul>
</div>
</div>
current result
expected result
PS: Note the position of the boxes. That's the required position in my situation. clear:both on #container-shadow does not fix my problem.
You should not use the float:left on the #container, it should look like this:
#container {
position: relative;
top: -90px;
left: 400px;
}
here is an updated codepen:Codepen
This is because you have a float: left on your #container which is not cleared - add this after the #container:
<div style="clear:both"></div>
to clear the float - see demo below:
#container {
position: relative;
top: -90px;
left: 400px;
float: left;
}
#container-shadow div,
#container div {
width: 280px;
box-sizing: border-box;
position: relative;
}
.box3 {
background-color: lightgray;
line-height: 24px;
padding: 4px;
border: 1px solid black;
}
.box4 {
background-color: darkgray;
border: 1px solid black;
border-top: 0px;
padding: 0;
left: 10px;
}
.box4 ul {
padding: 0;
margin: 0;
}
.box4 li {
list-style: none;
line-height: 24px;
padding: 4px;
border-bottom: 1px solid lightgray;
}
<div style="height: 100px;"></div>
<div id="container">
<div class="box3">
</div>
<div class="box4">
<ul>
<li>line 1</li>
<li>line 2</li>
<li>line 3</li>
<li>line 4</li>
</ul>
</div>
</div>
<div style="clear:both"></div><!-- ADDED THIS -->
<div id="container-shadow">
<div class="box3">
why this element is this height?
</div>
<div class="box4">
<ul>
<li>line 1</li>
<li>line 2</li>
<li>line 3</li>
<li>line 4</li>
</ul>
</div>
</div>
EDIT:
If you don't want the #container-shadow to drop down, you can relatively position it and float it to left using something like this:
#container-shadow {
float: left;
left: -275px;
position: relative;
}
See demo below:
#container {
position: relative;
top: -90px;
left: 400px;
float: left;
}
#container-shadow div,
#container div {
width: 280px;
box-sizing: border-box;
position: relative;
}
.box3 {
background-color: lightgray;
line-height: 24px;
padding: 4px;
border: 1px solid black;
}
.box4 {
background-color: darkgray;
border: 1px solid black;
border-top: 0px;
padding: 0;
left: 10px;
}
.box4 ul {
padding: 0;
margin: 0;
}
.box4 li {
list-style: none;
line-height: 24px;
padding: 4px;
border-bottom: 1px solid lightgray;
}
#container-shadow {
float: left;
left: -275px;
position: relative;
}
<div style="height: 100px;"></div>
<div id="container">
<div class="box3">
</div>
<div class="box4">
<ul>
<li>line 1</li>
<li>line 2</li>
<li>line 3</li>
<li>line 4</li>
</ul>
</div>
</div>
<div id="container-shadow">
<div class="box3">
why this element is this height?
</div>
<div class="box4">
<ul>
<li>line 1</li>
<li>line 2</li>
<li>line 3</li>
<li>line 4</li>
</ul>
</div>
</div>
I would suggest removing float and use inline-block for #container and #container-shadow (note that I have swapped their position in the markup) and then apply positioning to the #container to get the desired result:
#container {
position: relative;
top: -90px;
left: 50px;
display: inline-block;
}
#container-shadow {
display: inline-block;
}
#container-shadow div,
#container div {
width: 280px;
box-sizing: border-box;
position: relative;
}
.box3 {
background-color: lightgray;
line-height: 24px;
padding: 4px;
border: 1px solid black;
}
.box4 {
background-color: darkgray;
border: 1px solid black;
border-top: 0px;
padding: 0;
left: 10px;
}
.box4 ul {
padding: 0;
margin: 0;
}
.box4 li {
list-style: none;
line-height: 24px;
padding: 4px;
border-bottom: 1px solid lightgray;
}
<div style="height: 100px;"></div>
<div id="container-shadow">
<div class="box3">
why this element is this height?
</div>
<div class="box4">
<ul>
<li>line 1</li>
<li>line 2</li>
<li>line 3</li>
<li>line 4</li>
</ul>
</div>
</div>
<div id="container">
<div class="box3">
</div>
<div class="box4">
<ul>
<li>line 1</li>
<li>line 2</li>
<li>line 3</li>
<li>line 4</li>
</ul>
</div>
</div>
The solution is simple.
Remove this:
float: left;
An element with position: relative; is positioned relative to its normal position.
Setting the top, right, bottom, and left properties of a relatively-positioned element will cause it to be adjusted away from its normal position. Other content will not be adjusted to fit into any gap left by the element.
The float: left attempts to force container-shadow to occupy this space causing distortion.
It's your same code just comment the float:
#container {
position: relative;
top: -90px;
left: 400px;
/* float: left;*/
}
#container-shadow div,
#container div {
width: 280px;
box-sizing: border-box;
position: relative;
}
.box3 {
background-color: lightgray;
line-height: 24px;
padding: 4px;
border: 1px solid black;
}
.box4 {
background-color: darkgray;
border: 1px solid black;
border-top: 0px;
padding: 0;
left: 10px;
}
.box4 ul {
padding: 0;
margin: 0;
}
.box4 li {
list-style: none;
line-height: 24px;
padding: 4px;
border-bottom: 1px solid lightgray;
}

Scrolling UL with fixed header

I have a ul with a title in a div and I'm trying to make the ul scroll while keeping the title fixed. I also want to have the title match the width of the ul. I'm able to do one of those at a time, but not both together. Either I get a ul with a title that is 100% of the ul width, or I get a title that stays put when the list scrolls, but it doesn't match the ul width. Can someone point out what I'm doing wrong?
fiddle here: http://jsfiddle.net/9zcRy/2/
The HTML
<div class="talkingPointsHolder">
<div class="genericScriptsHolder">
<span class="listHeader">List One</span>
<ul
class="scrollingList">
<li>item 1.1</li>
<li>item 1.2</li>
<li>item 1.3</li>
<li>item 1.4</li>
<li>item 1.5</li>
<li>item 1.6</li>
<li>item 1.7</li>
<li>item 1.8</li>
<li>item 1.9</li>
<li>item 1.10</li>
<li>item 1.11</li>
<li>item 1.12</li>
</ul>
</div>
<div class="genericScriptsHolder">
<span class="listHeader">List Two</span>
<ul
class="scrollingList">
<li>item 2.1</li>
<li>item 2.2</li>
<li>item 2.3</li>
<li>item 2.4</li>
<li>item 2.5</li>
<li>item 2.6</li>
<li>item 2.7</li>
<li>item 2.8</li>
<li>item 2.9</li>
<li>item 2.10</li>
<li>item 2.11</li>
<li>item 2.12</li>
</ul>
</div>
The CSS
.talkingPointsHolder {
border: 1px solid black;
background: #eeeeee;
height: 200px;
overflow: auto;
}
.genericScriptsHolder {
float: left;
width: 48%;
margin: 0px 2px 0px 2px;
/* uncomment to make the title match the ul width (see listHeader too)*/
/*position: relative;*/
}
.listHeader {
color: #ffffff;
background: #444444;
padding: 10px 0px 10px 0px;
text-transform: uppercase;
font-weight:bold;
font-size:11px;
text-align: left;
text-indent: 1em;
position: absolute;
z-index:10;
/* uncomment to make the title match the ul width (see genericScriptsHolder too)*/
/*width: 100%;*/
}
.scrollingList {
position: relative;
top: 31px;
}
.scrollingList li {
overflow: auto;
height: 20px;
color: #666666;
background-color: #cccccc;
font-weight: lighter;
padding: 10px;
margin: 2px;
list-style-type: none;
}
You need to define the width of an element if you're using position: absolute;
I set the width your .list-header to match the width of your .genericScriptsHolder and then adjusted the padding accordingly.
Here's the fiddle: http://jsfiddle.net/9zcRy/15/
Notice that I removed the horizontal margins that you created for the scrolling list line items and instead edited the styling on the parent .genericScriptsHolder element.
.genericScriptsHolder {
float: left;
width: 48%;
margin: 0px 5px 0px 5px;
/* uncomment to make the title match the ul width (see listHeader too)*/
/*position: relative;*/
}
.listHeader {
color: #ffffff;
background: #444444;
padding: 10px 0px 10px 0px;
text-transform: uppercase;
font-weight:bold;
font-size:11px;
text-align: left;
text-indent: 1em;
position: absolute;
width: 48%;
z-index:10;
.scrollingList li {
overflow: auto;
height: 20px;
color: #666666;
background-color: #cccccc;
font-weight: lighter;
padding: 10px;
margin: 2px 0 0 0;
list-style-type: none;
}
http://jsfiddle.net/9zcRy/9/
.listHeader {
color: #ffffff;
background: #444444;
padding: 10px 0px 10px 0px;
text-transform: uppercase;
font-weight:bold;
font-size:11px;
text-align: left;
text-indent: 1em;
position: absolute;
z-index:10;
width:46%;

New list items shadowing previous items due to negative margin

I'm working on a step indicator which I implemented as a list:
<ol>
<li>Step 1</li>
<li class="active">Step 2</li>
<li>Step 3</li>
</ol>
Each list element has a rounded edge to it's right in order to indicate progress, so I have the following CSS:
li{
display: block; background-color: white; width: 33%; border: 1px solid #ddd; text-indent: 40px;
float: left;
margin: 0 0 0 -20px;
border-radius: 0 15px 15px 0;
}
My problem is that later elements are shadowing the earlier, thus the rounded edge are hidden. I've tried to set a decreasing z-index for each element, but it doesn't work (besides I couldn't use this solution anyway). I acheive the desired presentation by changing to float:right but that renders the list items in descending order...
Check this jsfiddle for details: http://jsfiddle.net/fMRbr/
You can use the :before
li{
display: inline-block;
width: 33%;
margin: 0 0 0 -20px;
border: 1px solid #ddd;
border-radius: 0 15px 15px 0;
background-color: white;
text-indent: 40px;
position: relative;
}
li.active{
background-color: red;
}
li:before{
content: '';
width: 15px;
height: 19px;
display: inline-block;
background: #fff;
border: 1px solid #ddd;
border-width: 0 1px 1px 0;
border-radius: 0 15px 15px 0;
position: absolute;
top: 0;
left: -3px;
}
li.afteractive:before {
content: '';
width: 15px;
height: 19px;
display: inline-block;
background: #f00;
border: 0;
border-radius: 0 15px 15px 0;
position: absolute;
top: 0;
left: -3px;
}
<ol>
<li class="active">Step 1</li>
<li class="afteractive">Step 2</li>
<li>Step 3</li>
</ol>
<br /><br />
<ol>
<li>Step 1</li>
<li class="active">Step 2</li>
<li class="afteractive">Step 3</li>
</ol>
<br /><br />
<ol>
<li>Step 1</li>
<li>Step 2</li>
<li class="active">Step 3</li>
</ol>
Instead of using border-radius and negative margin values, have you considered a Tbackground image at the top right of each <li> which looks like this:
The active (red) <li> would have a similar background but colored red. The result should look something like this:
Add a span tag to your li's with display: inline-block so they automatically grow to the right width:
html
<ol>
<li><span>Step 1</span></li>
<li class="active"><span>Step 2</span></li>
<li><span>Step 3</span></li>
</ol>
css
li {
display: block;
float: left;
width: 33%;
margin: 0 0 0 -20px;
background-color: white;
text-indent: 40px;
}
li.active {
}
li.active span {
background-color: red;
}
li span {
display: inline-block;
border: 1px solid #ddd;
border-radius: 0 15px 15px 0;
padding-right: 10px;
}
See a jsfiddle of this solution here:
http://jsfiddle.net/c4urself/HYQSJ/