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.
Related
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.
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.
How do I align the red box with the gray box vertically?
http://jsfiddle.net/sLZzK/1/
I need several box combinations like that on my page, which is why I cannot simply push the red box up manually. A negative margin won't work either, since I do not know in advance how much content will be in the gray box. And the red box must overlap other page content, hence the absolute positioning. (http://jsfiddle.net/xMm82/)
CSS:
body {
padding: 0;
margin: 10px;
}
.left_div {
margin-bottom: 10px;
width: 300px;
height: 70px;
border: 1px solid gray;
}
.right_div {
position: absolute;
border: 1px solid red;
left: 311px;
width: 200px;
height: 200px;
}
HTML:
<div class="left_div">gray box
<div class="right_div">red box</div>
</div>
Why are you using absolute positioning for such structure? In the case the better solution is to use float: left for each div. If you want to have two divs aligned vertically use display: table-cell rule. Here it is:
FIDDLE
UPDATE: Try to use this:
FIDDLE
what I've understood is you want gray box on top of Red box:
first of all wrap them in a parent div.
set the width of wrapper to desirable width.
set width to 100%(both red and gray) and you are done !! (fiddle)
If you want to arrange them horizontally:
left_div will be wrapper
it will contain 2 child div's
left one will have content and right one will be red box.(fiddle)
I would do it this way:
HTML:
<div class="container">
<div class="left_div">gray box</div>
<div class="right_div yellow">red box</div>
<div class="clr"></div>
</div>
CSS:
.container:not(:last-child){margin-bottom: 10px;}
.left_div,.right_div{float:left;}
.clr{clear:both;}
Fiddle here.
use float to arrange vertically and clear:both to prevent any errors
here's the corrected one
.left{
float:left;
width: 300px;
}
.right{
float:left;
width: 200px;
}
.left_div {
width: 300px;
height: 70px;
border: 1px solid gray;
}
.right_div {
border: 1px solid red;
width: 200px;
height: 200px;
}
<div class="left">
<div class="left_div">
</div>
</div>
<div class="right">
<div class="right_div">
</div>
</div>
<div style="clear:both"></div>
http://jsfiddle.net/sLZzK/8/
There you go: http://jsfiddle.net/sLZzK/14/
HTML:
<div class="wrapper">
<div class="left_div">gray box</div>
<div class="right_div">red box</div>
</div>
CSS:
.wrapper {
border: 1px solid #369;
padding: 10px;
}
.wrapper > div {
display: inline-block;
vertical-align: middle;
}
You might also want to read about flexbox which will give you a similar and more consistent result, however it's not fully supported on various browsers yet.
I'm sure this has been asked before but I'd really like to know why this is doing what's it's doing rather than just the answer (if there is one).
What I've got is a pretty simple layout at the moment, which consists of a main wrapper div, a header div, a content div and a footer div. The problem I'm having is when I come to place a number of squares within the content div and set their positioning to absolute - so as to lay them out in a grid so that they span the entire width of the content div. When I set these divs to absolute the footer div jumps up and does not appear below the grid of divs sitting in their parent content div. If I set the height of the content div to a value the footer div sits where it should, but if I don't or set it to auto (as I want to do) then the footer div sits effectively below the content div.
I have read that setting anything to absolute takes it out of the normal flow of the document, but is there anyway I can set the content div so that the height of the content div is set by the contents (ie the grid of divs) and also so that the footer div always sits below the content div?
Here is a mock up http://jsfiddle.net/M4jyH/3/
And here is my code
#wrapper {
width: 400px;
height: auto;
border: 1px solid #000;
margin: 10px auto;
padding: 10px;
}
#header {
width: 100%;
height: 50px;
border: 1px solid #000;
}
#content {
position: relative;
width: 100%;
/*height:92px;*/
border: 1px solid #000;
margin: 10px 0px 0px 0px;
}
.box {
position: absolute;
width: 92px;
height: 92px;
background-color: #999;
}
#footer {
position: relative;
width: 100%;
height:92px;
border: 1px solid #000;
margin: 10px 0px 0px 0px;
}
<div id="wrapper">
<div id="header">header</div>
<div id="content">
<div class="box" style="top:0px; left:0px;"></div>
<div class="box" style="top:0px; left:102px;"></div>
<div class="box" style="top:0px; left:205px;"></div>
<div class="box" style="top:0px; left:308px;"></div>
</div>
<div id="footer">footer</div>
</div>
You don't need to use position: absolute for the inner elements, to position them horizontally just use float: left with margin for spacing. You will still get a similar collapsing height going on with regard to the content region - because again floats are partially taken out of the content flow. However, this is easily fixed by applying overflow: hidden to the content area.
I've added first and last classes to your box elements, just to make handling margins easier:
<div id="content">
<div class="box first"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box last"></div>
</div>
I've also altered your css items as follows:
#content {
overflow: hidden; /* <-- added overflow hidden */
position: relative;
width: 100%;
outline: 1px solid #000;
margin: 10px 0px 0px 0px;
}
.box {
float: left; /* <-- replaced pos abs with float left */
margin-right: 10.5px; /* <-- added a specific margin */
width: 92px;
height: 92px;
background-color: #999;
}
.box.last {
margin-right: 0px;
}
With regards to using 10.5px for the margin, it is probably best if you re-evaluate the dimensions used so this is not necessary. However most modern browsers will handle this correctly.
http://jsfiddle.net/M4jyH/5/
position: absolute should really only be used for items that you specifically want taken out of the document flow and to not interfere with anything else.
The div inside another div picture and code below. Because there will be text and images of the parent div. And red div will be the last element of the parent div.
<div style="width: 200px; height: 150px; border: 1px solid black;">
<div style="width: 100%; height: 50px; border: 1px solid red;">
</div>
</div>
This is one way
<div style="position: relative;
width: 200px;
height: 150px;
border: 1px solid black;">
<div style="position: absolute;
bottom: 0;
width: 100%;
height: 50px;
border: 1px solid red;">
</div>
</div>
But because the inner div is positioned absolutely, you'll always have to worry about other content in the outer div overlapping it (and you'll always have to set fixed heights).
If you can do it, it's better to make that inner div the last DOM object in your outer div and have it set to "clear: both".
A flexbox way.
.parent {
display: flex;
flex-direction: column;
justify-content: space-between;
}
/* not necessary, just to visualize it */
.parent {
height: 500px;
border: 1px solid black;
}
.parent div {
border: 1px solid red;
}
<div class="parent">
<div>Images, text, buttons oh my!</div>
<div>Bottom</div>
</div>
Edit:
Source - Flexbox Guide
Browser support for flexbox - Caniuse
Make the outer div position="relative" and the inner div position="absolute" and set it's bottom="0".
Here is another pure CSS trick, which doesn't affect an elements flow.
#parent {
min-height: 100vh; /* set height as you need */
display: flex;
flex-direction: column;
background: grey;
}
.child {
margin-top: auto;
background: green;
}
<div id="parent">
<h1>Positioning with margin</h1>
<div class="child">
Content to the bottom
</div>
</div>
You may not want absolute positioning because it breaks the reflow: in some circumstances, a better solution is to make the grandparent element display:table; and the parent element display:table-cell;vertical-align:bottom;. After doing this, you should be able to give the the child elements display:inline-block; and they will automagically flow towards the bottom of the parent.
Note : This is by no means the best possible way to do it!
Situation :
I had to do the same thign only i was not able to add any extra divs, therefore i was stuck with what i had and rather than removing innerHTML and creating another via javascript almost like 2 renders i needed to have the content at the bottom (animated bar).
Solution:
Given how tired I was at the time its seems normal to even think of such a method however I knew i had a parent DOM element which the bar's height was starting from.
Rather than messing with the javascript any further i used a (NOT ALWAYS GOOD IDEA) CSS answer! :)
-moz-transform:rotate(180deg);
-webkit-transform:rotate(180deg);
-ms-transform:rotate(180deg);
Yes thats correct, instead of positioning the DOM, i turned its parent upside down in css.
For my scenario it will work! Possibly for others too ! No Flame! :)
Here is way to avoid absolute divs and tables if you know parent's height:
<div class="parent">
<div class="child"> Home
</div>
</div>
CSS:
.parent {
line-height:80px;
border: 1px solid black;
}
.child {
line-height:normal;
display: inline-block;
vertical-align:bottom;
border: 1px solid red;
}
JsFiddle:
Example
You may not want absolute positioning because it breaks the reflow: in some circumstances, a better solution is to make the grandparent element display:table; and the parent element display:table-cell;vertical-align:bottom;. After doing this, you should be able to give the the child elements display:inline-block; and they will automagically flow towards the bottom of the parent.
<div style="position: relative;
width: 200px;
height: 150px;
border: 1px solid black;">
<div style="position: absolute;
bottom: 0;
width: 100%;
height: 50px;
border: 1px solid red;">
</div>
</div>
<div style="width: 200px; height: 150px; border: 1px solid black;position:relative">
<div style="width: 100%; height: 50px; border: 1px solid red;position:absolute;bottom:0">
</div>
</div>