child button exceeds parent absolute container - html

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>

Related

The width of the element's content if it is a child with absolute positioning

I am trying to create a dropdown component (similar to an HTML select). I am working on a content width issue. I need it to behave like an inline-block, but if I set the wrapper class as an inline-block, the width of the content starts to be adjusted according to the width of the button.
How can it be solved so that the width of the content behaves as if the wrapper is set to block even if it is inline-block?
.wrapper {
position: relative;
display: inline-block;
}
button {
color: white;
border: 0;
background: #2c7be5;
padding: 10px 15px;
}
.content {
position: absolute;
border: 1px solid #2c7be5;
margin-top: 4px;
padding: 15px;
}
<div class="wrapper">
<button>Toggle box</button>
<div class="content">
My box content
</div>
</div>

position: fixed prevents elements to be centered properly

I want to center .donut-graphs inside .dashboard horizontally, so the space between the right edge of the sidebar and the left edge of .donut-graphs is the same as the space from the right edge of .donut-graphs and the right edge of the screen. I have managed to do so, but I had to remove position: fixed from .navbar. The problem is, I can't do that because my sidebar has to stay on top of the screen when you scroll up/down, and with position: fixed on .navbar, the graphs aren't centered properly.
HTML:
<div class="container">
<div class="navbar">
</div>
<div class="content">
<div class="dashboard">
<div class="donut-graphs">
<div class="dashboard-income">
Div 1
</div>
<div class="dashboard-overall">
Div 2
</div>
<div class="dashboard-spent">
Div 3
</div>
</div>
</div>
</div>
</div>
CSS:
body {
margin: 0;
}
.container {
display: flex;
align-items: stretch;
max-width: 100%;
min-height: 100vh;
}
.navbar {
background-color: #ddd;
flex: 0 0 230px;
position: fixed;
height: 100vh;
width: 230px;
}
.content {
flex: 1;
overflow-x: auto;
text-align: center;
}
.donut-graphs {
display: inline-flex;
border: 1px solid;
margin: 50px auto 0;
position: relative;
text-align: left;
}
.dashboard-income,
.dashboard-overall,
.dashboard-spent {
height: 256px;
width: 357px;
display: inline-block;
}
.dashboard-income {
background-color: green;
}
.dashboard-overall {
background-color: blue;
}
.dashboard-spent {
background-color: red;
}
How can I overcome the issue?
Demo
position: fixed puts element above everything. That element won't attach to any element in body because it is the way that works. It only becomes dependent of viewport
What you want to achive could be done with position: absolute but parent (whose child you want to center) has to be position: relative for this to work.
Read more about positioning elements in css here
.content { padding-left:230px; }
Should do the trick.
Assigning your navbar a fixed position takes it out of the document flow, so when centering your donut graphs the browser doesn't take the navbar into account.
Giving the .content element a padding equivalent to the width of the navbar makes up for this.
The only problem with this approach is that if .navbar changes dimensions, you'll need to change the padding on .content to match.

Margin Overflow From Parent in CSS

Whenever I add margin to any element I get overflow, I tried adding box-sizing, position:relative. but nothing works
searched on google but nothing seems to help me
can anyone know why is this happening?
Sample Image
The margin is outside the element. One way to deal with it is to use calc on width as in the following snippet.
And note that margin is diferent from padding: paddingis inside the border (so it is included in the area covered by the background color), margin is outside:
.x {
box-sizing: border-box;
margin: 30px;
width: calc(100% - 60px);
background: yellow;
border: 5px solid red;
}
<div class="x">margin....</div>
With padding instead of margin, this would be:
.x {
box-sizing: border-box;
padding: 30px;
width: 100%;
background: yellow;
border: 5px solid red;
}
<div class="x">Padding....</div>
You can't add margin to a div that is a sibling of your container or else it'll create an overflow. Use padding instead. See how the text in the margin example shifts the text.
.parent {
width: 100px;
height: 100px;
background: red;
}
.padding-example {
padding: 10px;
}
.margin-example {
margin: 10px;
}
<div class="parent">
<div class="padding-example">Correct</div>
</div>
<hr>
<div class="parent">
<div class="margin-example">Wrong</div>
</div>

Can't center div in another div

