This is best explained through my JSFiddle. I'm using Chrome.
I have an inline-block container element. Inside of it are inline elements (spans).
<div id="container">
<span class="star">★</span><span class="star">★</span>
</div>
When I give the star class padding of 5px, the border of the container renders as expected, at the edge of the last element.
When I change the padding to 5.5, or one of many other decimal values, the container appears to have additional width on one side (the more inner elements, the more profound this effect is).
Actually, I suspect that the container doesn't have extra width, but that the inner elements have too little width. Notice how the blue box displayed by Chrome's element inspector is narrower that in should be in the first example.
When the element is inline:
when the element is inline-block:
What's going on here?
Ok, let's try to get to a reasonable conclusion.
Using fractional pixels is not wrong, but it doesn't work quite exactly as we would expect, since most browsers will round up the fractional number to an integer one.
I wish I could give you an official reference regarding this matter, but I can't. It is not a standard, it's just the way some browsers decided to render it. (if someone can find a reference, please feel free to update the answer)
Now, with that information in mind:
It's just a matter of math:
(This measures are calculated in Google Chrome)
Without padding, your star character has a width of 13.33px. And you are adding a surrounding padding of 5.5px. So:
FIRST STAR SECOND STAR
-------------------- -------------------
5.5 | 13.33 | 5.5 5.5 | 13.33 | 5.5
-------------------- -------------------
Summing up: 5.5 + 13.33 + 5.5 + 5.5 + 13.33 + 5.5 = 48.66
So the parent element is told by the browser that it's inner contents sum up to 48.66px, but based on what we have considered, it will render as 49px.
If that's true, then a 49px element should be exactly the same size of your example, as it is:
#container {
display: inline-block;
border: dashed 1px red;
}
#compare {
border: dashed 1px blue;
width: 49px;
text-align: center;
margin-bottom: 10px;
}
.star {
padding: 5.5px;
background-color: lightgray;
}
<div id="compare">49px</div>
<div id="container">
<span class="star">★</span><span class="star">★</span>
</div>
Conclusion:
You may ask, why isn't the inner content also rounded up to a total of 49px?
Apparently, the browser will round up or down depending of the fractional, so 13.33px will round to 13px on the inner elements, causing it to render smaller than its parent.
Fractional pixels are allowed, you can refer to this answer: Can a CSS pixel be a fraction?
However, it depends on the browser how it interprets it. If you open your fiddle in IE11 the width is correct (funny IE11 being 'better' at something).
A quick test on safari show us that they are fit. Look:
The best way to fight with this is adding the border to the star. Take a look here:
#container {
display: inline-block;
border: dashed 1px red;
}
#container2 {
display: inline-block;
}
.star {
/* This creates extra width. */
padding: 5.5px;
background-color: lightgray;
}
.star2 {
/* This is fine. */
padding: 5px;
background-color: lightgray;
}
.star3 {
/* This is fine. */
padding: 5.5px;
border-top: dashed 1px red;
border-bottom: dashed 1px red;
background-color: lightgray;
}
.star3:first-child {
border-left: dashed 1px red;
}
.star3:last-child {
border-right: dashed 1px red;
}
<div id="container">
<span class="star">★</span><span class="star">★</span>
</div>
<div id="container">
<span class="star2">★</span><span class="star2">★</span>
</div>
<div id="container2">
<span class="star3">★</span><span class="star3">★</span><span class="star3">★</span>
</div>
#container {
display: inline-block;
border: dashed 1px red;
}
.star {
/* This creates extra width. */
/* padding: 4.48px 6.72px; */
/* This is fine. */
/* padding: 5px; */
/* This creates extra width. */
padding: 5.5px;
display: inline-block;
background-color: lightgray;
}
<div id="container">
<span class="star">★</span><span class="star">★</span>
</div>
#container {
display: inline-block;
border: dashed 1px red;
}
.star {
/* This creates extra width. */
/* padding: 4.48px 6.72px; */
/* This is fine. */
/* padding: 5px; */
/* This creates extra width. */
padding: 5.5px;
display: inline-block;
background-color: lightgray;
}
Related
I have an editable span element that will be initially empty. Its height varies when it's empty and when its not, and can't figure out how to make give it the correct height.
<b>Foo:</b> <span contenteditable>Bar</span>-<span contenteditable></span>
span[contenteditable]
{
display: inline-block;
min-width: 2ch;
height: 1em;
padding: 0 .2em;
outline: 1px solid #text-subtle-color;
}
As noted by #temani-afif and #facundo-corradini, this issue seems to be an inssue only in FireFox. With a couple more searches with that in the query I found a simple fix that seems to work, and also not mess anything up in the other browsers:
*[contenteditable]:empty:before
{
content: "\feff"; /* ZERO WIDTH NO-BREAK SPACE */
}
Note: If I drop the :empty selector, which was not part of the linked answer nor the answer of #facundo-corradini here, things looks off again. Their extra does also not seem to make a difference.
You can do it with the Flexbox:
.flex-container {
display: inline-flex; /* takes only the content's width */
/*align-items: stretch; by default / takes care of the equal height among all flex-items (children) */
}
.flex-container > * {
margin: 0 5px; /* just for demonstration */
}
span[contenteditable] {
/*display: inline-block;*/
min-width: 2ch;
/*height: 1em;*/
/*padding: 0 .2em;*/
/*outline: 1px solid #text-subtle-color;*/
border: 1px solid; /* also this */
}
<div class="flex-container">
<b>Foo:</b> <span contenteditable>Bar</span>-<span contenteditable></span>
</div>
<div class="flex-container">
<b>Foo:</b> <span contenteditable>Bar</span>-<span contenteditable>123</span>
</div>
It's an issue with empty content editable specifically on Firefox.
A workaround is to set a pseudo-element containing a zero width no-break space "character" as follows:
span[contenteditable]
{
display: inline-block;
min-width: 2ch;
height: 1em;
padding: 0 .2em;
outline: 1px solid grey;
box-sizing:border-box;
content="";
}
span[contenteditable]:before {
content: "\feff ";
}
<b>Foo:</b> <span contenteditable>Bar</span>-<span contenteditable placeholder=""> </span>
I want to make a table via Html/Css (Javascript if needed) which basically looks like this:
As you can see there every row in this table has a bottom border, which starts above an image in the table, and then goes down to the other columns.
Is there any way to do this? (Maybe with a transparent image?)
You can use a psudo element with a rotation to solve this:
Check out this jsfiddle
http://jsfiddle.net/zRMLr/
You will likely have to play with the numbers a lot to get it to work with whatever you want.
what I used in this demo (no images) BUT only works for IE9+
html:
<table>
<tr><td><div></div></td><td></td><td>Some sort of text</td></tr>
<tr><td><div></div></td><td></td><td>Some sort of text</td></tr>
<tr><td><div></div></td><td></td><td>Some sort of text</td></tr>
</table>
css:
table {
width: 400px;
}
td:first-child {
border-top: 1px solid black;
width: 20px;
}
td:first-child:after {
content: '';
border-top: 1px solid black;
display: block;
width: 28px;
height: 1px;
float: left;
position:relative;
top: -5px;
left: 24px;
transform:rotate(45deg);
-ms-transform:rotate(45deg); /* IE 9 */
-moz-transform:rotate(45deg); /* Firefox */
-webkit-transform:rotate(45deg); /* Safari and Chrome */
-o-transform:rotate(45deg); /* Opera */
}
td:first-child div {
width: 10px;
height: 10px;
background-color: red;
}
td:nth-child(2) {
width: 14px;
}
td:last-child {
border-bottom: 1px solid black;
}
What you may do to achieve the desired effect is:
Create a div with a left/right border
Rotate using CSS3 rules the div to give this effect
Or
create a div with a left/right border
use border radius to have the desired effect
I hope this helps, if you would like I can bring some sample of code for you
My problem is with the below html
<div class="editor-container">
<div class="editor-row curFocus">
<div class="editor-label">
<label for="FirstName">First Name</label>
</div>
<div class="editor-field">
<input class="text-box single-line valid" id="FirstName"
name="FirstName" type="text" value="Nancy" maxlength="20">
</div>
</div>
</div>
When the user selects the input field, I add class "curFocus" to the outer div via some javascript to highlight both label and the input field.
My css is -
.editor-container {
border: thin solid #444444;
display: table; width: 100%;
}
.editor-row {
width: 100%; display: table-row;
}
.editor-label {
padding-left: .4em; width: 40%;
}
.editor-label, .editor-field {
padding-right: .4em; padding-bottom: .2em; padding-top: .2em;
display: table-cell;
}
.curFocus {
border: 2px solid #05365b;
background-color: #d3e5f2;
margin: 3px; padding: 3px;
}
My problem is that while using debuggers in Chrome 12 and IE9, they both show the border settings being applied to the outer div. But, when viewing the form, neither browser display's the specified border. All other css settings work correctly. I also tried changing definition of ".curFocus" to ".curFocus div". But this applied the style to each of the nested div's also, but did display borders on all of the divs.
While I'm not a CSS expert, it is not obvious why this shouldn't work.
Edit
Here is jsfiddle link - http://jsfiddle.net/photo_tom/KmsF5/1/. While testing this it does work correctly in IE9 if in IE7 compatibly mode. Otherwise, it does not display correctly.
Sorry about not including link, still getting use to fact that jsfiddle even exists.
Well, I can tell you what's causing it, but I can't tell you why. Elements with display: table-row; can't have a border applied to them. You can apply the border to the table-cell children of the .curFocus element, but not the table-row itself.
Again, no idea why this silly rule exists, but you can fix your problem with some CSS:
.curFocus {
background-color: #d3e5f2;
margin: 3px; padding: 3px;
}
.curFocus>div {
border: 2px solid #05365b;
border-width: 2px 0px; /* top and bottom border for all the table-row's immediate children (table-cells) */
}
.curFocus>div:first-child {
border-width: 2px 0px 2px 2px; /* left border for the leftmost table-cell */
}
.curFocus>div:last-child {
border-width: 2px 2px 2px 0px; /* right border for the rightmost table-cell */
}
See http://jsfiddle.net/d772N/
I think your problem is your display type on the .editor-row. display: table-row; Remove that and the problem will go away. Plus I don't think that all browsers support display: table-row; very well.
You might need a higher CSS specificity, as it is ambiguous which CSS styles will apply with the current definitions.
Try div.curFocus rather than .curFocus div for the class definition to apply the style to the div with that class name rather than its div children.
In my web app I use the following CSS to provide notices/error messages:
#notice {
border: 1px solid green;
padding: 1em;
margin: 1em;
margin-bottom: 2em;
background-color: lightgreen;
font: bold sans-serif;
color: darkgreen
}
But when a notice isn't required, I want to have white space equal to the amount of space that this notice would've taken up. I want to do this so that my web pages look consistent, and items on the page aren't shifted up/down according to whether there is a notice or not.
I have done this by setting a fixed height.
I've also heard the argument that its okay to have the page bump down, (that's how stackoverflow works) because it draws attention to the message and that is a good thing.
The solution can depend on how you want to / have to implement this notice block. If you update the page with Ajax (without graceful degradation, a JS off fallback to normal state) I strongly recommend to do this with modal windows like Facebook - its nice and handy. If you did not have the chance to use modal windows it could be something like:
#notice{ height: 100px; margin: 1em 1em 2em } /* #notice can be a wrapper with basic dimensions */
.error{ border: 1px solid red; } /* reuse the same block */
.info{ border: 1px solid green; } /* reuse the same block */
And the HTML respectively:
<div id="notice"></div>
Error state:
<div id="notice" class="error"> Your error message </div>
Info state:
<div id="notice" class="info"> Your info message </div>
Of course you can run into problems with the #notice div height when the message is too long but that is an other problem :)
You can set a fixed height and width for the div.
#notice {
....
height: 200px;
width: 100%;
}
Alternatively, you may use min-height and min-width.
I'm assuming the div with #notice won't be there if you don't need it. Why not use the adjacent selector like this. It won't work in some browsers like IE6. Give the element following it the class of "following" or something similiar. There will still be a bit of a difference because you have the 2px from the border in there.
#notice {
border: 1px solid green;
padding: 1em;
margin: 1em;
margin-bottom: 2em;
background-color: lightgreen;
font: bold sans-serif;
color: darkgreen
}
.following {
margin-top:4em
}
#notice + .following {
margin-top:2em;
}
I'm trying to use divs instead of tables to style boxes around my content. The content can be any size and needs to allow the browser to be resized to any degree. Need the background color and border to contain the content. This works fine with tables. How do I get a div to work the same way?
Note: I added "_"s because my non-breaking spaces were getting lost.
Sample Page
Sample image
(source: c3o.com)
Content:
<style type="text/css">
div.box, table.box
{
padding: 10px 1000px 10px 10px;
}
div.box-header, td.box-header
{
border: solid 1px #BBBBBB ;
font-size: larger;
padding: 4px;
background-color: #DDDDDD;
}
div.box-body, td.box-body
{
padding: 6px;
border: solid 1px #BBBBBB ;
border-top: none;
}
</style>
<div class="box">
<div class="box-header">please_help_make_these_divs_stop_overlapping</div>
<div class="box-body">please_help_make_these_divs_stop_overlapping</div>
</div>
<table class="box" width="100%" cellpadding="0" cellspacing="0">
<tr><td class="box-header">tables_make_good_containers_tables_make_good</td></tr>
<tr><td class="box-body">tables_make_good_containers_tables_make_good</td></tr>
</table>
There is no easy way to do this that is crossbrowser friendly that I know of.
At least in firefox you can create an simulated table by setting divs with
display:table;
display:table-row;
display:table-cell;
So that those divs work like table elements. Then the box will contain it's content. Wether that's a good solution or not is debateable.
I've been having similar issues with page layouts myself. Usually I've solved those by setting min-width and overflow:auto;
If you really don't want to use a table you can do this:
div.box div {
overflow: hidden;
zoom: 1; /* trigger haslayout for ie */
}
Next time this kind of problem comes up go to giveupandusetables.com.
One way is to make your boxes floats. Add float:left; to box, box-header, and box-body. Add clear:both; to box-body to force it below box-header. You'll probably need to add clear property to whatever content follows as well.
You will not get right edges of box-header and box-body to align, though. If you want their widths to be the same, you really want a table. Table is a tool to make all cells in the same column to share the widths.
For other ideas, check out this SO question.
Firstly, you should be using semantic markup. If something is a header and content mark it up as such with header and paragraph tags. That will help you move out of the 'table-way' of thinking were you try to emulate your markup and styles like a table, markup should come first, CSS can come after.
The following should do what you want:
<style type="text/css">
* {
margin:0px;
padding:0px;
}
.box {
border: solid 1px #BBBBBB;
margin:10px;
}
.box h3 {
padding: 4px;
border-bottom: solid 1px #BBBBBB;
background-color: #DDDDDD;
}
.box p {
padding: 6px;
}
</style>
<div class='box'>
<h3>please help make these divs stop overlapping</h3>
<p>please help make these divs stop overlapping</p>
</div>
Thinking about markup and style separately is the path to CSS Zen Mastery :o)
This works (actually holds together better than tables in ie7 too)
div.box{
float:left;
width:auto;
margin: 10px 1000px 10px 10px;
}
div.box-header{
float:left;
width:100%;
border: solid 1px #BBBBBB ;
font-size: larger;
padding: 4px;
background-color: #DDDDDD;
}
div.box-body{
clear:left;
float:left;
width:100%;
padding: 4px;
border: solid 1px #BBBBBB ;
border-top: none;
}
NOTE: both boxes have to have same left and right padding or one juts out a bit.
Floats are not needed, but you seem to be confusing the uses of margin vs. padding. The following minor tweaks to your style works as you need it to:
<style type="text/css">
div.box, table.box
{
margin: 10px 1000px 10px 10px;
border: solid 1px #BBBBBB ;
padding: 0px;
}
div.box-header, td.box-header
{
font-size: larger;
padding: 4px;
background-color: #DDDDDD;
border-bottom: solid 1px #BBBBBB ;
}
.box-body, td.box-body
{
padding: 6px;
}
</style>
I've changed the padding on the box to a margin, moved the border to your box, and added an underline to the header.
I had this problem also using Firefox 6.0.1, Opera 10.62, Safari 5.1, but not in IE 9, and the overflow:auto fixed it in all browsers. Nothing else did. I also tried overflow:contain, which also fixed the problem, but it appears that contain is not a valid value for overflow, so I am assuming that, since the value was not valid, auto was substituted.