Zoom-out bug in chrome, IE, etc, with borders? - html

Simple test case:
http://cssdesk.com/K2xmN
Another Example:
http://developer.nokia.com/
Problem: When you change the zoom page to 90%, the border goes to 1.111 (1.333 at 75%) and breaks the layouts.
In the nokia website, you can see the top containers break because there is no space left. In the CSSDesk testcase, if you inspect the computed styles, you can see the border width going higher.
Why this happen? border is not set in EM or %, why does it scale?

The why has been explained but I though I'd share a workaround which I just discovered:
Often you can replace the border with a box-shadow that looks just like a border but doesn't add to the outer width of the element:
Instead of
border: 1px solid red;
write
box-shadow: inset 0 0 0 1px red;
width: 102px;
height: 102px;
The width and height of the div have to be adjusted accordingly to accomodate to the fact that the 1px of the borders on each side are gone now.
Now when zooming out the browser will still treat the box-shadow the same as the border, i.e. it won't shrink below 1px, but it will not influence the width of the element and thus the layout won't break.
Alternatively, you can probably use box-sizing: border-box; to some similar effect.

This is an artifact of the problem of scaling down a 1px border. To illustrate what happens, I have modified your test case to include zoom: 0.5;
in the css: http://cssdesk.com/zn4Lx
Notice that if you inspect the computed style, the border width will be 2px. What happens is that Chrome tries to scale down the element, but after scaling, the border still has to be 1px wide if it is to remain visible (after all, 1px is the smallest unit that can be rendered on the computer screen, and if the border width is scaled down to a floating point number smaller than 1.0, it will be rounded down to 0px and disappear). But to justify the scaling, it over-compensates by adjusting the initial width to satisfy the equation
new_width = old_width * scale
In this example, since new_width = 1px, and scale = 0.5, it re-calculates old_width as 2px. Note however that the actual width of the border that is rendered after the scaling is still just 1px.
So in your example, the adjusted old width will be approximately 1.11111111px, and the rendered border width will be 1px wide, but since all the other widths in the layout that are larger than 1px also have been scaled down by approximately 90%, there is no room for a 1px wide border, which results in a broken layout.

The box shadow solution by Shepard might not work well for elements with children that occupy all their space because the shadow will be covered by the children.
Another fix would be to use a border width larger than 1px but smaller than 1.5px.
border-width: 1.3px;
I found 1.3px or 1.4px to be the ideal value and it works in Chrome and IE11 with zoom >= 75%

Related

Border included in the layout/ frame of an element, instead of being around it? (Like stroke: included on Figma)

Hope you're all doing fine. I have a question regarding borders in CSS.
I have a button that is 48px height, but padding sets its size dynamically instead of hardcoding the 48px height value. When I give it a 2px border, the button ends up being 52px because of the extra 2px on top and bottom.
Is there a way to include border in the total height? Like border included in layout? There is a specific reason that I don't wanna lower padding with 4px in total. Maybe stack the border on top of the padding? Is this possible?
Further reading: https://forum.figma.com/t/borders-are-not-included-in-the-size-of-frames/2372

image border and image itself is overflowing [duplicate]

