Solved

Add Border to Element Without Effecting Element Size

Posted on 2008-06-13
22
1,562 Views
Last Modified: 2013-11-19
I am trying to add a border to an element using javascript without affecting the size of the element. Simply adding a 1px border adds 2px to both the width and height of the element causing other elements that are relatively positioned to the affected element to move around.

Is there any simple way with CSS to apply a border without affecting the size of the element? I have tried subtracting 2px from the width and height of the element as well as both negative and positive margins and paddings but they all seem to effect the size of the element in some way and I can't get it to remain constant as the new border is added.

I have also tried adding a new element and positioning it on top of the original element so that the border appears visually but is not actually on the original element. This works well but causes any content inside the original element to be hidden behind the new div so that it cannot be select (although it is still visible as the new div has no background-color).

I have tried playing with the z-index of both the original element and the new one on top of it but couldn't get that to work well.

Can anybody think of a way that this might be achieved without effecting the current elements on the page?
0
Comment
Question by:jfredrickson
  • 11
  • 7
  • 4
22 Comments
 
LVL 10

Expert Comment

by:bluefezteam
ID: 21781580
if you have a div which is 100px x 100px with no border, and add a border then it becomes 102px x102px

So you apply a border and deducated 2px from the objects width and height.

according to what you right above you have tried it - but that is how it's done, I've done it loads of times.

You could try applying display:block; to the element see if that fixes the method
0
 
LVL 4

Author Comment

by:jfredrickson
ID: 21781760
What method do you use to subtract 2px from the height and the width? I am using the following:

element.style.border = "1px solid red";
element.style.width = (element.offsetWidth-2)+"px";
element.style.height = (element.offsetHeight-2)+"px";

When I look closely at it though it doesn't seem to be doing anything at all. Perhaps this isn't the appropriate way to change the height and width?
0
 
LVL 4

Author Comment

by:jfredrickson
ID: 21781773
The main issue comes when two elements are floated next to each other. When the border is added to the first element the second one no longer has enough room to float next to it and gets forced to the next line. This is still happening using the above method.
0
 
LVL 10

Expert Comment

by:bluefezteam
ID: 21781921
that's crazy.

if you have enough room for 200px across a line and both boxes add up to a combined width of 200px then it will fit, by swapping 2px border and reduceing the width of the div by 2px amounts to the same thing. Are you sure the javascript isn't applying a whitespace element? this may give it a 'space' and cause the wrap...

Method for change I'd use is :

d = document.getElementById('THE-NAME-OF-THE-DIV');
d.style.width="98px"; // WAS 100PX
d.style.height="98px"; // WAS 100PX
d.style.border="solid black 1px";
0
 
LVL 4

Author Comment

by:jfredrickson
ID: 21781970
Isn't that exactly what I had except that I am getting the height and width dynamically from the element? Since I don't know which element this will be used on it needs to be dynamic. Is that the correct way to do it?

What do you mean by the javascript applying a whitespace element?
0
 
LVL 10

Expert Comment

by:bluefezteam
ID: 21782282
If i write out html and include a whitespace (a line brean, space or similar) it can cause gaps that apply extra space around items, eg

---------------------------------------------------
<img src="1.jpg" /> <img src="2.jpg" />
---------------------------------------------------
<img src="1.jpg" />
<img src="1.jpg" />
---------------------------------------------------
<img src="1.jpg" /><img src="2.jpg" /> <<< here theres no gap between elements so when set to 100px each they are exactly 200px - with accidental spacing they may become 205px and that wont fit causing a wrap.

have you tried performing an ALERT() to see what values you are receiving when running this (element.offsetWidth-2)+"px";

any chance you can upload a link to what you have so far.
0
 
LVL 4

Author Comment

by:jfredrickson
ID: 21782341
Here's the script being tested on a random cnet article:

http://purusstudios.com/files/tmp/random_cnet_article.html

As you can see adding the border to the moused-over element causes things to jump around quite a bit.

I've been outputting the before and after height and width to my Firebug console and it seems that it is able to update the style.width and style.height properties but that doesn't seem to actually do anything.
0
 
LVL 10

Expert Comment

by:bluefezteam
ID: 21782463
Ok I'll give this somethough - interesting project.

Did you know that the effect doesn't work in IE? Also, in FF at the moment, images start to get squished.

I'm wondering if a cleaner solution would be to generate a div to fit over the top that has the same bounding box -2px with a border - this way it hovers over the top of the item and won't interfere with the physical dimesions - have you noticed images twitch and go smaller, some divs end up on 2 lines, this is because the physical size is altering, that suggestion of laying the border over the top will mean NO reshaping...
0
 
LVL 4

Author Comment

by:jfredrickson
ID: 21782519
Yup, that's exactly the problem. I tried adding the div on top and that worked perfectly except that it was made it impossible to select any text inside the original element because the new element was on top of it.

Here's a link to that demo:

http://purusstudios.com/files/tmp/v03.html

As you can see it works great until you are trying to select an element inside the current selected element.
0
 
LVL 10

Expert Comment

by:bluefezteam
ID: 21782563
Hmm - I'm in IE7 and I can select underlying text, double clicking selects all text in that 'area' could you not have the facility of when clicking on the element it's copied to clip board?

I'll test it in FF
0
 
LVL 10

Expert Comment

