how to make "overflow: hidden" work for all browsers - css

Problem:
I am currently creating a webpage layout using divs and css rather than an HTML table layout. I want, of course, for this to be able to operate across all major browsers.
I have a pane for a banner, which has a floated menu over the left portion of it. The problem is that if the banner is too wide for the space provided, it jumps to a space below the menu (where it is wider) and takes all of the pages content with it.
Attempted solutions:
The obvious solution is to use the "overflow: hidden" property in my css. The problem is that this doesn't work in IE. I read that this is because I have it positioned relatively (which is true), but I don't see any way around using relative positioning in this case. I must keep it.
I also read that you could set the width of the pane to something besides the default, and then the "overflow: hidden" property would take effect. This DOES solve the problem in IE (setting width to 100%), but creates a problem in chrome (and potentially other browsers as well) where the alloted space for the banner is too wide for the page, and then chrome behaves the same way IE had originally - pushing the banner to the bottom of the page. This workaround could work, but I would need to define the width value as "100% - menuWidth" since there is a menu over the left side. I tried this:
style="width:expression(document.compatMode=='CSS1Compat'? document.documentElement.clientWidth-(Menu Width goes here)+'px' : body.clientWidth-(And here too)+'px');"
But using the expression doesn't appear to enable the "overflow" property, even though directly setting the width a simple value does.
EDIT: At request I have attached my code.
HTML:
<div id="ControlPanel" runat="server" class="contentpane" align="center"></div>
<div id="Link" runat="server" align="right" onclick="location.href='address.html';"></div>
<div id="Header" runat="server" class="header" align="right"></div>
<div id="Links" runat="server" class="header" align="center">LINKS</div>
<div id="Search" runat="server" class="skingradient" align="right">[SEARCH]</div>
<div id="LeftPane" runat="server" class="leftpane" align="left">[USER]</br>LEFT</div>
<div id="TopPane" runat="server" class="toppane" align="left"><img src="image.jpg" alt="" /></div>
<div id="RightPane" runat="server" class="rightpane" align="center">RIGHT</div>
<div id="ContentPane" runat="server" class="contentpane" align="center">CONTENT</div>
<div></div>
<div id="BottomPane" runat="server" class="bottompane" align="center">BOTTOM</div>
<div id="Footer" runat="server" class="skingradient" align="center">[COPYRIGHT]</div>
</body>
</html>
CSS:
#Search
{
position: relative;
top: -20;
background-color: transparent;
z-index: 1;
}
#Header
{
height: 77px;
background-color: #0860A8;
background-image: url(ImagePath.gif);
background-position: right;
background-repeat: no-repeat;
border-bottom: 1 solid white;
}
#Links
{
background-color: #E6E6E6;
}
#TopPane
{
border-top: 1 solid #0860A8;
position: relative;
top: -20;
overflow: hidden;
}
#LeftPane
{
float: left;
position: relative;
top: -20;
width: 200px;
height: 100%;
background-color: #E6E6E6;
border-right: 1 solid #0860A8;
}
#ContentPane
{
position: relative;
top: -20;
width: 100%;
height: 100%;
background-color: Green;
z-index: -1;
}
#RightPane
{
z-index: 0;
position: relative;
top: -20;
height: 100%;
float: right;
width: auto;
background-color: Red;
max-width: 40%;
width:expression(document.compatMode=='CSS1Compat'? document.documentElement.clientWidth*2/5+'px' : body.clientWidth*2/5+'px');
}
The color coding is to allow for easy previewing and editing of the site.

Make sure your file begins with a doctype, for one. It goes a long way toward making browsers act alike.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
...

