|Help with div border|
I want to see if I can have space between border and actual div dimensions
I'm trying to do something I see but can't seem to recreate.
I want to put a dashed border on a <div>. Dashed, dotted, solid, etc. doesn't really matter, I can handle that. What I want to do is have some space between the actual div dimensions and where the border is displayed.
With your basic CSS statement:
border: 2px dashed #2D72C2;
I get what you expect, a 2px, blue, dashed border at the very edge of the <div>.
What I want is some separation between the actual <div> dimensions and where the borer is displayed. The best way I can describe is if I had a <div> with the dimensions of 100px 100px 100px 100px with white background, and the above border statement I will get a border of the exact same dimensions around the <div>. What I want is for the border to actually display, centered, with dimensions something like 90px 90 px 90px 90px so that there is padding or space making the border be inside the <div> with a 10px space between <div> dimensions and border.
Is this possible with a property or do I need to create 2 separate <div> with the internal and slightly smaller one having the border?
Add a 'padding' setting to the DIV.
|Add a 'padding' setting to the DIV. |
That was my first thought, but if I'm reading the text right, I think he does need two nested divs.
From inside to outside the sequence goes: content, padding, border, margin. Any visible border is outside the padding (which shares the element's background) and inside the margin (which uses the background of whatever the containing element is).
:: shuffling papers ::
(intentionally de-linked so you can go straight to the picture).
Did you mean something like this?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
border: 2px dashed #2D72C2;
<div class="test">IE8+ (+ other modern browsers) only</div>
Paul_o_b, thanks. That appears to work. I get a red box - <div> - with a dashed blue line offset and 'inside' the red box. But I have to admit to my ignorance, I don't know how/why it works. I'm looking at the code and I can see in the body that you declare only the 'test' <div>. I guess this has to do with my limited knowledge of CSS, but how does the 'div:after' become part of the document?
What type of declaration is the 'div:after'? How does it become included/used in the 'test' <div>?
I think it's better to write .test:after instead of div:after . The first will add a pseudo element after any element that has a class of test, the latter will do it after every div in your document.
After is explained best in CSS2: http://www.w3.org/TR/CSS2/selector.html#before-and-after
swa66, okay, reading up on it but it looks like - in the above example - that using the attribute 'content:" ";' in the 'div:after' is so arbitrary. I can't guarantee what the content may be in the <div>'s I want it to apply to. They all wont have the same content. Am I missing something?
Hm, interesting approach. How far back does it work reliably? That is, ahem, how many MSIE versions? It works as intended in Camino-- which presumably means any Firefox that any human will ever use-- and in SEE preview, meaning any webkit should be OK. If I had half an hour to spare I'd try it in Opera. WHY does it take so long to load up? 12 and 15 are exactly the same in this respect.
smather, it's fairly straightforward once you spend a few minutes poring over the code. The secret is that "after" doesn't have to mean physically after (i.e. to the right in an ltr language). But because it's attached to the div, "position:absolute;" means "pretend that your div is now the entire universe". So "left: 15px" means "15 pix to the left of-- i.e. inside-- the container's left edge" and similarly for everything else.
Yup, it's a trick. The ostensible content
content = " ";
is just a placeholder to force the dashed border to display; it has nothing to do with the text content of the div itself. That's why he included the IE8 blahblah in the html: to show that the div's "real" content is unaffected.
If you leave out the "content" line, the border disappears too. It may or may not work with
content = "";
I don't understand why the main div requires "position: relative" (a declaration I normally wouldn't touch with a barge pole ;)), though I see by experiment that it's essential. Well, "absolute" might work too.
Now, whether this comes out cleaner and tidier in practice than nesting divs is a whole nother issue...
lucy24/all, thanks for your patience. Okay, part of the problem I'm having to deal with is that I'm not in complete control of the code. I'm working with a third party product that allows me to append or replace CSS statements into their CSS templates by creating what they call is a CSS Hook (that is immaterial). Now, the product is great and it's not their issue but mine in completely understanding.
So, in this instance, I'm 'appending' to a div class they have called .sg-content. In the example code that we've been working off of the declaration is:
Now, with example code like:
For example, the following rules insert an open quote mark before every Q element. The color of the quote mark will be red, but the font will be the same as the font of the rest of the Q element:
This example is obvious to me, but in the example in the post above we are referencing it's the 'div' part of div:after that is throwing me. To me, that implies that any <div> in the body will have the div:after properties assigned to it.
How do I specify which <div> I want my :after properties to apply to? Or, am I still way off the mark?
|To me, that implies that any <div> in the body will have the div:after properties assigned to it. |
Yes, that's right. He just did it that way for demo purposes. As swa66 said,
|I think it's better to write .test:after instead of div:after . The first will add a pseudo element after any element that has a class of test, the latter will do it after every div in your document. |
What you need to do is take the test code-- the part that currently says
and change it to either
replacing "test" with the name of the actual div.
If you expand the sample to this
border: 1px dotted blue;
border: 2px dashed #2D72C2;
<div class="foobar">IE8+ (+ other modern browsers) only</div>
<div class="test foobar">IE8+ (+ other modern browsers) only</div>
you'll get a better sense of what's happening where.
The part I'm having trouble with is: How do you get it to work with a div that is not relatively (or absolutely) positioned?
Apologies the div:after should have said .test:after.
I originally just used div as a selector for the styles as there was only one div in the example then thought I better use a class in case someone gets confused but forgot to change the div:after to .test:after :blush:
I already gave browser support in the demo and it is IE8+ and all other modern browsers (basically not supported in IE7 and under).
:after places generated content after the content in that element (not after the element). It goes hand in hand with the 'content' property which actually places the generated content into the html.
The quotes can be empty or contain a space - it doesn't really matter these days. What the content property does is place a pseudo box in the html that you can then style as you like. Without the content property there is nothing to style and without content in the 'content' property the box is empty and can be used for decoration. In fact :after is perfect for decoration as you should never insert important information via the content property.
The position:relative on the div container is imperative as it creates the stacking context for the now absolutely placed content that was inserted into the html. By using top, bottom, left and right co-ordinates the element maintains complete integrity with the parent div and will expand and contract as required should the div size be fluid or the height changed.
There is no need to nest another element (unless you want to support IE7 and under) and using :after for decoration continues the separation of structure from presentation goals, rather than polluting the mark up with unwanted html.
Using :before and :after are perfect tools for adding decorations to elements when the need arises and that you don;t need to support older browsers. The fact that Ie6 and 7 don't get a border is no loss to the usefulness of the page and falls into the graceful degradation category.
Apologies once again for my initial confusing code as the rule should have said .test:after (although it would still have worked form my example as there was only one div).
|The position:relative on the div container is imperative |
That's what I was afraid of. I agree that :before and :after are ideal for decoration (or, if you prefer, Added Value). Well, I'd ### well better agree, since I use it for that purpose myself! But requiring the element itself to have position:relative or :absolute is a pretty overwhelming limitation. Might work with a header or other navigation feature, but not with an ordinary normal-flow box.
|I already gave browser support in the demo |
Yup, my bad, looked right at it and it didn't sink in. (Although in fairness it could have meant "I use 8 so I don't know if it will work with earlier versions".)
there's ton in there that IE7 doesn't do properly (like setting both top and bottom on the same element. It's the usual case of IE legacy brain-dead design; the :after pseudo element, ...)
But IE7 is really starting to die out thanks to some big players deprecating their support for it.
Now if we can get rid of IE8 ...
The "test" class needing position relative is normal for absolute positioning to work. (absolute positioning works relative to the closest parent that has "positioning") . For the :after pseudo element that means the element itself.
But the good thing once you get rid of legacy IE versions is that position:relative doesn't do a thing. unless there's top/bottom/left/right on the element itself.
There's nothing wrong with adding position:relative to an element and even in IE7 and under its hardly a big issue (as long as the element has haslayout). Indeed position:relative triggers a better layout algorithm and will indeed fix some of the haslayout bugs as a bonus. However for position:relative to work properly in IE7 and under the element must be in haslayout mode.
The only issue with position:relative is that in IE7 and under they automatically apply a z-index of zero to positioned elements when in fact they should apply the value auto (which Ie7- doesn't actually understand).
If the element has an auto z-index then its stacking context is not 'atomic' which means that positioned children can react to the z-index of elements outside this current context. However once you apply z-index:0 to the parent then all children are trapped within the z-index of the parent and although they can react with each other then can never escape the parent or get behind the parent's background.
This is the only problem with adding position:relative to a container in IE7 and under (as long as the element has a layout). In all other browsers it will make no difference whatsoever apart from its intended use.
As I stated above the demo is only IE8+ because IE7 and under don't understand :after and also don't understand how to position using all 4 co-ordinates at the same time. For an effect such as a border that's a small price to pay for neater code :)
All, while I still haven't gotten the desired results using the third party CSS template logic - I will - all of this does work on my test pages and had given me a much greater understanding of how to use :before and :after.
You guys are great.
|could you please try with padding:10px; and try to include div's width in % like|
border:2px dashed #f1f1f1;