3px double border on the left or right side of a div, however in chrome it is leaving a 1px gap at the top of the border. I have tried looking extensively to see if this is a browser bug or for some kind of solution.
http://jsfiddle.net/QSm2Z/2/
If you view the code in firefox/ie you get continuous black bar, in chrome and on my phone/tablet I am getting a 1px gap at the top of each div which breaks the black bar
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style type="text/css">
.test {
height: 100px;
width: 100px;
border-right: 3px double #c7c7c7;
border-left: 3px double #c7c7c7;
background-color: #06F;
padding: 0px;
margin: 0px;
border-bottom-style:
}
</style>
</head>
<body>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
</body>
</html>
Observations
There appears to be a glitch in the corner-shaping algorithm that leaves a mitered edge in preparation of meeting a border on a perpendicular edge even though there is not one.
I doubt this is the intended behavior, even though the spec states that:
This specification does not define how borders of different styles
should be joined in the corner.
You can see evidence of the mitered join with a 2 pixel solid border (screenshot):
If you look very closely, you can see the manifestation of another potential problem: the edges of the top and side borders don't touch (screenshot):
Workaround
This is complex/inelegant by comparison, but one way to fix the problem is to hide both the top and bottom edge of the offending elements. You'll need to adjust the dimensions for your actual site.
Example: http://jsfiddle.net/QSm2Z/10/
.test{
position: relative;
height: 100px;
width: 152px;
overflow: hidden;
}
.test:after {
width: 100px;
height: 102px;
content: "";
top: -1px;
position: absolute;
background-color: #06F;
border-left: 26px double #000;
border-right: 26px double #000;
}
Looks like a browser bug - it doesn't happen with regular solid borders - check this out: http://jsfiddle.net/QSm2Z/8/
Maybe related to this bug: https://code.google.com/p/chromium/issues/detail?id=61702
Related
I am trying to understand the basics of CSS layouting and have some problem with a page being too high when I add a border.
Here comes my code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="KKF_00005.css">
<title>KKF 5: Border coping</title>
</head>
<body>
<div class="links_aussen">
<div class="innen">Rechts</div>
</div>
<div class="mitte_aussen">
<div class="innen">Mitte</div>
</div>
<div class="rechts_aussen">
<div class="innen">Links</div>
</div>
</body>
</html>
I use the following stylesheet:
#CHARSET "ISO-8859-1";
* {
height: 100%;
margin: 0;
padding: 0;
}
html,body {
background-color: grey;
width: 100%;
}
.innen {
border: 1px solid black;
}
.links_aussen {
float: left;
background-color: green;
width: 33%;
height: 100%;
}
.mitte_aussen {
float: left;
background-color: yellow;
height: 100%;
width: 34%;
}
.rechts_aussen {
float: left;
background-color: red;
height: 100%;
width: 33%;
}
And here is jsFiddle
My problem is that this code gives me a nice 100% layout horizontally but creates a scrollbar being to high verticcally. I would like to have no scrollbars but also see the borders (so overflow: hidden; will not help me in this one I think) - tested in Chrome and Firefox.
So: How can I tell my little browser that it should remove 2 pixels from the height so that I can have borders and no scrollbars?
Thanks in advance for any ideas and answers
André
Here is a solution for you using box-sizing: border-box. It also removes the need for the .inner div.
http://jsfiddle.net/mqchen/xHFvG/
EDIT: If anyone is wondering why this works, look down at Joakim Johansson's post. Now, back at this post. The box-sizing property simply redefines how the browser calculates the size of elements. More about it here: https://developer.mozilla.org/en-US/docs/CSS/box-sizing
This is because the default box model is content-box, and works like this:
The heights you set changes the "Content" part. So if you have height set to 100%, and border set to 1%, that will add up to 101%.
This is solved in different ways depending on what you're trying to do.
For example you can set the box-sizing attribute: http://www.quirksmode.org/css/box.html to make the height attribute work in different ways.
Can't for the life of me figure out a good solution right now (since relying on box-sizing isn't that compatible), but here's a bad one, using absolute positioning: http://jsfiddle.net/XhfmR/
Your problem is borders:
Instead of
.innen {
border: 1px solid black;
}
http://jsfiddle.net/tt13/997zC/
Use
.innen {
border-left: 1px solid black;
border-right: 1px solid black;
}
http://jsfiddle.net/tt13/997zC/1/
When you write just border it adds borders to all sides of div. In your case, bottom and top border takes extra 1px, you're getting result 2px taller in height. That's why you see scrollbar.
And always use jsfiddle for this kind of questions.
.innen {
border: 1px solid black;
}
is your problem. It creates the vertical scrollbar.
To solve this, use this code:
.innen {
border-left: 1px solid black;
border-right: 1px solid black;
}
http://jsfiddle.net/yrLtz/
Edit: Maybe the best solution is box-sizing: border-box as #mqchen suggested.
I want to be able to draw a border OUTSIDE of my Div! So if my div is say 20px by 20px, I want a 1px border outside of this (so in essence, I get a div 22x22px large).
I understand that I can just make the div 22x22 to start with, but for reasons I have, I need the borders to be on the outside.
CSS outline works, but I want only border-bottom or border-top thingy, so something like outline-bottom, which does not work, is what I want.
Is there a way to do this?
Thanks
I think you've got your understanding of the two properties off a little. Border affects the outside edge of the element, making the element different in size. Outline will not change the size or position of the element (takes up no space) and goes outside the border. From your description you want to use the border property.
Look at the simple example below in your browser:
<div style="height: 100px; width: 100px; background: black; color: white; outline: thick solid #00ff00">SOME TEXT HERE</div>
<div style="height: 100px; width: 100px; background: black; color: white; border-left: thick solid #00ff00">SOME TEXT HERE</div>
Notice how the border pushes the bottom div over, but the outline doesn't move the top div and the outline actually overlaps the bottom div.
You can read more about it here:
Border
Outline
Try the outline property CSS Outline
Outline will not interfere with widths and lenghts of the elements/divs!
Please click the link I provided at the bottom to see working demos of the the different ways you can make borders, and inner/inline borders, even ones that do not disrupt the dimensions of the element! No need to add extra divs every time, as mentioned in another answer!
You can also combine borders with outlines, and if you like, box-shadows (also shown via link)
<head>
<style type="text/css" ref="stylesheet">
div {
width:22px;
height:22px;
outline:1px solid black;
}
</style>
</head>
<div>
outlined
</div>
Usually by default, 'border:' puts the border on the outside of the width, measurement, adding to the overall dimensions, unless you use the 'inset' value:
div {border: inset solid 1px black};
But 'outline:' is an extra border outside of the border, and of course still adds extra width/length to the element.
Hope this helps
PS: I also was inspired to make this for you : Using borders, outlines, and box-shadows
IsisCode gives you a good solution. Another one is to position border div inside parent div. Check this example http://jsfiddle.net/A2tu9/
UPD: You can also use pseudo element :after (:before), in this case HTML will not be polluted with extra markup:
.my-div {
position: relative;
padding: 4px;
...
}
.my-div:after {
content: '';
position: absolute;
top: -3px;
left: -3px;
bottom: -3px;
right: -3px;
border: 1px #888 solid;
}
Demo: http://jsfiddle.net/A2tu9/191/
Why not simply using background-clip?
-webkit-background-clip: padding;
-moz-background-clip: padding;
background-clip: padding-box;
See:
http://caniuse.com/#search=background-clip
https://developer.mozilla.org/en-US/docs/Web/CSS/background-clip
https://css-tricks.com/almanac/properties/b/background-clip
I shared two solutions depending on your needs:
<style type="text/css" ref="stylesheet">
.border-inside-box {
border: 1px solid black;
}
.border-inside-box-v1 {
outline: 1px solid black; /* 'border-radius' not available */
}
.border-outside-box-v2 {
box-shadow: 0 0 0 1px black; /* 'border-style' not available (dashed, solid, etc) */
}
</style>
example: https://codepen.io/danieldd/pen/gObEYKj
Way late, but I just ran into a similar issue.
My solution was pseudo elements - no additional markup, and you get to draw the border without affecting the width.
Position the pseudo element absolutely (with the main positioned relatively) and whammo.
See below, JSFiddle here.
.hello {
position: relative;
/* Styling not important */
background: black;
color: white;
padding: 20px;
width: 200px;
height: 200px;
}
.hello::before {
content: "";
position: absolute;
display: block;
top: 0;
left: -5px;
right: -5px;
bottom: 0;
border-left: 5px solid red;
border-right: 5px solid red;
z-index: -1;
}
Put your div inside another div, apply the border to the outer div with n amount of padding/margin where n is the space you want between them.
I need a div with a height of exactly 1em minus 1px. This can be achieved in most browsers like this:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type="text/css">
.helper {
/* background-color: black; */
position: absolute;
top: 5em;
left: 5em;
width: 2em;
height: 1em;
}
.target {
background-color: #89f;
position: absolute;
top: 0;
bottom: 1px;
width: 100%;
}
</style>
</head>
<body>
<div class="helper">
<div class="target"></div>
</div>
</body>
</html>
The "target" div has the desired height. The problem is, that this doesn't work in IE6, because it ignores the bottom attribute, when top is set (a well known problem).
Is there a workaround for IE6 (maybe with multiple nested divs, with borders/paddings/margins/whatever), or will JavaScript be the only solution?
Please note, that I can't use Quirks Mode.
Does the target div have to be physically 1px smaller or just display 1px smaller?
The easiest way would be to add in an "ie6 only" stylesheet:
.helper {overflow:hidden;}
.target {top:auto;}
This will display target as 1em - 1px but its real height is 1em with the top 1px is hidden.
IE6 is flaky when it comes to absolute positioning support.
Another solution, instead of the code above, would be to add in an "ie6 only" stylesheet:
.target {position:static;margin:-1px 0 1px 0;}
I see you got the absolute positioned solution to work. Great!
Is it required by the client? If not then just abandon IE6 and hacks for this crappy/old browser.
I am using Google Chrome 3.0.196.2 and I noticed that for some reason the #main div's background is shrunk a tad bit, even though it should not be. It tests fine in every other browser but chrome.
Anyone know why?
Link to site: link text
Even have a screen shot: link text
Notice the green on the right side is cut off, as well as things not lining up.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<STYLE type="text/css">
#main {
border: 10px solid black;
height: 300px;
width: 1000px;
margin-left: auto;
margin-right: auto;
padding-top: 50px;
background: #AAA url("http://www.ipalaces.org/weird/mainbg.gif");
}
#picture {
border-top: 1px solid #EEE;
border-bottom: 1px solid #EEE;
height: 100px;
width: 1000px;
}
</STYLE>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>Imperial Palaces</TITLE>
</HEAD>
<BODY>
<DIV id="main">
<IMG id="picture" src="http://www.ipalaces.org/weird/mainbg.gif" alt="picture">
</DIV>
</BODY>
</HTML>
This seems to be working OK on Chrome 2: http://skipall.com/2vb.jpg
Remember that Chrome 3 is still in beta, it's possible this is just a bug (I'm not sure, of course).
To debug, I think I'd zero-out the paddings and borders - check for differences, then try substituting the IMG for DIV tag to check if it's the container or IMG at fault. Maybe even chuck in a couple of outline properties to see exactly what's going on:
#main {
padding: 0;
}
#picture {
border: 1px solid #EEE;
border-width: 1px 0;
}
/* and later... */
#main, #picture {
outline: 1px solid red;
}
I want to have XHTML+CSS progress bar with contrast colors between filled and empty background areas.
I have a problem with text color. Because filled and empty backgrounds are too contrast (this is a requirement), to remain readable the text should be double-colored to be contrast to both of them. The image should explain it better than words:
Progress bar with dark blue filled area and white empty background http://drdaeman.pp.ru/tmp/20090703/progress-bar-text-example.png
Example of the problem http://drdaeman.pp.ru/tmp/20090703/progress-bar-text-problem.png
My current progress bar implementation is trivial, but as example above shows, the text can be hard to read in some cases, which is exactly a problem I want to solve.
My current (simplified) implementation attempt (fails, because overflow: hidden does not work without positioning div.progress which I cannot position because of inner span's width):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Progress bar test</title>
<style type="text/css">
div.progress_bar {
border: 1px #ccc solid; position: relative;
text-align: center; height: 32px;
}
div.progress_bar .progress {
height: 32px;
overflow: hidden; /* This does NOT work! */
}
div.progress_bar .progress div {
position: absolute; width: 100%; height: 32px;
z-index: 30; overflow: hidden;
background-color: #44a;
}
div.progress_bar span {
position: absolute; top: 0; left: 0; width: 100%;
z-index: 20;
color: #000;
}
div.progress_bar .progress span {
position: absolute; top: 0; left: 0; width: 100%;
z-index: 40;
color: #eee;
}
</style>
</head>
<body>
<!-- Can be of any (unknown) width. Think of "width: auto".
The 400px value is just to keep it small on a big monitor.
DON'T rely on it! -->
<div id="container" style="width: 400px;">
<div class="progress_bar">
<!-- div.progress is a dark filled area container -->
<div class="progress" style="width: 51%;">
<!-- Actually dark filled area -->
<div style="width: 51%;"></div>
<!-- Text (white).
Does not clip, even with overflow: hidden on parent! -->
<span>This is a test</span>
</div>
<!-- Text (black) -->
<span>This is a test</span>
</div>
</div>
</body>
</html>
Live version of the above: http://drdaeman.pp.ru/tmp/20090703/test2.html
Previous attempt: http://drdaeman.pp.ru/tmp/20090703/test.html
The images are GIMP edited prototypes, and not exactly what this code displays.
Add: Thank you all, especially Meep3D, Nosredna and Lachlan! However I still have a problem — in my case progress bar should have no fixed width and take all horizontally available space (width: auto; or width: 100% are acceptable). But without width: 400px rule Lachlan's code breaks. And I'd still like to avoid using JavaScript, if that's possible.
As per Meep3D's suggestion, take 2 copies of the text.
Wrap each in a div of the same width as the container. The "upper" div is wrapped with another div which clips at the desired percentage.
Update: removed the fixed widths.
The "upper" div is sized to the inverse percentage of its wrapper.
<html>
<head>
<style type="text/css">
#container {
position: relative;
border: 1px solid;
text-align: center;
width: 400px;
height: 32px;
}
.black-on-white {
height: 32px;
color: #000;
}
.white-on-black {
height: 32px;
color: #fff;
background-color: #44a;
}
.wrapper {
width: 53%;
overflow: hidden;
position: absolute;
top: 0; left: 0;
}
.black-on-white {
width: 100%;
}
.white-on-black {
width: 188.7%;
}
</style>
</head>
<body>
<div id="container">
<div class="wrapper">
<div class="white-on-black">
<span>This is a test</span>
</div>
</div>
<div class="black-on-white">
<span>This is a test</span>
</div>
</div>
</body>
</html>
What about putting a second copy of the progress bar text inside the div, and set the div's overflow to hidden, so it reveals with it?
--
Update: I am also not a javascript expert, but I am sure that you can find out the width of an object and then set the offset based upon that if the width is flexible as you say.
You could:
Find a grey which suits
Use JavaScript to change the colour between white and black dynamically, depending on where it is
Make the middle colour of the background gradient closer to white, and always use dark text
Put the progress outisde the box:
[######### ] 50 %
You could use a text shadow for your "percentage" text. The only downside to this is that it would only work in the latest browsers. Only Firefox 3.5, Safari (all versions), and Chrome 2+ support it.
Here is a demo of using text-shadow in a way that would make your progress readable.
http://www.w3.org/Style/Examples/007/text-shadow#white
If you're willing to use more JavaScript, you could try this jQuery plugin:
http://kilianvalkhof.com/2008/javascript/text-shadow-in-ie-with-jquery/
The article says it works in IE only, however it works in Chrome 3 (what I'm using), Firefox 3.5, Internet Explorer, and Safari. It may work in older browsers but I haven't tested it.
Meep3D has the correct answer. Two versions of the box. Reveal n% of the top one.
More options:
Put a translucent box under the
number that either darkens the area
for a white number or lightens the
area for a black number.
Use red and white as backgrounds and
a black number. (Problem here is red
is associated with error, so you can
play with other combinations of three
colors that are all high contrast
against each other.)
You need 2 values styled differently. And fixed width
let counter = 0
const increment = () => {
counter++
}
let interval = setInterval(() => {
increment();
document.querySelectorAll('.value').forEach(node => {
node.textContent = `${counter}`
});
document.querySelector('.progress-bar').style.width = `${counter}%`
if (counter >= 100) clearInterval(interval);
}, 50)
.progress-wrapper{
margin: 20px auto;
width: 400px;
height: 20px;
background-image: linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 50%, #ccc 50%, #ccc 75%, transparent 75%, transparent);
animation: progress-bar-stripes 2s linear infinite;
background-size: 40px 40px;
position: relative;
border-radius: 5px;
overflow: hidden;
}
.progress-bar{
z-index: 3;
overflow: hidden;
position: absolute;
height: 20px;
background-color: #8178d9;
text-align: center;
transition: width 0.5s ease;
}
.progress-value-1, .progress-value-2{
margin: 0;
position: absolute;
width: 400px;
color: #8178d9;
text-align: center;
z-index: 2;
font-weight: bold;
}
.progress-value-2{
color: #fff;
z-index: 1;
}
#keyframes progress-bar-stripes {
from {
background-position: 40px 0;
}
to {
background-position: 0 0;
}
}
<div class="container">
<div class="progress-wrapper">
<div class="progress-bar">
<p class="progress-value-2">
<span class="value"></span>%
</p>
</div>
<p class="progress-value-1">
<span class="value"></span>%
</p>
</div>
</div>
https://codepen.io/kosachevlad/pen/dypEjBa
This answer with the use of clip-path: inset(0 0 0 50%); is great.
The use of a background linear gradient with a background-clip as described in this answer is also interesting.