I eventually hacked a solution that implemented slightly different styling for IE browsers.
IE has something called conditional comments, and has a 'comment' tag. Neither of these are recognized by other browsers, and are both simply passed over. The conditional comments take the following form:
<!--[if IE]> DO THIS <![endif]-->
Since it has the same structure as a typical comment (<!-- Commented code -->) it is passed over by all browsers besides IE, which apparently parses all comments looking for certain statements.
The comment tag:
<comment> HTML comment </comment>
This is recognized as a comment by IE, and is passed over, but other browsers just skip the unrecognized <comment> tag and process the line of code contained inside normally.
So my solution to this problem then since I could get IE to work one way, and other browsers another, was to place the HTML solution inside conditional comments:
<!--[if IE]><div id="TopPane" runat="server" class="toppane" align="left" style="width: 100%; overflow:hidden;"><img src="i5Banner.jpg" alt="" /></div><![endif]-->
and the solution for the remaining browsers inside the HTML 'comment' tags:
<comment><div id="TopPane" runat="server" class="toppane" align="left"><img src="i5Banner.jpg" alt="" /></div></comment>
This way I could treat IE browsers separately from other browsers. It may look ugly, but IE has apparently supported it through all IE versions and it causes no harm when encountered by other browsers, so I think I can consider it a safe and stable solution if nothing else is available.
I believe that this may offer a way around many of IE's other problems and idiosyncrasies.

If you wrap this floated element, and the others, in another (non-floated) div, and set the overflow property on that, it should work:
HTML:
<div id="wrapper">
<div id="the_problem_div">
</div>
</div>
CSS:
#wrapper {
overflow: hidden;
}

Related

Using :pseudo selector on img tag on hover [duplicate]

