Pure CSS3 for overlapping <div> elements with border radius - css

I have a varying number of <div>s inside a container <div>, that are each set to display:inline-block, have a -webkit-border-radius and some padding. I would like to position each of the <div>s in a way that the one to the right overlaps the one to the left enough, so that there is no break in the border on top and bottom. Also, Ideally the container <div> would only have a width that is exactly the size of the styled divs inside (hight of LAST_DIV and width equal to the distance from the leftmost to the rightmost div).
----------------
--------------------/ \
/ / | |
| DIV_1 | DIV_2 | LAST_DIV |
\ \ | |
------------------- \ /
----------------
Since the number of <div>s that will display varies, I ruled out absolute positioning. I would like to refrain from javascript or adding additional elements to the html document, since I am creating multiple styles for the same website element, and some of those styles might not have rounded <div>s that have to overlap.
Edit:
I have tried setting only a border radius to the left edge of the inner divs and giving the container div a border on top and bottom and setting a negative value for left until the overlapping border of the container div disappears. When all divs are the same hight, this gave me issues at the right end, since the container div now extended over the right end. This also gave me issues when the individual divs had different colors.

You could try it something like this:
demo
HTML:
<div class='container'>
<div>DIV_1</div><!--
--><div>DIV_2</div><!--
--><div>LAST_DIV</div>
</div>
Relevant CSS:
.container, .container div { display: inline-block; }
.container div {
padding: .25em 1.25em;
border-radius: .65em 0 0 .65em;
}
.container div:not(:first-child) {
margin: 0 0 0 -.65em; /* negative left margin, same value as border-radius */
}
.container div:last-child {
padding: 1.25em;
border-radius: .65em;
}
Note
Any kind of whitespace (space, tab, newline) between elements that have display: inline-block; set on them matters. This mean that a newline in the HTML between the divs in the container will introduce a space between them. There are a few fixes for this. The one I've chosen involves adding a comment between </div> (closing tag of a child div) and <div> (opening tag of the following div).

Related

Min-height and margin

Consider the following HTML:
.top {
min-height: 150px;
}
p {
margin: 50px;
}
div {
background-color: #eee;
}
<div class="top">
<p>Welcome</p>
</div>
<div class="content">Main content</div>
You can see it in action here:
http://jsfiddle.net/Lp4tp/1
Question
In Chrome(for Ubuntu), it appears that the margin defined on the p tag causes spacing between the top div and it's surrounding elements, instead of expanding the top div and producing the equivalent of adding 50 pixels padding on the top div.
Is this correct behavior? And if so, how can I ensure that child elements inside the top div cannot create undesired space between the top div and the content div.
Note
If I use a fixed height instead of a minimum height, the spacing between the top and the content div vanishes, but the top still produces 50 pixels of white space above itself.
Your margins collapse. Fix with overflow:auto on the div:
div {
background-color: #eee;
overflow:auto;
}
jsFiddle example
Top and bottom margins of blocks are sometimes combined (collapsed)
into a single margin whose size is the largest of the margins combined
into it, a behavior known as margin collapsing.
You could also add a border to the div for the same result.
add to p
display:inline-block;

Unwanted Space in div tags

I have two div id's. One has has an image in it and the other has a background image. There is an unwanted space in between these two divs. In the dreamweaver design view it appears as if there is no space, but if I make it live or preview in browser the space appears again.
This is the css for the divs
#header {
text-align: center;
padding: 0px;
margin: 0px;
}
#content {
background-image:url(img/ContentBox.png);
background-repeat: no-repeat;
background-position:center;
padding: 0;
margin: 0;
}
This is my body html (ignore the multiple line breaks, this is just so I can see the bg img in the div)
<body>
<div id="header"><img src="img/Header.jpg" /></div>
<div id="content"><br><br><br><br><br><br><br></div>
</body>
Images have a default display setting of inline. This causes them to flow inline with text, vertically-aligned with the baseline. All text is vertically-aligned with the baseline by default as well, unless you change it by setting vertical-align to something else on its containing element.
What is baseline?
The baseline floats above the bottom of the actual line. Look at the lower-case letter g. The bottom of the top circle is the baseline. That's where the images are getting aligned.
You can solve this multiple ways, but here are a couple:
Vertical Alignment
Again, image elements are set to display: inline by default. Assuming you don't want to change this, you need to adjust how the image element aligns vertically on the current line of text.
The vertical-align CSS property sets the vertical alignment of an inline element on the current line of text. It doesn't set it relative to the container.
Therefore, you can set the vertical-align property to middle, top, or bottom, and as long as the image element is larger than the line-height of the current line of text, it will not have the extra space below it.
However, you need to remember what I just said about line-height. In the event that your line-height is larger than your image element, vertical-align will do more than remove that extra spacing: it will actually align the image element on the line accordingly. See this jsFiddle to see an example of how a line-height greater than the height of the image will affect the result.
So, keeping with the HTML that you provided, to set the vertical alignment, you'd do the following CSS rule:
#header img {
vertical-align: bottom; /* or top or middle */
}
Displaying as Block Level
Another option would be to change the image element to display as a block level element. I don't recommend this approach unless you know you want a block level image.
Block level elements automatically fill to their container, and don't flow inline with text or other inline elements. Also, if you set a float on the image, this would force it to be block level.
So, you have two options to display as block level:
#header img {
display: block;
}
or
#header img {
float: left; /* You could float right too */
}