I've defined widths of the containers in percentage. I'd like to add a border (3px on right side of a width), since container width is in % while the border width is in px, how can I adjust the width of the container?
<div class="wrap">
<div class="left">...</div>
<div class="right">...</div>
</div>
.wrap{
width:100%;
}
.left{
width:30%;
}
.right{
width:70%;
}
I'd like to add 3px border on the right side of .left. For example:
.left{
width:30%;
border:3px solid #000;
}
Since I have defined width in the %, what is the best way to re-adjust the width of the .left. I can roughly decrease the width to 29%, but I want to do precisely.
Use the box-sizing: border-box property. It modifies the behaviour of the box model to treat padding and border as part of the total width of the element (not margins, however). This means that the set width or height of the element includes dimensions set for the padding and border. In your case, that would mean the element's width and it's border's width would consume 30% of the available space.
Support for it isn't perfect, however vendor prefixes will catch most if not all modern browsers:
.left {
width: 30%;
border: 3px solid #000;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
More information can be found on the MDN and Quirksmode.
According to Quirksmode, using the 3 vendor prefixes above (-moz-, -webkit- and -ms-), you get support for all browsers, even IE8.
The easiest cross-browser way is to NOT set the border on the outer divs, and instead set it on a NEW div inside .left. Simple, and works well.
That's a bit tricky but check out this post on a way to get around it:
Percentage Plus Pixel Sizing (and Example)
Box Sizing on CSS-Tricks (and Example)
The box-sizing property may also be of interest to you, check this out:
How do I add 1px border to a div whose width is a percentage?
In my case I ended up adding an outer div with a padding of the size that I wanted the original margin to be, and width 100%. That allowed me to set the inner div width to 100%, fitting entirely inside the padding (that would work as the previous margin I had set)
Just change px to vw like
border-width: 10px;
to
border-width: 10vw;
Its do whats percentage do....

Border is not included in width calculation for media queries

which is causing things to look sloppy.
There is a div which expand to 100%, but the right border is cut off.
See the dev site here - it is under Feed
https://frozen-dusk-2587.herokuapp.com/
Here in image of me toggling the border using Chrome Dev Tools:
and here it is with me toggling on the border:
This is the default behaviour for all box-sizing:content-box elements, which is the default value for all elements. add box-sizing:border-box; to #at_view. This causes the browser to include border and padding in relative width calculations.
If you define an element with a width of 100% and also a border, the border is added to the 100% so this makes the total width more than 100% which is causing your problem (read up on the css box-model: http://www.w3schools.com/css/css_boxmodel.asp).
So one solution is that you could change the width of #at_view to less than 100%, try 90-95% - until things look right.
Or to be very specific, you can define #at_view width as 100% and subtract the border using calc():
#at_view {
width: calc(100% - 20px);
}
(Subtracting 20px, since it looks like 20px is the width being added by the border, as the border is 10px --> 10px on the left + 10px on the right = 20px.)
Even such basic things as the box model can be modified using CSS Rules.
See
https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
to change the default behavior of the box model:
#at_view{
box-sizing:border-box;
}

Transparent borders are adding to width x height

Borders are supposed to go outside of the width x height of a div. But this jsfiddle - http://jsfiddle.net/L33cK/5/ - shows borders being added to the width x height of a div when they're transparent. I would expect the line in the jsfiddle to be 1px when given transparent 1px borders, but it's 3px.
Does anyone understand what's going on here? I'm looking at it with Chrome.
Thanks
div#line {
margin-left:100px;
width:1px;
height:200px;
background-color:red;
border:1px solid transparent;
}
The borders are transparent, so you can see the div's background through them. It's that simple.
In this updated fiddle I've added another div that has a dotted border.
background:red; border:10px dotted yellow
And you can see the background of the div between the dots of the border.
So if you want the borders to be the colour of the body background, the solution is to not make them transparent, but to give them the same background-color as the body. Or, use margins rather than borders.
Since the div is in content-box mode(*), the CSS width property does not designate the total outer width of the div, but its content area. The outer width is equal to width plus the size of the padding plus the size of the border. (If you give the div some padding as well, you will see that the outer width gets even larger, even if the width property remains 1px.)
(*) You can change this behaviour by using the box-sizing property. See MDN page on how to use it and what vendor prefixes to apply. Basically, with box-sizing: border-box you tell the browser that width is to be taken as the outer width of the element rather than the content area.

Create an even shadow on a full-width element

When a box-shadow is applied to an element the corners are less "thick" than the middle because they don't have shadow on both sides. This creates an odd effect on full width elements.
http://jsfiddle.net/kevincox/6FhYe/18/
If you look at that example you will see that the edges are lighter. If the "banner" is at the top of a page you can spread it and shift it up but that doesn't work for the middle of the page as you can see the top.
I was wondering if anyone had a solution with no images and preferably cross-browser but I can deal with vendor prefixes for a bit. Is there something like a separate horizontal and vertical stretch?
One trick that seems to work is setting negative horizontal margins on the element, so that its ends extend outside the page, and adjusting the padding to compensate. Using your jsFiddle as an example, try changing the CSS to:
h1 {
margin: 20px -20px;
padding: 10px 30px;
background-color: #AFA;
box-shadow: 0 0 10px black;
}
Take a look at this updated jsfiddle
Each number in the shadows represents the following
The horizontal offset of the shadow, positive means the shadow will
be on the right of the box, a negative offset will put the shadow on
the left of the box.
The vertical offset of the shadow, a negative one means the
box-shadow will be above the box, a positive one means the shadow
will be below the box.
The blur radius (optional), if set to 0 the shadow will be sharp,
the higher the number, the more blurred it will be.
The spread radius (optional), positive values increase the size of
the shadow, negative values decrease the size. Default is 0 (the
shadow is same size as blur).
Color
Applying border-radius also fixes this issue (but obviously it depends on whether you want that in your design).
h1 {
margin: 10px;
padding: 10px;
border-radius: 10px;
background-color: #AFA;
box-shadow: 1px 0 10px black;
}