I'm trying to make a menu bar centered horizontally in the header of my page. For some reason, i can't get the centering to work. I made a little test page roughly displaying the problem: JSFiddle. The inner div has to be 5px away from the bottom, that's whatI use the position: absolute for.
I've tried searching on the web alot, but everything I find gives me the same result, or none at all. Most problems I found were when text-align: center wasn't in the container div, but even with it, it still doesn't work.
I removed two css attributes and it work.
position: absolute;
bottom: 5px;
Check this Fiddle
5px from bottom. Fiddle
This is not a perfect way, but it's still kind of useful. I first think of this idea from this Q&A.
You'll have to make some change to your HTML:
<div id="container">
<div id="wrapper-center"> <!-- added a new DIV layer -->
<div id="inner_container">
TEXT ELEMETNES IN THIS THING!!!!
</div>
</div>
</div>
And the CSS will change to:
#container {
background: black;
width: 100%;
height: 160px;
position: relative;
}
#inner_container {
display: inline-block;
width: auto;
color: white;
background-color: #808080;
padding: 5px;
position: relative;
left:-50%;
}
#wrapper-center {
position:absolute;
left:50%;
bottom:5px;
width:auto;
}
Demo fiddle
The trick is to place the wrapper at the given top-bottom position, and 50% from left (related to parent), and then make the true content 50% to left (related to the wrapper), thus making it center.
But the pitfall is, the wrapper will only be half the parent container's width, and thus the content: in case of narrow screen or long content, it will wrap before it "stretch width enough".
If you want to centre something, you typically provide a width and then make the margins either side half of the total space remaining. So if your inner div is 70% of your outer div you set left and right margins to 15% each. Note that margin:auto will do this for you automatically. Your text will still appear to one side though as it is left-aligned. Fix this with text-align: centre.
PS: you really don't need to use position absolute to centre something like this, in fact it just makes things more difficult and less flexible.
* {
margin: 0;
padding: 0;
}
#container {
background: black;
width: 100%;
height: 160px;
}
#inner_container {
color:red;
height:50px;
width: 70%;
margin:auto;
text-align:center;
}
If you don't want a fixed width on the inner div, you could do something like this
#outer {
width: 100%;
text-align: center;
}
#inner {
display: inline-block;
}
That makes the inner div to an inline element, that can be centered with text-align.
working Ex
this CSS changes will work :
#container {
background: black;
width: 100%;
height: 160px;
line-height: 160px;
text-align: center;
}
#inner_container {
display: inline;
margin: 0 auto;
width: auto;
color: white;
background-color: #808080;
padding: 5px;
bottom: 5px;
}
Try this:
html
<div id="outer"><div id="inner">inner</div></div>
css
#outer {
background: black;
width: 100%;
height: 160px;
line-height: 160px;
text-align: center;
}
#inner{
display: inline;
width: auto;
color: white;
background-color: #808080;
padding: 5px;
bottom: 5px;
}
example jsfiddle
You may set the inline style for the inner div.
HTML:
<div id="container">
<div align="center" id="inner_container" style="text-align: center; position:absolute;color: white;width:100%; bottom:5px;">
<div style="display: inline-block;text-align: center;">TEXT ELEMETNES IN THIS THING!!!!</div>
</div>
</div>
Here is working DEMO

Is it possible for inline-block element to auto fill the available width?

I have a <div id="content">, which contains <div id="sub-navigation> and <div id="main container">, which themselves are inline-blocks. I would like to be able to make the main container fill the rest of the available page width. Is that possible?
I need columns-strip to expand or shrink based on the number and width of column elements. If the width of the columns-strip exceeds the width of the main container, then a horizontal scroll bar should appear.
* {
margin: 0px;
padding: 0px;
font-size: 10pt;
white-space: normal;
}
#wrapper {
margin: 0px 20px;
background-color: red;
}
#header {
margin: 25px 10px 10px 10px;
height: 50px;
background-color: purple;
color: white;
}
#content {
margin: 10px;
padding: 10px;
font-size: 0pt;
white-space: nowrap;
overflow: hidden;
background-color: white;
}
#sub-navigation {
width: 200px;
height: 150px;
display: inline-block;
vertical-align: top;
background-color: forestgreen;
color: white;
}
#main-container {
padding: 10px;
display: inline-block;
overflow: auto;
background-color: yellow;
}
#columns-strip {
padding: 10px;
font-size: 0pt;
white-space: nowrap;
background-color: mediumturquoise;
}
.posts-column {
margin: 0px;
width: 200px;
height: 200px;
display: inline-block;
vertical-align: top;
overflow: auto;
}
#footer {
margin: 10px 10px 25px 10px;
height: 50px;
background-color: navy;
}
<div id="wrapper">
<div id="header"></div>
<div id="content">
<div id="sub-navigation"></div>
<div id="main-container">
<div id="columns-strip">
<div class="posts-column" style="background-color: lightgray;"></div>
<div class="posts-column" style="background-color: darkgray;"></div>
<div class="posts-column" style="background-color: gray;"></div>
</div>
</div>
</div>
<div id="footer"></div>
</div>
You have to remove the inline-block styles and float the #sub-navigation div. inline-block is not suited for what you are trying to achieve. When you add no display styles, the div element will be the default value which is block, block elements take up all the available space by default. By floating the #sub-navigation element you make it only take up the space required for its contents.
#sub-navigation {
width: 200px;
height: 150px;
float : left;
vertical-align: top;
background-color: forestgreen;
color: white;
}
#main-container {
padding: 10px;
overflow: auto;
background-color: yellow;
}
make sure to add a clear: left element after the #main-container
That's not how inline-blocks are supposed to be used. Best thing to do here is make your navigation box float:left and leave the default display value alone.
If your header, footer and wrapper have specific widths, then yes, you can have your main-container fill the available space. But if you're not specifying widths in your CSS, then you need to determine how big your main-container CAN be based on the rendered width of the containing element (wrapper). The only way to determine that width after the page loads is with javascript. If you want your site to have a dynamic width but still have your content (sub-navigation and main-container) fill the screen, you would either need to use javascript or percentages, and percentages can get ugly when you start looking at varying resolutions of monitors, laptops, etc...
Ever heard of flex box model!!
It is made just for that.
Note in flexbox model all child elements act as flex box model you cant opt out certain things. Which mean if page has navigation and under it content div + side div. You can't make top navigation out of it. Which has implications. So solution is to have all things only that need flex box in one div.