I'm trying to use the :before selector to place an image over another image, but I'm finding that it simply doesn't work to place an image before an img element, only some other element. Specifically, my styles are:
.container
{
position: relative;
display: block;
}
.overlay:before
{
content: url(images/[someimage].png);
position: absolute;
left:-20px;
top: -20px;
}
and I find that this works fine:
<a href="[url]" class="container">
<span class="overlay"/>
<img width="200" src="[url]"/>
</a>
but this does not:
<a href="[url]" class="container">
<img width="200" src="[url]" class="overlay"/>
</a>
I can use a div or p element instead of that span, and the browser correctly overlays my image over the image in the img element, but if I apply the overlay class to the img itself, it doesn't work.
I'd like to get this working because that extra span offends me, but more importantly, I've got about 100 blog posts that I'd like to modify, and I can do this in one go if I could just modify the stylesheet, but if I have to go back and add an extra span element in between the a and img elements, this will be a lot more work.
Unfortunately, most browsers do not support using :after or :before on img tags.
http://lildude.co.uk/after-css-property-for-img-tag
However, it IS possible for you to accomplish what you need with JavaScript/jQuery. Check out this fiddle:
http://jsfiddle.net/xixonia/ahnGT/
$(function() {
$('.target').after('<img src="..." />');
});
Edit:
For the reason why this isn't supported, check out coreyward's answer.
The before and after pseudo-selectors don't insert HTML elements — they insert text before or after the existing content of the targeted element. Because image elements don't contain text or have descendants, neither img:before or img:after will do you any good. This is also the case for elements like <br> and <hr> for the same reason.
I found a way to make this work in pure css:
The I'm just fake content-method
a pure CSS method to enable img:after.
You can check out the CodePen: I'm just fake content or see the source.
Source & Snippet
img {
/* hide the default image */
height:0;
width:0;
/* hide fake content */
font-size:0;
color:transparent;
/* enable absolute position for pseudo elements */
position:relative;
/* and this is just fake content */
content:"I'm just fake content";
}
/* initial absolute position */
img:before,
img:after {
position:absolute;
top:0;
left:0;
}
/* img:before - chrome & others */
img:before {
content:url(http://placekitten.com/g/250/250);
}
/* img:before - firefox */
body:not(:-moz-handler-blocked) img:before {
padding:125px;
background:url(http://placekitten.com/g/250/250) no-repeat;
}
/* img:after */
img:after {
/* width of img:before */
left:250px;
content:url(http://lorempixel.com/350/200/city/1);
}
<img
alt="You are watching the ~ I'm just fake content ~ method"
/>
Browser support
✓ Chrome 10+
✓ Firefox 11+
✓ Opera 9.8+
✓ Safari
No support
⊗ Internet Explorer 8 / 9
Please test in other browsers
Due to the nature of <img> being a replaced element, document styling doesn’t affected it.
To reference it anyway, <picture> provides an ideal, native wrapper that can have pseudo-elements attached to it, like so:
img::after,
picture::after{
content:"\1F63B";
font-size:larger;
margin:-1em;
}
<img src="//placekitten.com/110/80">
<picture>
<img src="//placekitten.com/110/80">
</picture>
Here's another solution using a div container for img while using :hover::after to achieve the effect.
The HTML as follows:
<div id=img_container><img src='' style='height:300px; width:300px;'></img></div>
The CSS as follows:
#img_container {
margin:0;
position:relative;
}
#img_container:hover::after {
content:'';
display:block;
position:absolute;
width:300px;
height:300px;
background:url('');
z-index:1;
top:0;
}
To see it in action, check out the fiddle I've created. Just so you know this is cross browser friendly and there's no need to trick the code with 'fake content'.
The pseudo-elements generated by ::before and ::after are contained by the element's formatting box, and thus don't apply to replaced elements such as img, or to br elements.
https://developer.mozilla.org/en-US/docs/Web/CSS/::after
I think the best way to look at why this doesn't work is that :before and :after insert their content before or after the content within the tag you're applying them to. So it works with divs or spans (or most other tags) because you can put content inside them.
<div>
:before
Content
:after
</div>
However, an img is a self-contained, self-closing tag, and since it has no separate closing tag, you can't put anything inside of it. (That would need to look like <img>Content</img>, but of course that doesn't work.)
I know this is an old topic, but it pops up first on Google, so hopefully this will help others learn.
This one works for me:
html
<ul>
<li> name here </li>
</ul>
CSS
ul li::before {
content: url(../images/check.png);
}
::after may be used to display the fallback image of an image
See the example below, first 2 img tags are point to the broken urls. But the second one displays the fallback image instead of the default broken logo from the browser. However, I'm not sure this's any practical, I find it kind of tricky to get it to work right.
img {
position: relative;
display: inline-block;
width: 300px;
height: 200px;
vertical-align: top;
}
img:not(:first-child)::after {
position: absolute;
left: 0; top: 0; right: 0; bottom: 0;
content: "<" attr(alt) "> NOT FOUND";
border: 1px dashed #999;
background: url(https://cdn.dribbble.com/users/1012566/screenshots/4187820/topic-2.jpg) center/100%;
}
<img src="https://source.unsplash.com/random/100/75" alt="logo">
<img src="https://source.unsplash.com/random/100/75" alt="logo">
<img src="https://source.unsplash.com/random/100x75" alt="logo">
In these cases it is preferable to use the <figure> tag, which allows you to manage the css in an optimal way
This way you can use after just on the figure
Example
<div class="exemple">
<figure>
<img src="img1.jpg"/>
</figure>
<figure>
<img src="img2.jpg"/>
</figure>
</div>
<img> is a replaced element and using :before or :after pseudo-elements on it works if the image fails to load and otherwise it does not work. If you intend to have a fallback in case of image load failure,please refer to https://stackoverflow.com/a/71478688/14204452
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
#image img{
display: inline-block;
max-width: 50%;
}
#image::after {
position: absolute;
top: 0;
content: url('https://img.icons8.com/plasticine/100/000000/about.png');
}
</style>
<title>img before</title>
</head>
<body>
<a id="image" href="">
<img src="https://static.remove.bg/remove-bg-web/5c20d2ecc9ddb1b6c85540a333ec65e2c616dbbd/assets/start-1abfb4fe2980eabfbbaaa4365a0692539f7cd2725f324f904565a9a744f8e214.jpg">
</a>
</body>
</html>
Try this code
.button:after {
content: ""
position: absolute
width: 70px
background-image: url('../../images/frontapp/mid-icon.svg')
display: inline-block
background-size: contain
background-repeat: no-repeat
right: 0
bottom: 0
}
I tried and found a simpler method to do so. Here is the HTML:
<img id="message_icon" src="messages2.png">
<p id="empty_para"></p>
What I did was place an empty <p> tag after my image tag. Now I will use p::before to show the image and position it according to my needs. Here is the CSS:
#empty_para
{
display:inline;
font-size:40;
background:orange;
border:2px solid red;
position:relative;
top:-400px;
left:100px;
}
#empty_para::before
{
content: url('messages.png');
}
Try it.
Try ::after on previous element.
Just give the Image "position: relative" and it will work

