I'm adding a pseudo-element with :before and position it absolutely to its parent which can be a table or a div. For design purposes the parent also has to have a 20px border.
wwhy are firefox and IE inconsistent and treat the positioning of the pseudo-element differently in the table?
Please have a look at my jsFiddle or the code below.
Tested with IE10, Chrome29 and FF23.
HTML:
<div>i am a div</div>
<table>
<thead>
<tr><th>header 1</th><th>header 2</th></tr>
</thead>
<tbody>
<tr><td>entry 1</td><td>entry 2</td></tr>
</tbody>
</table>
CSS:
table,
div {
border: 20px solid yellow;
position: relative;
margin-bottom: 30px;
height: 50px;
}
table:before,
div:before {
background: red;
content: " ";
position: absolute;
display: block;
position: absolute;
top: 0;
left: 0;
width: 10px;
height: 10px;
}
Seems to be an issue with how Firefox handles absolutely positioned elements within tables. Can you try wrapping the div and table inside their own relatively positioned parent divs?
Check this DEMO.
EDIT: In cases where the html structure cannot be modified, try giving the elements box-sizing: border-box;.
This DEMO seems to work in Chrome, FF & IE on my machine. Let me know if it isn't rendering, and I'll give it another shot.
It seems to be that :before works good with just table less layouts on FF. There is some information on MDN which might be helpful.
Although the positioning fixes in Firefox 3.5 do not allow content to be generated as a separate previous sibling (as per the CSS spec stating "The :before and :after pseudo-elements elements interact with other boxes... as if they were real elements inserted just inside their associated element."), they can be used to provide a slight improvement on tableless layouts (e.g., to achieve centering)
when I added display: block to the table element and removed the fixed height, it is working fine.
table,
div {
border: 20px solid yellow;
position: relative;
margin-bottom: 30px;
display: block;
}
table:before,
div:before {
background: red;
content: " ";
position: absolute;
display: block;
top: 0;
left: 0;
width: 10px;
height: 10px;
}
Working Fiddle
For more information, go through MDN.
Related
I need to use this shape and inside that shows a text. But, I don't know why the text is not showing.
HTML:
<div id="thebag">
<h3> Shihab Mridha </h3>
</div>
CSS:
#thebag{
position: relative;
overflow: hidden;
}
#thebag::before{
content: '';
position: absolute;
top: 0;
left: 0;
height: 50px;
width: 30%;
background: red;
}
#thebag::after {
content: '';
position: absolute;
top: 0;
left: 30%;
width: 0;
height: 0;
border-bottom: 50px solid red;
border-right: 70px solid transparent;
}
https://jsfiddle.net/kn87syvb/1/
You need to add position: relative (or position: inherit, since it's the same as the parent) to your #thebag h3 class. Currently, your CSS styles are only affecting the parent of the h3—in order for the h3 to show with the text, you need to define CSS styling for it.
https://jsfiddle.net/kn87syvb/2/
By setting a position:absolute to the #thebag::before you "broke" the flow and your text is behind your div. You have to precise, than the h3 tag will be relative depending it's container.
So you have to add this :
#thebag h3 {
position:relative
}
To precise all h3 on your #thebag section will be affected. Be careful, if you change your kind of selector, It won t work anymore.
May be it will be better to use a custom class, like this https://jsfiddle.net/kn87syvb/5/
You need to use postion:relative property:
#thebag h3{
postion:relative;
}
Small explanation:
position: relative will layout an element relative to itself. In other words, the elements is laid out in normal flow, then it is removed from normal flow and offset by whatever values you have specified (top, right, bottom, left). It's important to note that because it's removed from flow, other elements around it will not shift with it (use negative margins instead if you want this behaviour).
However, you're most likely interested in position: absolute which will position an element relative to a container. By default, the container is the browser window, but if a parent element either has position: relative or position: absolute set on it, then it will act as the parent for positioning coordinates for its children.
please check this snippet:
https://jsfiddle.net/kn87syvb/4/
You can also re-structure your HTML and CSS as follows:
HTML
<span class="start">Shihab Mridha</span>
<span class="end"></span>
CSS
.end {
height:0;
width:0;
float: left;
display: block;
border:10px solid #0f92ba;
border-top-color:transparent;
border-right-color:transparent;
border-bottom-color:#0f92ba;
border-left-color:#0f92ba;
}
.start{
height: 20px;
width: 60px;
float: left;
background: #0f92ba;
display: block;
color:#FFFFFF;
}
Reference Link : https://solutionstationbd.wordpress.com/2011/12/21/trapezoids-shape-with-css/
I have a holder div that has specific dimensions, and has a single child element of varying height, and I am trying to align it to the baseline. Currently, I have a second element that is the same fixed height as the container which makes it aligned to the bottom, but if it is on its own, it sticks to the top, regardless of what rules are applied.
So, how can I vertically align an element to the bottom of a container if it is the only child element?
EDIT
While in the process of putting up the code that I am using, I came up with a solution which I have posted. The initial problem is similar to that, but without the position rules, and display:inline-block on the child elements. That is pretty much the long and short of it...
Damn it, thought of a solution after posting the question which works nicely:
Parent Element:
.parent {
height:200px;
position:relative;
width:200px;
}
Child Element:
.parent > * {
bottom:0px;
left:0px;
position:absolute;
right:0px;
}
The height of the Child element is then defined by block elements within it, but it sticks to the bottom
One way using table-cell
Assuming the bare bones markup:
<div class="wrap">
<div>Some content...</div>
</div>
the following CSS will do it:
.wrap {
border: 1px solid red;
height: 200px;
width: 200px;
display: table-cell;
vertical-align: bottom;
}
Major advantage: works with both inline and block level elements.
Disadvantage: Older browsers don't recognize display: table-cell
Demo at: http://jsfiddle.net/audetwebdesign/eXKbt/
Alternate way using inline-block
You can also do it this way by applying the following CSS:
.wrap2 {
border: 1px solid red;
height: 200px;
width: 200px;
}
.wrap2:before {
content: "";
width: 0;
height: 190px;
display: inline-block;
}
.wrap2 div {
display: inline-block;
width: 190px;
border: 1px dotted red;
vertical-align: bottom;
}
However, this approach involved using a pseudo-element to define a fictitious inline block to set a baseline nearly the full height of the box and then using vertical-align on the child element. There were some issues related to the width but it can be made to work.
See earlier fiddle for demo.
Not much detail to go off of, but maybe something like this
.container {
position: relative;
}
.child-element {
position: absolute;
bottom: 0;
}
This is my CSS code;
#wrap {
width:50em;
max-width: 94%;
margin: 0 auto;
background-color:#fff;
}
#head {
width:50em;
height:10em;
max-width: 100%;
margin: 0 auto;
text-align:center;
position: relative;
}
#css-table {
display: table;
margin: 1em auto;
position: relative;
width:50em;
max-width: 100%;
}
#css-table .col {
display: table-cell;
width: 20em;
padding: 0px;
margin: 0 auto;
}
#css-table .col:nth-child(even) {
background: #fff;
}
#css-table .col:nth-child(odd) {
background: #fff;
border-right: 4px double #b5b5b5;
}
And my HTML code;
<div id="cont">
<div id="css-table">
<div class="col">123</div>
<div class="col">123</div>
</div>
</div>
When I scale the Firefox window, the table scales fine even down to 300px width viewport...just like I want to. But in Chrome, the table looks normal only when the viewport is wider than 50em. If I narrow the Chrome window, the table bleeds out on the right side of the wrap.
Is there a reason why is Chrome doing this?
Technically Chrome is following the rules because max-width should only apply to block elements.
From MSDN docs:
The min-width/max-width attributes apply to floating and absolutely
positioned block and inline-block elements, as well as some intrinsic
controls. They do not apply to non-replaced inline elements, such as
table rows and row/column groups. (A "replaced" element has intrinsic
dimensions, such as an img or textArea.)
The table (or in your case display:table) should technically not work or be supported. FF apparently obeys it fine, but you'll probably need to come up with another solution, either removing the display:table or the max-width.
max-width property
MSDN Doc
The solution I found was using table-layout: fixed and width: 100%
Create a div and give it a styling to display block and a max width. You may use traditional <table> and give it a styling of 100% width.
I was able to use a mixin(SASS) to fix the issue.
#mixin clearfix {
&::after{
content: "";
display: table;
clear: both;
}
}
I'm trying to learn how to use the :before and :after pseudo elements. I'm trying to add a black background to the bottom of the page as a sticky footer but it doesn't seem to be working correctly.
Basically I have a repeating image as the background of the HTML element and then I add an absolute div positioned at the bottom with a solid black background.
I'd just like to point out that this is a learning experiment and not really how I'd achieve the same effect but what I'm trying is working in Firefox but not in Chrome!
Here's my CSS:
html {
background-image: url('images/template/html-bg.jpg');
background-position: top left;
background-repeat: repeat-x;
background-color: #0e0e0e;
height: 100%;
position: relative;
}
html:before {
content: "";
display: block;
background-color: #000;
width: 100%;
height: 138px;
bottom: 0px;
position: absolute;
}
In FF the page is rendered as I'd expect but in Chrome the whole page is black... Any ideas, am I doing this wrong?
Your CSS should work as expected, as your pseudo-element should be drawn in the context of the initial containing block (the viewport, represented by the html element) anyway, which is exactly what Firefox is doing.
Your particular issue was reported as a Chrome bug, but it hasn't been addressed. As a workaround, you can apply your pseudo-element to body instead:
body:before {
content: "";
display: block;
background-color: #000;
width: 100%;
height: 138px;
bottom: 0px;
position: absolute;
}
Depending on your layout, you may need to either keep your html rule or change it to body as well.
I want to set vertical alignment of image inside a div. I use img { vertical-align:middle}
but it is not working.
Using the line-height property will solve the problem:
<style>
.someclass {
width: 300px;
height: 300px;
text-align: center;
line-height: 300px;
border: dotted;
}
.someclass img {
margin: auto;
vertical-align: middle;
}
</style>
<div class="someclass">
<img src="someimg.jpg" border="0" alt="">
</div>
This is a solution that doesn't require JavaScript (as my previous solution did).
You can achieve what you want by assigning display: table-cell to the containing div. Here's an example: http://jsbin.com/evuqo5/2/edit
I feel I must warn you that you will need to test this in every browser you intend to support. Support for the table-cell value is fairly new, particularly in Firefox. I know it works in Firefox 4, but I don't know about any of the 3.x iterations. You'll also want to test in IE (I've only tested in Chrome 10 and Firefox 4).
The CSS:
div#container {
width: 700px;
height: 400px;
position: relative;
border: 1px solid #000;
display: table-cell;
vertical-align: middle;
}
div#container img {
margin: 0 auto;
display: block;
}
You won't need the div#container img styles if you don't also want to horizontally align the image.
If you're trying to do what I think, vertical align isn't going to work; you'll need to use positioning.
In general, position the container relative, and then position the image absolute, with top and left set to 50%, and then move the image back to the center by setting negative margins equal to half the width / height.
Here's a working example: http://jsbin.com/evuqo5/edit
Basic CSS is this:
#container { position: relative; }
#container img {
position: absolute;
left: 50%;
top: 50%;
margin-top: /* -1/2 the height of the image */
margin-left: /* -1/2 the width of the image */
}
See this awser: How to vertical align image inside div
If you want to align horizontally also, add the right and left, like this:
div {
position:relative;
}
img {
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
}
The following post has some useful references:
Text Alignment w/ IE9 in Standards-Mode
Also, depending on which version of IE you are testing against, you may end up needing some browser-specific hacks or some jQuery/JavaScript code.
If you have to, use a one-row-one-cell table and take advantage of the vertical-align property. This is brute-force, not overly semantic, but it works.
If you set the div display attribute to table-cell then vertical-align: middle; will work.
The vertical-align rule only affects table cells or elements with display: table-cell.
See this article from SitePoint for a detailed explanation.
<style>
/* change body to .someClasses's parent */
body {
width: 100%;
height: 100%;
display: table;
}
body > .someclass {
width: 300px;
height: 300px;
text-align: center;
border:dotted;
margin: 0 auto
display: table-cell;
vertical-align: middle;
}
</style>
<body>
<div class="someclass">
<img src="someimg.jpg" border="0" alt="">
</div>
</body>