So I've got essentially a list of items, that are separated by a border. I'd like to have equal padding and margin applied to the top and bottom of each item.
Here's a fiddle that contains a simplified version of what I'm working with.
Now, you see, I have 10px of margin and padding applied to the top and bottom of each item, but the items aren't evenly spaced. There's more space above each item than below it.
I realize that this is probably a result of CSS's collapsing margins behaviour, and that I could fix it by adding more padding than margin to get the spacing I want.
The issue is, however, that to some items, I want to highlight by adding a background colour, like this fiddle. And when I do, the padding on the top and the bottom must be the same.
So how can I fix this issue? I want it to be super flexible, so I can customize the amount of padding and margin if I like, and also be able to remove the border but still have it display properly.
HTML:
<div class="list">
<div class="item">
<span class="fill"> </span>
</div>
<div class="item">
<span class="fill"> </span>
</div>
<div class="item">
<span class="fill"> </span>
</div>
</div>
CSS:
.item {
display: block;
width: 150px;
margin-top: 10px;
margin-bottom: 10px;
padding-bottom: 10px;
padding-top: 10px;
border-bottom: 1px solid red;
}
.fill {
background-color: #aaa;
display: block;
height: 150px;
}
.bg {
background-color: #ccc;
}
Here is a fork of your fiddle
To achieve correct symetrical, vertical spacing, I actually created a 1px div to replace your border:
<div class="myborder"> </div>
with myborder class like so:
.myborder {
heigth: 1px;
background: red;
font-size: 1px;
margin-top: 10px;
width: 150px;
}
The border div is placed in between item divs, like so:
<div class="item">
<span class="fill"> </span>
</div>
<div class="myborder"> </div>
<div class="item bg">
<span class="fill"> </span>
</div>
In item class, I removed the border and margin-bottom attributes:
.item {
display: block;
width: 150px;
margin-top: 10px;
/*margin-bottom: 10px;*/
padding-bottom: 20px;
padding-top: 20px;
/*border-bottom: 1px solid red;*/
background-color:yellow;
}
You will get symetrical, vertical spacing between items as long as myborder's margin-top and item's margin-top attributes are equal.
UPDATE: in the provided, forked fiddle, I also created an invisible border class, as you mentioned being able to remove the border and keep proper spacing:
.myinvisibleborder {
height: 1px;
background: transparent;
font-size: 1px;
margin-top: 10px;
width: 150px;
}
By setting background to transparent, it becomes invisible; another way would be to set height and font-size to 0px;
The reson for problem lies in margin itself. If you are providing a
margin then it will take a blank space from provious element. Now if
you are applying padding means indirectly u are increasing div size.
Here in your problem u can solve this by making top and bottom margin
0 and instead doubling padding in ".item" class as follows:
.item {
display: block;
width: 150px;
**margin-top: 0px;
margin-bottom: 0px;
padding-bottom: 20px;
padding-top: 20px;**
border-bottom: 1px solid red;
}
this will look perfect without touching to other code segments!
The problem is the way you are seeing things. The padding and margins are all equal, but you can't see them that way as you only have a bottom border. If you add a top border (red like the bottom one), you can see that the spacing is exactly the same between the items.
Now if you want to fix your problem, you have to take into account that you only have one border, so you can remove one of the paddings or margins.
Edit: Replace your css code with the following and you should achieve what you want:
.item {
display: block;
width: 150px;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid red;
}
Edit 2: I just realised that because of your highlighting in your second example, you'll run into another problem. So you'll probably have to take out the red line from the divs and put them into a separate entity.
Edit 3: Here's a jsfiddle with updated, hope it does what you want.
Related
Why does scrollbar appears when i remove display: inline-block property from link and is there any another way to avoid scrollbar from appearing
Php file -
<main>
<div class="container">
<h2>Test Your PHP Knowledge</h2>
<p>This is a multiple choice quiz to test your knowledge of PHP</p>
<ul>
<li><strong>Number of Questions : </strong>5</li>
<li><strong>Type : </strong>Multiple Choice</li>
<li><strong>Estimated Time : </strong>4 Minutes</li>
</ul>
Start Quiz
</div>
</main>
body{
font-family: arial;
font-size: 15px;
line-height: 1.6em;
}
.container{
width: 60%;
margin: 0 auto;
overflow: auto;
}
header{
border-bottom: 3px #f4f4f4 solid;
}
footer{
border-top: 3px #f4f4f4 solid;
text-align: center;
padding-top: 5px;
}
main{
padding-bottom: 20px;
height: auto;
overflow-y: auto;
}
What does below property display:inline-block does to avoid scrollbar in main area
Css File -
a.start{
display: inline-block;
color: #666;
background: #f4f4f4;
border: 1px dotted #ccc;
padding: 6px 13px;
}
You can see what happens when you give a background color to the container.
What happens here is that the padding to the <a> does not help increase the height of the container.
.container {
background:tan;
padding:1px .5em;
}
.container a {
padding:1em;
background:#eee;
border:1px solid;
}
<div class="container">
<p>Some text here</p>
<a>Some inline text here</a>
</div>
The system doesn't use the <a>'s padding for the calculations of the container's height, so the container incorporates the line height of the a, but not the bottom padding.
So the <a> overflows out of the container. Its padding does not have any effect on its positioning. (You also see that the top padding of the <a> is inside the bottom margin of the <p>.)
Now if you change the <a>'s display mode to inline-block, the whole picture changes: the padding does count; the container does grow to encompass its padding, and its top padding is no longer intruding on the <p>'s bottom margin.
.container {
overflow:visible;
background:tan;
padding:1px .5em;
}
.container a {
display:inline-block;
padding:1em;
background:#eee;
border:1px solid;
}
<div class="container">
<p>Some text here</p>
<a>Some inline-block text here</a>
</div>
So there are a couple of solutions:
Accept that things are as they are; keep the <a> an inline-block
Remove the overflow:auto, so that the <a> bleeds out of the container. This may affect elements on the screen below the container though
Don't use padding on the <a>
Put some other, block or inline-block, element in the container after the <a>.
So I currently have the following HTML/CSS:
<style type="text/css">
body {
background: #eeeeee;
}
.table {
display: table;
margin: 0px auto;
max-width: 400px;
position: relative;
}
.row {
display: table-row;
max-width: 400px;
}
.td1,
.td2 {
display: table-cell;
border: 2px #aaaaaa solid;
padding: 15px;
background: #ffffff;
font-size: 18px;
color: #333333;
}
.td2 {
border-top: none;
color: #777777;
position: absolute;
max-width: 400px;
right: 0px;
left: 0px;
}
.under_div {
position: relative;
}
</style>
<body>
<div class="table">
<div class="row">
<div class="td1">Some random text that changes and can change the height of this div/td</div>
</div>
<div class="row">
<div class="td2">Some random text that changes and can change the height of this div/td</div>
</div>
<div class="row">
<div class="under_div">
<p>Some random text that remains the same always
</div>
</div>
</div>
</body>
My problem is that the second td (td2) needs to be position: absolute. There is a reason why it is so, so therefore it just can't be a regular div, as that would make this much easier :)
So, as you can see the next in the under_div is occupying the same space as the td2div. What I would like is for that to right under the td2div. In principle I could just try to position it so that it fits right under. But as stated in text of the divs the text changes, and therefore the height will be random for both the td1 and td2 divs.
So is there a way where I can stack the under_div div just under the td2 div where it of course follows along according to whatever size the two other divs have, and not just stick around in one position ?
I have tried just making another table-div after the first one. But that doesn't seem to do anything either...
I think you need to rethink your design a little as I don't think it's possible to do this with an absolutely positioned element. You can accomplish what I believe you want using float and clear. An example jsfiddle is here.
I'm trying to render column header text vertically, so the columns are narrow. I cannot seem to get the text to rotate and stay within the div.
I've made a quick jsfiddle.
https://jsfiddle.net/DaveC426914/w674sLbL/9/
My "pre-problem" is that my demo is not rendering correctly.
It's repeating the data three times i.e. three 17s, three 18 and three 19s. I don't know why.
(The barebones Angular fiddle I started from did not contain a div ng-app="myApp" so I had to add it or the angular is never applied. I thought maybe that had something to do with it, but remving this div breaks the app.)
Once I fix that, my real problem is that I can't get the text to behave. It should fall within the 100px tall, 20px narrow boxes that should be flush against each other, so that he columns are only 20px or so wide. They are rendering 100px wide.
<div class="table-header-cell" ng-repeat="item in headerDates">
{{item.date}}
</div>
.table-header-cell {
display: inline-block;
border: 1px solid grey;
margin: 1px 1px 5px;
height: 30px;
transform: rotate(-90deg);
transform-origin: left bottom;
width: 100px;
}
I've tried variants of nesting a div within a div, and applying the rotation to outer or inner divs. I've also tried setting width to 100px and height to 20px in the hopes that it applies the dimensioning before the rotation, but so far no combination has worked.
Try wrapping the text in an internal div and apply transforming and margin properties to that instead of all width and rotation on a single div.
Use the following html:
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<div class="table-header-cell" ng-repeat="item in headerDates">
<div class="innertext">
{{item.date}}
</div>
</div>
</div>
</div>
and the css:
.table-header-cell {
display: inline-block;
border: 1px solid grey;
margin: 1px 1px 5px;
width: 30px;
height:90px;
}
.table-header-cell .innertext {
transform: rotate(-90deg);
width: 150px;
margin: 0 -60px;
}
This should give you the results your looking for hopefully.
If this helps please mark the answer and vote it. Thanks
For the angular ng-repeat issue, you need to make sure your load type is "No wrap in Body" for your JavaScript, also you were loading Angular twice so I removed the second load.
And for the rotation, you should not rotate the container, but create an inner container and rotate on that.
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<div class="table-header-cell" ng-repeat="item in headerDates">
<div class="cell">
{{item.date}}
</div>
</div>
</div>
</div>
.table-header-cell {
display: inline-block;
border: 1px solid grey;
margin: 1px 1px 5px;
height: 100px;
width: 30px;
}
.cell {
transform: rotate(-90deg);
margin-left: -30px;
margin-top: 30px;
width: 100px;
}
Here is the corrected fiddle: https://jsfiddle.net/w674sLbL/10/
Hope this helps.
Fiddle: http://jsfiddle.net/rg3w8kxc/2/
I have a fixed bar on top and an element below it. Since the top bar is fixed, I need to add some padding to the top of the element below it so that the whole height of that element shows. However, when I add something like padding-top:40px for example, it doesn't move the element down; rather it creates space below the element. Same goes with margin.
I feel like I'm missing something obvious. What's the issue here?
Here's my HTML:
<div id="top-bar">
<div class="section-wrap">
Win a [name of phone]!
</div><!-- .section-wrap -->
</div>
<div id="top-section-page">
<div class="section-wrap">
<span>⇦</span> Back to the mix
</div>
</div>
<p>Some text here</p>
Here's my CSS:
#top-bar {
background: #FAFAFA;
height: 60px;
line-height: 60px;
padding: 0 20px;
position: fixed;
width: 100%;
z-index: 999;
}
#top-section-page {
background: url("http://i.imgur.com/KNYV8j2.jpg") repeat center top #69C9CA;
border-bottom: 10px solid #FFF;
line-height: 185px;
margin-bottom: 100px;
}
You can add add the padding-top on the body and then you need a top 0px on the #top-bar
Add this to your css code:
body{
padding-top: 40px;
}
#top-bar {
top: 0px;
}
Is this standard CSS behavior?
How does one get the container to wrap around the button?
http://jsfiddle.net/frank_o/yepw7oLw/
CSS:
.button {
background: grey;
padding: 10px 20px;
}
.test {
border: 1px solid black;
}
HTML:
<div class="test">
<a class="button">Test</a>
</div>
This is happening because your a.button element is currently being displayed as inline. Margin and Padding values applied to the top and bottom of inline elements don't impact elements around it, because the browser doesn't want to affect the flow.
To fix this, add display: inline-block to the a.button element.
This will force the browser to treat it as block for all rules regarding styling, and treat it as inline for placement on the page.
Add
display: block;
to .button
Generally I wouldn't recommend adding padding to an anchor <a> tag.
Add the padding and other styles to a <div> instead, with the anchor encompassing that div: JSFiddle
New HTML:
<div class="test">
<a href='#'>
<div class='button'>Test</div>
</a>
</div>
EDIT: in my JSFiddle example above, the width of the grey button defaults to 100% of the container, but you can change this if required by adding a width value to the .test div.
Try adding
display: block;
as suggested and add a width to the button so it is not the full length of your div, e.g:
body {
padding: 20px;
}
.button {
display: block;
width: 4%;
background: grey;
padding: 10px 20px;
}
.test {
border: 1px solid black;
}