Button with absolute position doesn't stretch to full width - html

Button element doesn't stretch to full parent width with left/right zero technique. It perfectly works for a tag but not for button. What am I missing?
The question is why left/right approach isn't working for button.
I know that I can use wrapper, calc() or flexbox. But it seems strange that old way doesn't work.
Fiddle
#container {
position: relative;
width: 400px;
height: 60px;
padding: 0 20px;
background: #ccc;
}
.button {
position: absolute;
left: 20px;
right: 20px;
height: 20px;
background: green;
color: white;
border: 1px solid #000;
}
a.button {
top: 0;
}
button.button {
top: 20px;
display: block;
}
button.button-full {
width: 100%;
top: 40px;
}
<div id="container">
<a class="button">Link button</a>
<button class="button">Button button</button>
<button class="button button-full">Button button</button>
</div>

You can set width:inherit on the button, but be aware that it won't work when box-sizing:border-box is set on the container, otherwise you will probably need width:calc(100% - paddings), also mentioned in the other answer.
button {
width: inherit;
}

you can add button width to 100% so that it will be 100% of its parent container.
.button {
position: absolute;
left: 0;
right: 0;
**width: 100%;**
background: green;
color: white;
border: 1px solid #000;
}

Add width: calc(); to the .button as in
a.button {
top: 0;
width: calc();
}
This will stretch it to 100% and retain your padding of the parent element.

Your button is overflowing the parent since your button is absolute and has left of 20px.
There is no need to compensate for the parent padding.
Change left left: 0px; or remove position: absolute;.
.button{
position: absolute;
left: 0px;
...
}
I would rather be removing position: absolute;

Related

How to make overflow-y: scroll account for border size

I would like to make ul's overflow account for the borders of div it is contained in.
I have tried adding padding with the same px measurement as border tag.
.resizable {
background: black;
width: 80%;
height: 50%;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
}
.resizable .resizers {
width: 100%;
height: 100%;
border: 3px solid #4286f4;
box-sizing: border-box;
}
.resizable .resizers .resizer {
width: 10px;
height: 10px;
border-radius: 50%; /* Magic to turn square into circle. */
background: white;
border: 3px solid #4286f4;
position: absolute;
}
.resizable .resizers .resizer.top-left {
left: -5px;
top: -5px;
cursor: nwse-resize;
}
.resizable .resizers .resizer.top-right {
right: -5px;
top: -5px;
cursor: nesw-resize;
}
.resizable .resizers .resizer.bottom-left {
left: -5px;
bottom: -5px;
cursor: nesw-resize;
}
.resizable .resizers .resizer.bottom-right {
right: -5px;
bottom: -5px;
cursor: nwse-resize;
}
#npc_events {
width: 100%;
height: 100%;
flex-grow: 1;
list-style: none;
margin: 0;
padding: 0;
border-bottom: 1px solid lightgrey;
overflow-y: scroll;
}
#npc_events li {
padding: 10px 10px 10px 10px;
color: white;
}
<body>
<div id='div_npc_chat' class='resizable'>
<div class='resizers'>
<div class='resizer top-left'></div>
<div class='resizer top-right'></div>
<div class='resizer bottom-left'></div>
<div class='resizer bottom-right'></div>
<div class="chat-wrapper">
<form id="npc_chat-form">
<input id="npc_chat" autocomplete="off" title="chat"/>
<button id="npc_say">Say</button>
</form>
</div>
<ul id="npc_events"></ul>
</div>
</div>
</body>
I expected the text, which is <li> elements of <ul> contained in <div> to not appear above div's blue borders, but I got this:
https://cdn.discordapp.com/attachments/401030271417188355/613446713629343756/unknown.png
The reason that your list is overflowing (or going out of the div/appearing on top of the line) is due to the fact that you have the tag #npc_events set to 100% height and this is not accounting for the input bar (chat-wrapper div).
One solution would be to add a padding to .resizers class and calculating the height of the class .chat-wrapper div, from there you can add the following to the #npc_events div.
height: calc(100% - (height of chat-wrapper));
Otherwise, I'd recommend setting the height of the chat-wrapper to a certain percentage of the wrapper div (.resizers) and the remaining to the list. For example:
.resizers {padding: 10px;}
.chat-wrapper {height: 20%;}
#npc_events {height: 80%;}
This would get you the desired result.

Stretch fixed to bottom parent div to div child's width