CSS 2.1 spec: 8.3.1 Collapsing margins: cannot properly interpret special case: clarification sought

Section 8.3.1 of the CSS 2.1 spec on collapsing margins states:
If the top and bottom margins of an element with clearance are
adjoining, its margins collapse with the adjoining margins of
following siblings but that resulting margin does not collapse with
the bottom margin of the parent block.
Here is my, surely erratic, attempt at making something out of this statement:
The statement considers an element X for which:
X has clearance, therefore either of the "clear: left;", "clear: right;"
or "clear: both;" properties have been applied to it.
Since the top AND bottom margins of X are adjoining,
in the case of a normal flow we are considering the scenario where:
X has one parent above and one sibling below, or
X has one sibling above and one sibling below, or
X has one sibling above and one parent below
Then the spec says, "its margins collapse with the adjoining margins
of following siblings", but there can be at most one following sibling,
as pointed out above, so this essentially must mean that if there is a
sibling following then the margin collapses.
"but that resulting margin does not collapse with the bottom margin
of the parent block." - I don't understand this: if the bottom margin
is adjacent to a sibling's top margin then it cannot be adjacent to
the parent block's bottom margin unless the sibling's height is zero.
I'm utterly confused. Can someone please explain this statement in a better way, perhaps with a few illustrative examples?
First, a couple of clarifications:
An element with clearance is one which has clear set to something other than none and is actually clearing a float.
An element whose top and bottom margin are adjoining means adjoining with each other, not with siblings. We're talking about a 0 height element without border or padding, so the top margin and bottom margin of the element are touching each other. When this happens, they collapse with together, a situation known as collapsing through.
Now, let's look at an example:
body {
border:solid;
}
#container {
margin: 20px;
background: blue;
}
#floated {
float: left;
width: 20px;
height: 20px;
background: red;
}
#cleared {
clear: left;
margin-top: 10px;
margin-bottom: 20px;
}
#following {
margin-top: 30px;
}
<body>
<div id=container>
<div id=floated></div>
<div id=cleared></div>
<div id=following></div>
<div>
</body>
Play with it here: http://jsbin.com/wuvilu/1/edit?html,css,output
Since there is a border on the body, you can see the 20px margin around the blue #container. The red #floated is also an obvious 20px by 20px.
Then, since it is 0 height with no padding and no border, the top and bottom margin of the #cleared collapse with each other. They are also adjoining with the top margin of the #following. The size of this collapsed margin is 30px, the largest of the three.
Since the #following is 0 height and has no padding and no border, our 30px margin is adjoining with the bottom margin of the #container, and would collapse with it. Except now the rule you have quoted kicks in, and it doesn't.
Since it won't collapse with the bottom margin of the container, it has to be placed somewhere within it. Where? It starts from 10px above the bottom edge of #floater, and extends 20px below. Why? The top margin of #cleared is the top-most margin that participates in this collapse margin, so we start where it would start. Since it is 10px, our collapsed margin starts 10px above the bottom edge of #floater, the element immediately before it.
Yes, this is insane, and most scenarios that involve collapsing through are insane. Collapsing through was a terrible idea, and it should never have made it into CSS, but it did before people knew better, and now we have to deal with it, and all the crazy consequences.

Floating element dissapears behind background when container has position:relative

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.

Align floated divs to fill an entire space

So I have a div, 720px wide, and i'm filling it with divs that are 140px wide, floated left. I would love to be able to line these divs up flush with the left and right edges of the containing div.
Of course, the issue is that when I put a margin-right on the floated divs, the right edge won't line up due to that margin. A left margin yields the same results, but on the left edge.
Is there any way to combat this issue?
Try this: Link
You can put the elements into rows and detect first, middle, and last elements with these css2 selectors. You can specify different margins for the different positions inside.
element:first-child {
}
element:last-child {
}
element .className {
margin-left: 6px;
}
If you are using a server-side language to generate these divs you can calculate which item is last in the row by doing something like this:
<div class="column <%if iteration % 6 == 0 %>last-in-row<%end%>"></div>
and then just set the style
.column {
margin-right: 10px;
}
.last-in-row {
margin-right: 0;
}

Resources