I am trying to set up a form that displays a vertical separator between two elements that appear side by side. These are the problem parameters:
The height of either element is unknown and will change by virtue of the contents being modified with JavaScript in response to user interaction.
The separator should cover the whole of the elements' shared vertical border, irrespective of which element happens to be taller at any given time.
Given the above it seems that this setup will do the trick:
<div>This is some text on top.</div>
<ol>
<li id="a">Lalalala</li>
<li id="b">Lololol</li>
</ol>
<div>And some text on the bottom.</div>
CSS
ol { overflow: hidden }
li { float: left; width: 5em; padding: 4px }
div { clear: both }
#a { background: gold; min-height: 100px }
#b { background: yellow; border-left: 1px black dotted }
#b { padding-bottom: 400px; margin-bottom: -400px } /* "infinitely" tall */
The idea is that the second element becomes "infinitely tall" by applying bottom padding and gets a left border; elements following the group are brought back into their original position by counteracting the padding with negative bottom margin; and the "unused" portion of the vertical border is hidden by giving the parent overflow: hidden.
This setup indeed works correctly (JsFiddle) on Firefox, Chrome and IE >=8 (my compatibility requirements):
However, when I try to apply the same technique in my real HTML Firefox breaks down and seems to not honor the overflow: hidden set on the parent element. As a result the infinitely tall vertical border bleeds through all elements following the two panels on the page.
Here is a JSFiddle of (simplified) real copy/pasted content together with my actual CSS rules that shows the problem. Note that only Firefox mishandles this; other browsers continue to display it properly.
Correct render:
Firefox render:
I am properly stumped: why would Firefox display the proof of concept correctly and botch the real deal? And how can I fix it?
I was able to fix your JSFiddle by changing the fieldset element to a div or by surrounding the fieldset with a div that had overflow set to hidden. Maybe worth a try. Is the fieldset tag essential to your HTML?
Related
I have an anchor tag, and I'm using the :before selector to add some text. I have added a hover state around the anchor tag. The :before text is slightly larger than the rest of the text in the anchor tag and I'm adding a display: inline-block property to the before text.
When I hover over the anchor tag, the hover state is wrapped tightly around the all the anchor text, including the :before text (EXAMPLE 1 in codepen). Like so:
https://user-images.githubusercontent.com/20184809/52691191-27364e80-2fb4-11e9-9ffe-8777e645acee.png
How ever if I add the display:inline-block property to the anchor tag the hover state is a rectangle which matches the height of the larger :before text. Like so:
https://user-images.githubusercontent.com/20184809/52691272-7da38d00-2fb4-11e9-900b-c795623de3e2.png
Why is this?
.link-1:hover, .link-2:hover {
outline: 3px solid green;
outline-offset: 2px;
}
.link:before {
content:':before text';
font-size: 35px;
display: inline-block;
}
.link-1 {
display: inline-block;
}
<!-- EXAMPLE 2 -->
anchor text
<br>
<!-- EXAMPLE 1 -->
anchor text
EDIT:
I've noticed this happens on Chrome and not Safari and firefox. It could be a browser thing?
From the specification we can read:
Outlines may be non-rectangular. For example, if the element is broken across several lines, the outline is the minimum outline that encloses all the element's boxes. In contrast to borders, the outline is not open at the line box's end or start, but is always fully connected if possible.
And
The outline may be drawn starting just outside the border edge.
For the second example, when making the element inline-block we will have the below
.link-1:hover, .link-2:hover {
outline: 3px solid green;
outline-offset: 2px;
}
.link:before {
content:':before text';
font-size: 35px;
display: inline-block;
}
.link-1 {
display: inline-block;
border:1px solid;
}
anchor text
It's clear that the outline need to at least surround the border and it will be the same for all the browser.
But for the first example we will have this:
.link-1:hover, .link-2:hover {
outline: 3px solid green;
outline-offset: 2px;
}
.link:before {
content:':before text';
font-size: 35px;
display: inline-block;
}
.link,
.link:before{
border:1px solid;
}
<!-- EXAMPLE 2 -->
anchor text
It seems that Chrome in this case is following the borders to draw the outline and is respecting the Specification by keeping it connected. The result is somehow logical but other browser aren't doing the same. I won't say if Firefox is doing wrong but both result are fine and doesn't violate the specification.
In both cases we have :
The minimum outline that encloses all the element's boxes
Always fully connected if possible
May be drawn starting just outside the border edge
There are two types of HTML elements. Inline and Block elements. Block elements take up the full width available to them(With exception of inline blocks, will come back to these). Inline elements only take up as much space as they need, i.e they try to be as small as possible. So just the space around their outer border. When you add display: inline-block you turn the whole thing into a block which is why it becomes rectangular. The difference with inline-blocks is that they also take up as much space as they need but they are also fully rectangular. Check out this answer too CSS display: inline vs inline-block
Something strange is happening with a margin setting in Firefox, I have a div with an id "wrap" with a top margin of 20px, when a user is logged in a div appears above the wrap div with an id of user_nav I don't want any margin above this div, but Firefox is for some unknown reaslon propagating the top margin I have on the wrap div to the user_nav div above it, it isn't happening in any other browsers.
If I remove the top margin from the wrap div it is removed from both.
I can get rid of it by giving the user_nav div a negative top margin, but that messes up all the other browsers.
div#user_nav {
width: 980px;
margin: 0 auto;
}
div#wrap {
width: 980px;
margin: 20px auto 30px auto;
}
Any ideas about what is happening?
Thanks
Rob Fenwick
It is indeed quirky behaviour - and it appears to be one of the effects of this old bug related to clearing block elements (or one of its many, many duplicates):
https://bugzilla.mozilla.org/show_bug.cgi?id=451791
One way to get around it is getting rid of the <div class="clear"> and using the overflow method of clearing instead (though that's not always possible, e.g. - obviously - if you have content inside the cleared element that will extend outside it):
http://www.quirksmode.org/css/clearing.html
I.e., remove <div class="clear"> from inside user_nav_frame and apply overflow: hidden (and width: 100%) to it in the CSS instead to clear the floats:
div#user_nav_frame {
background-color: #0A4D84;
overflow: hidden;
width: 100%;
}
JSFiddle: http://jsfiddle.net/69aD9/2/
There are counter-hacks too, if this won't work out in your case. See the above bug report.
The Margin Issue
I am working with extra large block elements (2000-4000px for both width and height) and most of these elements overflow the window/viewport. That is fine and is the intended effect of my application. However, when I apply margin to the element on all sides, say 40px, it is applied only to the top, left, and bottom sides. The far right edge is flush with the edge of the window after scrolling over. I am looking to have an even margin on all sides of the block element.
The Code
See below or view this jsFiddle of a reduced test case.
<!-- HTML -->
<div></div>
/* CSS */
* {
margin: 0;
padding: 0;
}
div {
background: #000;
height: 3000px;
margin: 40px;
width: 3000px;
}
What I Have Tried
I have tried the above method, which I initially assumed would work, but it didn't. I have also tried applying a padding of 40px to the body element, and removing the margin from the div altogether, but got the same result. The same was true for a containing element with padding applied.
Any help would be greatly appreciated. Thanks!
How about making your div an inline-block element.
Add display:inline-block to your div and that should solve the issue.
See the updated fiddle- DEMO
I have boiled down my problem to a pretty simple single file with the CSS included in a <style> tag.
The problem is:
I have a floating right column with a transparent background to show some text and pictures. This works fine, as expected.
Now I want to position a "Site designed by.... " block just above the footer.
I want to use an absolute positioned div for this, which is positioned relative to the containing #content div, which must get the position:relative property to achieve this.
When I set this property, the floating right column disappears, and seems to be hidden behind the background image of the #content block.
I cannot find an explanation for this. A workaround would be to position it relative to the footer (in that case the #footer div would get the position:relative property).
But I just would like to understand what goes wrong here and why the floating column is hidden. See the links for the layouts without and with the relative positioned content div.
Understandably, in the case of no relative positioning, the text is positioned relative to the browser in the bottom left corner.
http://websites.drsklaus.nl/relativeproblem/index_withoutrelative.html
http://websites.drsklaus.nl/relativeproblem/index_withrelative.html
You were almost there! Heres a little help to finish it.
#main {
width: 1005px;
margin: 20px auto; /* shorthand margin for x and y axis */
border: solid black 1px;
/* Added background to main instead so it still covers the full background */
background-image: url('grey-repeating-background-4.jpg');
}
#content {
position: relative;
min-height: 500px;
/* made the padding here margin, made it slightly bigger to accomedate the right column */
margin: 5px 370px 5px 5px; /* Margin right should be as wide as the right column+extra space */
}
The reason for your right column to hide behind the content is that before you put position:relative; on it it is in normal flow, not 'positioned' and so z-index priority is really just by DOM order. Positioning it just made it a whole lot more important; obscuring the right column.
The site is appearing fine in Mozilla, Chrome, and IE6. But IE7 onwards, the menu background image was not appearing at all.
In the file moo.menu.css, I made the following changes in li:
.ry-cssmnu ul li {
margin: 0; /* all list items */
padding: 0;
float: left;
display: block;
background: url(../images/mainnav-bg.gif) repeat-x center top blue;/*added this line*/
cursor: pointer;}
After this, the background repeat is appearing only where the menu text is present.
http://bit.ly/ie8issue
The site is at: www.agmrcet.com/cons
Thanks in advance.
You have to declare a height to that container. Your floating list items are not giving their parent container height because float removes them from the document flow. Your <ul> has a current height of nothing, and the background image won't remedy that.
#mainnav { height:44px; ... }
First of all, I would change the CSS background property according to the CSS syntax:
background: blue url(../images/mainnav-bg.gif) repeat-x center top;
Looks like the problem is with your
<div class="clearfix" id="mainnav">
tag. Have you tried adding a pink border or something (to debug it) to the mainnav element and then setting a fixed width on it to make sure it goes the full width?