by:bluefezteam
ID: 21782578
Hmmm the last demo works better in IE than it does in FF - FF makes the border flash whenever you move the mouse.
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 4

Author Comment

by:jfredrickson
ID: 21782703
Yup, I've almost got the full keyboard imprinted on my forehead by now.

Interesting that IE allows you to interact with an element that is behind another one. It seems that v03.html is working almost exactly as intended in IE, now if only I can figure out a way to make it work in standards compliant browers.
0
 
LVL 2

Expert Comment

by:Keale2
ID: 21785430
Hey guys,
How about this:
border-color: transparent;

Tadaaaa. :D

No more adding borders or resizing divs; just change the color of the border when you need to see it.
0
 
LVL 2

Expert Comment

by:Keale2
ID: 21785445
^ Not really an appropriate solution here. Just thought it was something to think about.
0
 
LVL 4

Author Comment

by:jfredrickson
ID: 21786435
Do you mean applying that to every element on the page initially and then just changing the color for the currently selected element? This would require a full restyling of the entire page making it impossible to use on any randomly selected page.
0
 
LVL 2

Expert Comment

by:Keale2
ID: 21787133
No, I'm dumb. I wrote it before you I saw that you were going to be doing it on random pages that you don't create.

I think it would be awesome if you could create one semi-transparent div when the page was first loaded, then use javascript to set the height/width/position of that div above the element that you hover. As you stated in the question, this would get in the way if you tried to use the stuff below it.

Have you tried using javascript to fill in the overlay div with the innerHTML from the element you are hovering?
0
 
LVL 10

Expert Comment

by:bluefezteam
ID: 21789135
Not possible to do that in this instance as it would make all the objects spaced apart. The true solution is to float a clone opbject above the current object - however there's a cross browser issue (as always)
0
 
LVL 4

Author Comment

by:jfredrickson
ID: 21793969
"Have you tried using javascript to fill in the overlay div with the innerHTML from the element you are hovering?"

Yeah that's what I've been considering doing but I'm not quite sure how to handle the selection of elements inside if they are now duplicated on the page. Perhaps I can just remove the entire duplicate div which should leave the mouse above the newly selected div anyway allowing it to be reselected. I'll have to see how that works.
0
 
LVL 4

Author Comment

by:jfredrickson
ID: 21794215
Damn, that works nicely except that the copied content doesn't seem to retain the original styling and so shows up all jumbled on top of the original content. It does allow you to select interior elements, but not in a transparent way as if you were selecting the original elements.

I played around a bit with styling to see if I could simply hide the interior content and simply retain blank blocks in place of the content so that the user could still interact with it as if it were the content beneath it. But this didn't seem to work in the way that I am used to when doing image-replacement.

Attached is the code I tried. Without a way to emulate the interior content and retain exact styling while hiding the content beneath it this doesn't appear to be the transparent solution that I need. I'm wondering if there just isn't a way to make the content beneath the highlight div selectable without having to replicate it inside the highlight div.

        // Add the content from our original div so that it is selectable by the user

        highlight.innerHTML = element.innerHTML;
 

        // Loop through all the interior elements and hide all their actual content

        highlightElements = highlight.getElementsByTagName("*");

        for (i=0;i<highlightElements.length;i++) {

            highlightElements[i].style.display = "block";

            highlightElements[i].style.width = highlightElements[i].offsetWidth+"px";

            highlightElements[i].style.height = highlightElements[i].offsetHeight+"px";

            highlightElements[i].style.textIndent = "-5000px";

            highlightElements[i].style.overflow = "hidden";

        } 

Open in new window

0
 
LVL 4

Accepted Solution

by:
jfredrickson earned 0 total points
ID: 21795593
Ahh, just discovered the perfect solution. Instead of adding a single div on top of the currently selected element, I added 4 new divs and positioned them around the currently selected div. This leaves the content inside the selected div available for user interaction while creating 4 new divs to create the border with and position at the appropriate position around the selected div to simulate the border. This appears to work perfectly in all browsers and has no effect on the elements currently on the page.
0
 
LVL 2

Expert Comment

by:Keale2
ID: 21796078
If I say one more thing, will it make an admin come and look at this stuff? I'm still new here.
If somebody does have to review this: jfredrickson solved his own problem, and should get his points back.

I just think it's an interesting project, and your solution is pretty awesome.
Here's what I think would make it awesomer:
Use black divs without borders that are very transparent. Make them stretch to every edge of the screen. When your mouse isn't over any element, make them fill up the whole screen.

Make them so subtle that people don't even realize they are there; the page will just look a little darker. Then when you hover over an element it will get brighter. Yeah?
0
 
LVL 4

Author Comment

by:jfredrickson
ID: 21796561
Thanks for the feedback Keale2. That does sound like a nice idea but again we run into the problem of not being able to select elements that are behind the new divs.  It could perhaps work to darken the rest of the page when an element is selected because you can still remove them when you mouse out of the selected div, but if you cover up the entire page initially you won't be able to select anything (at least in non-IE browsers). It does sound like a nice way to highlight the currently selected element though so I'll definitely take a look at it to see if it is feasible. Thanks again.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
In this tutorial viewers will learn how to style a corner ribbon overlay for an image using CSS Create a new class by typing ".Ribbon":  Define the class' "display:" as "inline-block": Define its "position:" as "relative": Define its "overflow:" as …
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now