So, I have a main container that shows like the following:
I want to be able to adapt the parent div to the number of child's it receives. Let's say we remove div2. The result should be something like this:
Instead, the parent div does not stretch to the width of the div child's
Here's my code:
HTML:
<div class="main-container">
<!-- Card container -->
<div class="card-container">
<div class="card">div1</div>
<div class="card">div2</div>
<div class="card">div3</div>
</div>
<!-- Footer container -->
<div class="footer">i am a footer</div>
</div>
CSS:
.main-container {
position: fixed;
margin: 0 auto;
left: 0;
right: 0;
bottom: 0;
width: 100%;
max-width: 400px;
box-shadow: 0 0 15px #B3B3B3;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
text-align:center;
}
.card-container {
color: #3B3D3D;
height:105px;
float: left;
width: 100%;
}
.footer {
color: #FFFFFF;
background: #0095D3;
height: 45px;
float: left;
width: 100%;
}
.card {
width:100px;
float:left;
}
What am I doing wrong here? I've tried the display: inline-block; solutions out there but since the parent div must be fixed to the bottom, I am not seeing the desired result.
Any help will be precious.
Thanks in advance.
Try this https://jsfiddle.net/2Lzo9vfc/136/
You can try to remove one .card on click and see what hapens here https://jsfiddle.net/2Lzo9vfc/138/
CSS
.main-container {
position: fixed;
margin: 0 auto;
left: 50%;
bottom: 0;
box-shadow: 0 0 15px #B3B3B3;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
text-align:center;
display: inline-block;
transform: translateX(-50%);
}
.footer {
color: #FFFFFF;
background: #0095D3;
height: 45px;
width: 100%;
}
.card {
width:100px;
height:105px;
display: inline-block;
}
HTML
<div class="main-container">
<div class="card">div1</div>
<div class="card">div2</div>
<div class="card">div3</div>
<div class="footer">i am a footer</div>
</div>
Here you go: http://codepen.io/n3ptun3/pen/PPgWNb
You don't need to use display: inline-block.
I've left your HTML alone, and simplified some of your CSS: .card-container and .footer don't need float: left; and width: 100%;. They are both block-level elements so they will take up 100% of the width, and they don't need anything to wrap around them.
On the .main-container, you can't set margin: 0 auto; and position: fixed;. position: fixed; removes the ability for centering via margin. left: 0; and right: 0; were stretching the size of the main container, so those need to be removed. width: 100%; and max-width: 400px; were trying to fix the width issue, but that wouldn't allow resizing based on content.
Instead you need to set left: 50%; (places left edge of element at 50% of the parent's width, i.e. the viewport width, in this case) and then transform: translate(-50%); to bring the element back toward the left by 50% of its width. Thus bringing the element to the center of the window/viewport.
Now, if you remove one of the "cards," it will resize the "main-container," while keeping everything fixed to the bottom and centered.
.main-container {
position: fixed;
bottom: 0;
left: 50%;
transform: translate(-50%);
box-shadow: 0 0 15px #B3B3B3;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
text-align: center;
}
.card-container {
color: #3B3D3D;
height: 105px;
}
.card {
width: 100px;
float: left;
}
.footer {
color: #FFFFFF;
background: #0095D3;
height: 45px;
}
EDIT: Based on your new information (re: the increased width or added "cards"), I've found that the issue lies with the left position on the .main-container. When you position the element by 50% and its width is more than 50% of the parent, it runs into the right side of the parent div, and you get the stacking. To fix this, you can instead remove the float: left; on .card and add display: flex; on .card-container. This will allow you to increase the width of the "cards" while keeping them from stacking.
I've updated the code here: http://codepen.io/n3ptun3/pen/PPgWNb
.main-container {
position: fixed;
bottom: 0;
left: 50%;
transform: translate(-50%);
box-shadow: 0 0 15px #B3B3B3;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
text-align: center;
}
.card-container {
color: #3B3D3D;
height: 105px;
display: flex;
}
.card {
width: 100px;
// float: left;
}
.footer {
color: #FFFFFF;
background: #0095D3;
height: 45px;
}

How to create vertically centered meeting borders on a div?

Here is what I have so far: http://jsfiddle.net/F8AN4/
I want a border on each side of the div that is vertically centered and is pointing to the left/right sides of the screen. I've seen this done a lot, but can't for the life of me figure out how to do it!
It would look like:
-----|DIV|------
CSS
div {
background: lightgreen;
height: 100px;
margin: 0 auto;
position: relative;
width: 200px;
}
div::after {
border-right: 10px solid black; // not sure how to do this.
content: "";
top: 0; left: 0; right: 0; bottom: 0;
position: absolute;
}
div::before {
content: "";
top: 0; left: 0; right: 0; bottom: 0;
position: absolute;
}
Any ideas?
You will need two wrapping containers: an inner div that holds the content, and an outer div:
<div class="outer">
<div class="inner"></div>
</div>
The CSS is simple — the outer div will need to have 100% width (so that the pseudo-element can stretch to the full width), while the inner div can have a width that you designate later.
.inner {
background: lightgreen;
height: 100px;
margin: 0 auto;
width: 200px;
}
.outer {
position: relative;
width: 100%;
}
.outer:before {
border: 1px solid #000;
box-sizing: border-box;
content:"";
position: absolute;
top: 50%;
left: 0;
width: 100%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
The CSS transform property is used to ensure that the pseudo-element is perfectly vertically centered — it matters when the horizontal line you want is thick.
If you want odd-numbered dimensions for the horizontal line, you can choose to specify the height of a single border, i.e. border-top: 1px solid #000;, or abandon the border property and set the height and background-color. It works either way :)
http://jsfiddle.net/teddyrised/F8AN4/9/
[Edit]: Remove the bottom margin on outer div, it was not necessary for the code to work ;)
FIDDLE
HTML
<div><span>TEXT</span></div>
CSS
div {
margin-top:10px;
height: 1px;
border-top: 1px solid black;
text-align: center;
position: relative;
}
span {
position: relative;
top: -.7em;
background: lightgreen;
display: inline-block;
border-width:0 2px;
border-color:black;
border-style:solid;
}
Is this what you're looking for?
http://jsfiddle.net/F8AN4/3/
I guess there is a more beautiful way to do it maybe someone has a better idea :)
<div id="main">
<div class="hrleft"></div>
<div class="mid"></div>
</div>
div.hrleft {
height: 45px;
width: 200px;
border-bottom: 10px solid black;
float: left;
}