Disable overflow scrolling on webkit-based browsers

I'm using ::after to create shadow to decorate a element (say A).
In order to do this, I set the overflow: hidden for A to hide undesired part of the shadow.
It looks perfect, but there is a problem after I added a input box to A. If I click in the input and drag, the A layer will scroll, and the rest part of shadow will show up.
Here is the demo and the simplified code:
<div style="width: 200px; height: 30px; overflow: hidden; border: 1px black dotted;">
<div style="height: 30px; border-bottom: red 10px solid;">
<input style="width: 200px" placeholder="click and drag me downward" />
</div>
</div>
I'm looking for a pure CSS solution to fix this problem. Thanks ahead.
This isn't an ideal solution, but I don't think a pure CSS solution exists to this problem (unfortunately), it makes me wonder whether this has been logged as a bug with the Chrome team.
jQuery should be as follows:
$('input').on('mousedown', function(e){
$(e.target).focus();
e.preventDefault();
});
(I know I shouldn't assume you're using jQuery, if needed I can provide you a pure JS solution, it'll just be more complicated).
Fiddle: http://jsfiddle.net/jzb5a/
EDIT: Apparently this is a known bug (https://bugs.webkit.org/show_bug.cgi?id=114384) it's dissapointing that four months on there still hasn't been a fix though.
Finally come to an solution, which is not that perfect but fixed the problem anyway.
As the background overflows, and the input on the same layer would cause the problem. So just move the input to another layer which doesn't overflow. demo
<div style="position: relative; width: 200px; height: 30px; border: 1px black dotted;">
<div style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; z-index: -1; overflow: hidden;">
<div style="height: 30px; border-bottom: red 10px solid;"></div>
</div>
<input style="width: 160px" placeholder="click and drag me downward" />
</div>

How to create a div filling the vertical available space without overlapping the containing div?

I'm working on a layout with a container (div), inside the container there are two elements, a div for the header and another div for the content.
The header div has a fixed height, the div for the content must fill the available space.
The container div has own style and cannot be overlapped.
My goal is to create simple div based elements to dispose simple widgets on a web page.
I checked the other similar questions like:
How to make a div expand to fit available vertical space?
Force to fill all available vertical space
Add a DIV that takes up all available vertical space
But none of this solutions applies to me.
I managed to get this html/css:
<?xml version="1.0"?>
<html>
<head>
<style type="text/css">
.workbench {
width: 100%;
height: 100%;
background: white;
}
.widget {
width: 100px;
height: 500px;
position: absolute;
top: 50px;
left: 50px;
border: solid 1px black;
margin: 2px;
}
.widget-header {
height: 50px;
border: solid 1px red;
margin: 2px;
}
.widget-body {
position: absolute;
top: 50px;
bottom: 0px;
left: 0px;
right: 0px;
border: solid 1px blue;
overflow: hidden;
margin: 2px;
}
</style>
</head>
<body>
<div id="workbench" class="workbench">
<div id="widget" class="widget">
<div id="widget-header" class="widget-header">
Header
</div>
<div id="widget-body" class="widget-body">
Body
</div>
</div>
</div>
</body>
</html>
This is working like a charm on FireFox and Chrome, but doesn't work on Internet Explorer 8:
Can you help me?
realizing you're not aiming at the IE5.5 / IE6 market, and by your descriptions (renders fine on jsFiddle, while not from a file), the issue seem to originate from the absence of a doctype declaration.
in order for the document to render correctly you must specify a doctype, to deny the browser from falling to quirksmode. your document seem to conform to a valid XHTML convention, therefore you can use the XHTML transitional doctype to instruct IE8 to render in standards mode, or use the HTML5 doctype (along with an HTML5 shim/shiv, if you'll be using HTML5's semantics as well).
just for convenience, the XHTML transitional doctype declaration:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
note: Modernizr contains an HTML5 shiv of its own, and is recommended regardless to ease up the development.
here's the jsFiddle for you to mess around with
As you have a height on the widget of 500px and the widget header is 50px; why not just make the widget-body 450px; (also subtracting any additional margin and padding) and make the whidget-header and widget-body relative positioning.
jquery can help with this.
$('.workbench').each(function(){
var total=$(this).height();
var headerHeight=$(this).find('.widget-header').height();
$(this).find('.widget-body').height(total-headerHeight);
});

Overlay transparent image on hover using CSS

I'm trying to overlay a transparent image on hover using CSS.
There is an answer here but it doesn't work in IE7 or IE8. Would anyone know how to do this?
I'm trying to keep super-light so don't really want to use js or anything similar.
Thanks
I checked your link and came up with this solution based on that.
HTML:
<div class="image">
<img src="xy.jpg" alt="" />
<img class="hoverimage" src="xy_hover.jpg" alt="" />
</div>
CSS:
.image { position: relative; width: 184px; height: 219px; }
.hoverimage { position: absolute; top: 0; left: 0; display: none; }
.image:hover .hoverimage { display: block; }
Should work in all browsers including IE8 and IE7. It won't work in IE6 because it only allows :hover on certain elements like links (<a>). If you want to support IE6, change .image to be an <a> instead of a <div> and give it display: block;.
This still doesn't work on IE7/8 AFAIK, so I'm afraid this won't answer the question.
However, I have ended up on this page when I forget how to make this work using modern methods, so I'm placing the answer here for reference.
I've only been able to do this by placing the img within a container/wrapper div, as img elements won't accept psuedo-classes like :after.
<div class="container"><img src="http://placekitten.com/240/320" alt="icanhaz"></div>
Then the CSS is styled to provide a pseudo element on hover.
.container {
position: relative;
}
.container:hover:after {
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5); /* Here you may also use images, gradients, etc */
}
See the example here
Usually we recreate the image that is supposed to have a transparent overlay in the .png format. .Jpeg is a flat image format which doesn't support transparency.
the next step we take is to have something like this :
<div style="Background-Image:Url(BackgroundImage.Jpg);Width:500px;Height:500px" >
<div style="Background-Image:Url(OverlayImage.Png);Width:50%;Height:50%" >
...
</div>
</div>
This is the closest to how I could understand your question

Position <div> on top

I have an area on a page that uses with overflow. In side that div a have content with a few links and a few hidden divs. When a link is clicked, a hidden div is shown. In FF the div appears like intended: above everything else, in IE, however it appears above the content inside the div with overflow, but not above the overflow. How can I fix that?
Here's an example of my code:
<style>
.hiddenDiv {
position:absolute;
zIndex:9999;
width:300px;
height:250px;
background:#fff;
border:1px solid #ccc;
}
</style>
<div style="overflow-y: auto; border: 1px solid #ccc; height: 200px; width: 300px">
some content here
<div class="hiddenDiv" style="display:none">more content here</div>
</div>
i think this is some sort of IE specific issue.
This means your page is rendered in quirks mode..
Do you have a doctype declared in your page ?
example that works fine unless IE is put in quirks mode (then it exhibits the behavior you describe): http://www.jsfiddle.net/UtKYn/1/
Use:
* { zoom: 1; }
Though it's not advised to use the * selector, so try to narrow it down a little.
Also, consider z-index
try to add
margin: 0px;
padding: 0px;
above code for the div that is indented.

Resources