I am trying to center a block of dynamic height. I followed the nice guide at Vanseo Design and implemented the solution with negative margins. After a while of tweaking I got it to work in Chrome, but when trying in IE and Firefox the negative margins were way off! Chrome and Safari handles the position as expected, but not IE and FF. Had it been only IE I could have done a classic IE-CSS-hack, but with Firefox in the mix as well... Anyone who know how to get vertical cenetring with dynamic element to work in all browsers?
Screenshot from Chrome / Safari (Correct):
Screenshot from Firefox / IE (Wrong):
<!DOCTYPE html>
<html>
<head>
<title>Dead Centre</title>
<style type="text/css" media="screen"><!--
body
{
color: white;
background-color: #000;
margin: 0px
}
#content
{
position: absolute;
top: 50%;
left: 0%;
height: 64%;
width: 100%;
margin-top: -32%;
text-align:center;
background-color:#339;
}
--></style>
</head>
<body>
<div id="content">
<div class="bodytext">This box should be centered vertically</div>
</div>
</body>
</html>
Well, you put a height of 64% for your element, so let do mats :)
100-68 = 36 ,., so there is only 36% left.
then devide this by 2 and you have 18
By putting your content ID to 18% from top and removing your margin, everything should work just fine. :)
#content
{
position: absolute;
top: 18%;
left: 0%;
height: 64%;
width: 100%;
text-align:center;
background-color:#339;
}
Related
I'm centering my canvas using this code:
position:absolute;
top:50%;
left:50%;
margin-top:-200px; /* Half of canvas height */
margin-left:-275px; /* Half of canvas width */
It works perfect in all browsers except for IE9 and 10. In Internet Explorer, it covers the whole page. Is it possible to support the centering the canvas in IE?
Centring using margin: 0 auto; with display: block; works in almost all browser - the ones that support <canvas> for sure.
Live example: http://jsbin.com/ovoziv/2
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Centring Canvas</title>
</head>
<body>
<canvas></canvas>
</body>
</html>
CSS
canvas {
display: block;
background: #FFFFB7;
width: 550px;
height: 400px;
margin: 0 auto;
}
EDIT: Updated answer to center vertically too. This CSS will do the trick:
canvas {
background-color: #FFFFB7;
width: 550px;
height: 400px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -275px;
margin-top: -200px;
}
Now the explanation. We first place the canvas with 50% offset from the top and left-side using position: absolute by setting top and left to 50%. Then, because your canvas has a static size, we add a negative margin (which you should never do when the element is not absolute positioned) for half of the width and size (550x400/2 = 275x200): margin-left: -275px; margin-top: -200px;.
The canvas will now be displayed at the center of the screen. If you do this inside another element and want to center in that one, try adding position: relative; to that element, so it will use it's bounds instead of the body's.
Live example here: http://jsbin.com/ovoziv/6
My Chrome install updated itself last night (without telling or asking me!)
It now interprets CSS percentage relative positioning differently to yesterday. Suppose I have:
<body>
<div class="everything">
<div class="centerMe">
Center me!
</div>
</div>
</body>
And this CSS:
body
{
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
.everything
{
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
}
.centerMe
{
position: relative;
top: 50%;
left: 50%;
}
In the version of Chrome I had until last night (6.x), and for that matter in Firefox 3.6.10 and IE 8, the Center me! appears roughly in the middle of the page, vertically and horizontally.
But in Chrome 7.0.517.41, it is only centred horizontally. Vertically, it is at the top of the page.
Was this change made deliberately to address a long-standing inaccuracy in CSS rendering, or is it a new bug in 7.x that Google will fix soon?
Notes:
If I take out the <div class="centerMe"> and corresponding </div> then Chrome 7.x obeys the vertical positioning, but Firefox and IE don't! (i.e. browsers all reverse their behaviour).
If I change the CSS for .centerMe to position: absolute; all browsers I've tested behave consistently, centring vertically and horizontally. This makes more sense anyway, so would appear to be the sane workaround for anyone who hits this as a problem.
As always, IE's behaviour is nothing remotely similar unless <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> appears at the start of the HTML.
It seems Chrome 7 doesn't calculate implicit height of an absolute-positionned element, as this will work :
body
{
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
.everything
{
position: absolute;
left: 0px;
top: 0px;
right: 0px;
height:100%; /* fix height */
}
.centerMe
{
position: relative;
top: 50%;
left: 50%;
}
I don't see anything in W3C specifications so I think it's a "bug". Anyway this method is bad to center an element ^^
I have an issue with background-position in mobile safari. It works fine on other desktop browsers, but not on iPhone or iPad.
body {
background-color: #000000;
background-image: url('images/background_top.png');
background-repeat: no-repeat;
background-position: center top;
overflow: auto;
padding: 0px;
margin: 0px;
font-family: "Arial";
}
#header {
width: 1030px;
height: 215px;
margin-left: auto;
margin-right: auto;
margin-top: 85px;
background-image: url('images/header.png');
}
#main-content {
width: 1000px;
height: auto;
margin-left: auto;
margin-right: auto;
padding-left: 15px;
padding-right: 15px;
padding-top: 15px;
padding-bottom: 15px;
background-image: url('images/content_bg.png');
background-repeat: repeat-y;
}
#footer {
width: 100%;
height: 343px;
background-image: url('images/background_bottom.png');
background-position: center;
background-repeat: no-repeat;
}
Both "background_top.png" and "background_bottom.png" are shifted too far to the left. I've googled around, and as far as I can tell, background-position IS supported in mobile safari. I've also tried every combination of keywords ("top", "center", etc.), px, and %. Any thoughts?
Thanks!
Update: here's the markup in the .html file, which displays the design & layout fine in other browsers: (I also updated the above css)
<html lang="en">
<head>
<title>Title</title>
<link rel="Stylesheet" type="text/css" href="styles.css" />
</head>
<body>
<div id="header"></div>
<div id="main-content"></div>
<div id="footer"></div>
</body>
</html>
Both background images are very wide (~2000px) so as to take up space on any sized browser.
P.S. I know that there's probably a few more efficient CSS shortcuts I could be using, but for now I like having the code organized like I have it for visibility.
The iPhone/Webkit browser cannot center align background images when placed in the body tag. The only way around this is to remove the background image from your body tag and use an additional DIV as a wrapper.
#wrapper {
background-color: #000000;
background-image: url('images/background_top.png');
background-repeat: no-repeat;
background-position: center top;
overflow: auto;
}
<html lang="en">
<head>
<title>Title</title>
<link rel="Stylesheet" type="text/css" href="styles.css" />
</head>
<body>
<div id="wrapper">
<div id="header"></div>
<div id="main-content"></div>
<div id="footer"></div>
</div>
</body>
</html>
It'll work with
background-position-x: 50%;
background-position-y: 0%;
and still add
background-position: center top;
for other browsers.
Apparently, when you "scroll" on an iPhone / iPad, you're not scrolling the page in the same way as you do in a desktop browser. What you're doing is more like moving the whole page within a viewport. (I'm sure someone will correct me if I'm using the wrong terminology here.)
This means that background-position: fixed is still "supported" but has no real effect, since the whole page is moving within the viewport rather than the page content scrolling within the page.
Create a wrapper ID to place in the body, then include the following CSS:
#background_wrap {
z-index: -1;
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-size: cover;
background-image: url('../images/compressed/background-mobile.png');
background-repeat: no-repeat;
background-attachment: scroll;
}
Just ensure that none of your content goes within the div otherwise the whole page will be fixed with no scrolling.
I have this problem and I'm addressing it by getting rid of my fixed footer using a separate style as mentioned here: How to target CSS for iPad but exclude Safari 4 desktop using a media query?
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 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.