How to place an image on the bottom right corner of an image that doesn't have a set size

Here is my html
<div class="container">
<img src="something" class="avatar"/>
<div class="edit_photo">Edit</div>
</div>
"edit_photo" has an image on it's background. the img tag dimensions is not set so it could be anything. But I want the "edit_photo" div to always be on the bottom right corner of the img. Is this possible with css? I can't think of a way to do this. the img tag needs to always be an img tag and I can't change it to a div.
Thank you!
I think this may be possible:
CSS:
.container{
position: relative;
display: inline-block;
}
img{
background: red;
height: 120px;
width: 250px;
}
.edit_photo{
position: absolute;
bottom: 0;
right: 0;
background: blue;
height: 25px;
width: 25px;
}
Here's a JSFiddle to see: http://jsfiddle.net/gW9PK/
You might need to play around with the .edit_photo and nudge it up a little bit.
The container should be position: relative; and the edit_photo position: absolute; like this:
.container {
position: relative;
/* inline-block for 100% of child width */
display: inline-block;
border: 3px solid #ddd;
}
img {
/* for 100% height of the container */
display: block;
}
.edit_photo {
position: absolute;
right: 5px;
bottom: 10px;
/* Some color */
background: red;
padding: 2px 4px;
border-radius: 3px;
color: white;
}
UPDATED DEMO WITH MULTIPLE IMAGES: http://jsfiddle.net/HYQLQ/3/
write this code in css
.container{
position: absolute;
}
.edit_photo{
position: absolute;
bottom:0px;
right:0px;
widht:20px;
height:20px;
}
edit_photo
{
bottom:-600
top:30px;
right:5px;
}
play with the numbers.

How to place div at the bottom of another div?

How do I place the adInfoBox1 at the bottom of the container?
Take a look at this: http://jsfiddle.net/snowman/hxXJh/
Please note that the container will not have a fixed height.
You can use position: absolute.
.container
{
height: 400px;
position: relative;
}
.adInfoBox1 {
padding: 5px 5px 5px 10px;
position: absolute;
bottom: 0px;
width: 457px;
background-color: green;
}
.adRegularList .categoryList {
bottom: 0;
height: 16px;
position: absolute;
}
See a working example here: http://jsfiddle.net/hxXJh/5/
I'd suggest:
.adInfoBox1 {
padding: 5px 5px 5px 10px;
position: absolute;
bottom: 0; /* attaches the element to the bottom */
left: 0; /* attaches the element to the left-side */
right: 0; /* attaches the element to the right-side */
background-color : green;
}
The above will give the .adInfoBox 100% width, implicitly. This can be adjusted by removing, or amending, the right or left declarations. I removed the float because using position: absolute; will take the element out of the document flow anyway.
JS Fiddle demo.
Simple tricky solution. Div2 will be at the bottom of containerDiv.
<div id="containerDiv">
<div id="div1" style="heigth:90%;"></div>
<div id="div2">Content here...</div>
</div>
change the css of adInfoBox1 to:
.adInfoBox1 {
float: left;
padding: 5px 5px 5px 10px;
position: absolute;
width: 457px;
background-color : green;
bottom: 0;
}