Hi i just started trying to teach myself HTML/CSS a few days ago. I really dont like asking for answers id rather figure it out myself. But now i need some help so i can find peace and FINALLY move on. Im trying to make a horizontal menu with one drop down button and links in it.
.container {border:1px solid black;
text-align:left;
border-radius:10px;
overflow:hidden;}
.container a {padding:15px;
display:inline-block;
font-size:30px;
text-decoration:none;
background-color:grey;
color:white;}
.aboutcontainer {display:inline-block;}
.about {position:absolute;
display:none;
width:100%;}
.about a {display:block;
text-align:left;
font-size:20px;
padding:15px 5px;}
.aboutcontainer:hover .about {display:block;}
.container a:hover, .aboutcontainer:hover .button {background-color:red;}
.about a:hover {background-color:lightgrey;}
<div class="container">
<a href="#">Home</a
><a href="#">Media</a
><a href="#">Store</a
><div class="aboutcontainer">
<a class="button" href="#">About</a>
<div class="about">
About2
About3
</div>
</div>
</div>
I cant figure out how to make the dropdown menu automatically the same width as the drop down button. I figured that perhaps the drop down menu (.about) which has a width:100% would stretch as far as the div its contained in (.aboutcontainer) which is displayed as inline-block whose width would be determined by the "About" text-link inside of it. But the drop down menu, when displayed, goes the full length of the screen. So it seems to be the case that actual content inside an inline:block element will not define the width of that element. And although the border of an inline:block element wraps around its content automatically, its just an illusion and its actual width is really the full length of the screen, if no fixed widths have been defined in any of the parent divs (hope im using the right terminology). So is there a way to do this without any fixed widths assigned? If not then thats ok. Ill finally have my answer and know what im trying to do is impossible and stop wasting time on it.
Yes, an inline-block element will size to fit it's content.
Why isn't it working in your situation? You have .about positioned absolute.
When you position an element absolutely, you are taking it out of the HTML structure, meaning:
Do not leave space for the element. Instead, position it at a specified position relative to its closest positioned ancestor if any, or otherwise relative to the containing block. Absolutely positioned boxes can have margins, and they do not collapse with any other margins.
MDN Docs
This means the element is pulled out of the structure, and no longer influences the surrounding elements, or its parent.
An example of this:
.parent {
background: blue;
}
.child {
background: red;
position: absolute;
top: 20px;
}
Below is the parent element, with a blue background.
<div class="parent">
<div class="child">Bye bye parent</div>
</div>
If you run the snippet above, you don't see the parent or it's blue background at all, because the child element has been positioned out of it, and relative to the viewport.
Now back to your problem. How can we make the absolute positioned element be positioned relative to its parent, instead of the viewport?
The answer is extremely simple: position:relative; on the parent:
This keyword lays out all elements as though the element were not positioned, and then adjust the element's position, without changing layout (and thus leaving a gap for the element where it would have been had it not been positioned). The effect of position:relative on table-*-group, table-row, table-column, table-cell, and table-caption elements is undefined.
Relative positioning means that the absolute child elements will be positioned relative to the parent. While absolute will still pull the element out of the HTML structure, and it still won't influence the surrounding elements or its parent, the absolute element will now be influenced by its parent. So, in your case, setting width to 100% will be 100% of .aboutcontainers width, instead of 100% of the viewports width:
.container {
border: 1px solid black;
text-align: left;
border-radius: 10px;
}
.container a {
padding: 15px;
display: inline-block;
font-size: 30px;
text-decoration: none;
background-color: grey;
color: white;
}
.container>a:first-of-type {
border-radius: 10px 0 0 10px;
}
.aboutcontainer {
display: inline-block;
position: relative;
}
.about {
position: absolute;
display: none;
width: 100%;
}
.about a {
display: block;
text-align: left;
font-size: 20px;
padding: 15px 5px;
}
.aboutcontainer:hover .about {
display: block;
}
.container a:hover,
.aboutcontainer:hover .button {
background-color: red;
}
.about a:hover {
background-color: lightgrey;
}
<div class="container">
<a href="#">Home</a
><a href="#">Media</a
><a href="#">Store</a
><div class="aboutcontainer">
<a class="button" href="#">About</a>
<div class="about">
About2
About3
</div>
</div>
</div>
You'll notice in the snippet above, we had to remove overflow:hidden from .container. That is because now that the element is positioned absolutely within its parent element, it gets hidden when it overflows from .container. You had applied overflow:hidden so the end elements wouldn't stick out over the border-radius, so I simply added a border-radius to the first element.
Here, I removed overflow: hidden from .container and added position: relative to .aboutcontainer.
.container {
border: 1px solid black;
text-align: left;
border-radius: 10px;
}
.container a {
padding: 15px;
display: inline-block;
font-size: 30px;
text-decoration: none;
background-color: grey;
color: white;
}
.aboutcontainer {
display: inline-block;
position: relative;
}
.about {
position: absolute;
display: none;
width: 100%;
}
.about a {
display: block;
text-align: left;
font-size: 20px;
padding: 15px 5px;
}
.aboutcontainer:hover .about {
display: block;
}
.container a:hover,
.aboutcontainer:hover .button {
background-color: red;
}
.about a:hover {
background-color: lightgrey;
}
<div class="container">
<a href="#">Home</a
><a href="#">Media</a
><a href="#">Store</a
><div class="aboutcontainer">
<a class="button" href="#">About</a>
<div class="about">
About2
About3
</div>
</div>
</div>
Related
I am trying to make a list of buttons in an absolute <div>. The buttons should span over the whole <div> container, without exceeding them. They do though I am wondering what I did wrong.
.container {
position: absolute;
background-color: yellow;
}
.btn {
padding: 8px;
margin: 8px;
width: 100%;
display: block;
background-color: blue;
}
<div class="container">
<button class="btn">Text</button>
<button class="btn">Text2</button>
</div>
Since you are using margin in your child element, the container will have the width of child only. But when using margin, it will overflow the element.
One way to workaround is to give a padding on left and right on the container, and a margin top and bottom on the child. Hope it makes sense.
.container {
position: absolute;
background-color: yellow;
padding: 0 8px;
}
.btn {
padding: 8px;
margin: 8px 0;
width: 100%;
display: block;
background-color: blue;
}
<div class="container">
<button class="btn">Text</button>
<button class="btn">Text2</button>
</div>
Regards
Margins that are hardcoded to a value will take precedence over relative sizing. As a result, it will push make space for the element on the DOM irrespective of the properties of its parent container.
A way to achieve what you want is to set the padding (to the same size as your required margin) on the parent container instead as I've done to achieve the border gap you're looking for rather than setting margin on the buttons themselves.
.container {
position: absolute;
background-color: yellow;
padding: 8px;
}
.btn {
padding: 8px;
width: 100%;
display: block;
background-color: blue;
}
<div class="container">
<button class="btn">Text</button>
<button class="btn">Text2</button>
</div>
So there is the following layout:
We are focusing at the 'SERVICEUSER' button and its submenu problem.
So is there a way to make the minimum width of the submenu (with position absolute) the same as its parent.
I have recreated the situation on this
jsfiddle link.
So basicly what is needed is to make the .collection min-width same as the width of the li.
The html structure of this situation is like this:
<ul>
<li>
SERVICEUSER
<div class="collection">
<div class="item">Item-1</div>
<div class="item">Item-2</div>
<div class="item">Item-3</div>
</div>
</li>
</ul>
The css of this situation is like this:
ul { list-style-type: none; }
li { display: inline; }
a { background: green; }
.collection {
position: absolute; // this is necessary for the situation
background: white;
}
An element positioned with "absolute" is contained in the flow of its closest relative parent. If you make li relative, you can set the width for collection.
li { display: inline; position: relative; }
.collection {
position: absolute;
background: white;
min-width: 100%;
white-space: nowrap;
}
Edit: I added white-space: nowrap to allow the collection (subitems) to be larger than the main item.
I'm trying to recreate a website and position the icons in a certain way. Currently I have a black nav bar on the left with icons. I want the black nav bar to extend all the way to bottom of the page and I also want the icons to be separated.
Here is the CSS code:
#left_nav {
border: solid black;
}
#left_nav i {
color: gray;
padding-right: 35%;
padding-left: 35%;
margin-top: 60%;
}
HTML code:
<div id="left_nav" class="grid_2 alpha">
<i class="ss-icon">home</i>
<i class="ss-icon">time</i>
<i class="ss-icon">user</i>
<i class="ss-icon">question</i>
<i class="ss-icon">play</i>
</div>
http://jsfiddle.net/fmpeyton/3L5YV/
A few things:
Inline elements (i.e. <i>) cannot have a margin. You'll have to make the element a block level element via display:block;
In order for the sidebar to reach the whole page, you can set its height to 100%, but only after setting the height of its parent (in this case, the BODY and concurrently HTML elements) to 100% height.
CSS:
html, body{
height: 100%; // height declared so child #left_nav can expand to this height
}
#left_nav {
border: solid black;
height: 100%; // will expand to height of parent
}
#left_nav i {
display:block; // added display:block; to allow for margin
color: gray;
padding-right: 35%;
padding-left: 35%;
margin: 10px 0; // only available to block level elements
}
I have a "container" div to which I gave margin:auto;.
It worked fine as long as I gave it a specific width, but now I changed it to inline-block and margin:auto; stopped working
Old code (works)
#container {
border: 1px solid black;
height: 200px;
width: 200px;
}
.MtopBig {
margin-top: 75px;
}
.center {
margin-left: auto;
margin-right: auto;
text-align: center;
}
<div class="center MtopBig" id="container"></div>
New code (doesn't work)
#container {
border: 1px solid black;
display: inline-block;
padding: 50px;
}
.MtopBig {
margin: 75px auto;
position: relative;
}
.center {
text-align: center;
}
<div class="center MtopBig" id="container"></div>
DEMO fiddle.
It is no longer centered because it now flows on the page in the same way inline elements do (very similarly to img elements). You will have to text-align: center the containing element to center the inline-block div.
#container {
border: 1px solid black;
display: inline-block;
padding: 50px;
}
.MtopBig {
margin: 75px auto;
position: relative;
}
.center {
text-align: center;
}
<div class="center">
<div class="MtopBig" id="container"></div>
</div>
What 'auto' means:
Using auto for the horizontal margin will instruct the element to fill up the available space (source: http://www.hongkiat.com/blog/css-margin-auto/).
Why 'display: inline-block' does not center:
There is no available horizontal space in an inline setting. Before and after it are other inline elements (characters) that take up their own space. Therefore, the element will act as if the horizontal margin is set to zero.
Why 'display: block' centers:
When used as an element with display: block set to it, the available horizontal space will be the full width of the parent element minus the width of the element itself. This makes sense because display: block is reserving this horizontal space (thus making it 'available'). Note that elements with display: block cannot be placed next to each other. The only exception occurs when you use float, but in that case you also get the (expected) zero-margin-behaviour, as this disables the horizontal 'availability'.
Solution for 'inline-block' elements:
Elements with display: inline-block should be approached as characters. Centering characters/text can be done by adding text-align: center to their parent (but you probably knew that already...).
For elements with property display: inline-block;
A computed value of 'auto' for 'margin-left' or 'margin-right' becomes a used value of '0'. [reference: CSS2ยง10.3.9]
margin-left:50%;
transform: translateX(-50%);
.container{
border:solid 1px red;
}
.container img{
display:inline-block;
margin-left:50%;
transform: translateX(-50%);
}
<div class="container">
<img src="https://placekitten.com/100/300" />
</div>
I have a div in a list item which is floated right. The div positions it self at the top right corner of the list item. Is it possible to position it in the middle-right without the use of padding or margins?
---------------
DIV
---------------
Needs to be:
---------------
DIV
---------------
I made a bunch of assumptions and didn't bother check this first.
li {
height: 32px;
}
li div {
width: 100%;
line-height: 32px;
text-align: center;
}
You could use the table cell method.
<div class="wrap one">
<div class="inner-wrap">
<div class="inner">Test</div>
</div>
</div>
With the CSS defining a parent as a table, then table-cell with vertical align:
.wrap .inner {
background: white;
float: right;
}
.wrap.one {
display: table;
width: 100%;
}
.wrap.one .inner-wrap {
display: table-cell;
vertical-align: middle;
}
Demo: http://jsfiddle.net/vFqSC/
If you want the div to take up the full space you could position the div this way:
li div {
float: right;
height: 100%;
}
or if you don't want it to take up the full space
li div {
position: absolute;
right: 0px;
top: 50%;
height:80%;
margin-top:-40%; // Half of height
}
If you have a hard coded list height and div height:
li { height: 50px; }
li div {
position: absolute;
right: 0px;
height:30px;
top: 10px;
}
There are many ways to do this, you should provide more information on how you want it to behave and look
Yes, you can, but margin or padding is the preferred method, but you could use relative positioning and assess a amount along on vertical axis. fiddle: http://jsfiddle.net/De4CV/1/
div {
width:200px;
height:200px;
background:#333;
}
div p {
font:1em normal Futura, sans-serif;
color:#f5f5f5;
text-align:right;
position:relative;
top:90px;
}
<div class="div">
<p>Hello there!</p>
</div>