Proportional scaling -- need help understanding how this css code works - css

I created this fiddle (http://jsfiddle.net/HfpHf/1/) based on the following stackoverflow question/answer: https://stackoverflow.com/a/9236397
The relevant bits are:
.box-parent {
width:95%;
padding-bottom:95%;
height:0;
position:relative;
}
.box {
border-radius: 10%;
width:100%;
height:100%;
position:absolute;
left:0;
background-color:rgb(17, 17, 17);
color: #ffffff;
text-align: center;
}
The trouble is I don't really understand how or why it works. More specifically, what does setting height: 0 on the parent do and why does setting padding-bottom to the same percentage as width result in the child being a square?

The problem is that the li element doesn't have got specified height. So child elements have to be determinated only by its width.
We can't use height: 100% to specify parent-box because we don't know the height of li.
The only solution is use padding which is destined only by parent element's width as you can see here in percentage specifition. There is written Specifies the padding in percent of the width of the containing element.

Related

css relative alignment upon image

I am trying to align a div on top of my image. Horizontal alignment works fine, vertical offset however doesn't. Also, the background-color of #studentenlijn is not applied.
HTML Snippet:
<div id="container">
<div id="studentenlijn">STUDENTENLIJN</div>
<img src="http://lsvb.nl/s/lsvbheader.jpg" class="banner" />
</div>
Relevant CSS
#studentenlijn {
width: 10%;
height: 10%;
position: absolute;
top: 30%;
left: 72%;
background-color: #660000;
}
JSFiddle: http://jsfiddle.net/YGeLA/
Any ideas?
Your body had a height of 0, thus affecting the height of the containers within it when you try to specify a percentage height. Another problem was that you had a floating image within your container div, and thus you need to hide the overflow in order for the container to properly calculate the heights of elements within.
I have made some minor changes to your fiddle here:
http://jsfiddle.net/YGeLA/1/
I added:
height: 100%; to the body element
overflow: hidden; to #container which forces the container to respect the height of all elements within it.
The size of your div is:
#studentenlijn {
width: 10%;
height: 10%;
}
So it'll be a % of the parent element. The parent element, your container, is:
#container {
width: 100%;
height: 100%;
}
At this point, your browser can't determine which size should have your block.
So you won't be able to center it (Since you can't center an element which have not a browser-determined size).
You can't see the background-color for the same reason. It is applied, but you won't see your colored block because his size is 0.
Try to solve it, and it would be easier to center your div. In case it doesn't help you, edit your post with your modification :)
the container height is 0px. so you can't give height 100%
you have to set height in px
look at this update
#container {
position:relative;
width:100%;
height:100%;
line-height: 0;
}
.banner {
width:100%;
}
#studentenlijn {
width:200px;
height:30px;
position:absolute;
top:35px;
left:72%;
background-color:#660000;
line-height:30px
}
http://jsfiddle.net/YGeLA/2/

Fluidly vertically expanding DIV or TEXTAREA

I want a textarea to take up as much vertical space as possible without overlapping any other visual elements. Obviously different screens / devices are different heights so I need the solution to be fluid (I think that's the right term).
The other questions I've looked at don't involve textareas, instead using (child) DIVs whose content is already determined. I don't need the textarea to expand dynamically to fit it's content, I just want it to be as tall as possible but without obscuring any other elements.
I've collected together parts of answers to similar questions but can't quite make it work:
http://jsfiddle.net/wa5zU/
CSS:
body, html {
height:100%
}
p {
text-align:justify
}
textarea {
resize:vertical;
height:auto;
width:100%;
box-sizing:border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
}
.vexpand {
border:1px solid blue
}
.vexpand {
position:absolute;
bottom:0;
width:90%;
height:auto
}
HTML:
<h2>Some content of variable length / height to fill the top portion of the screen</h2>
<p>Either: 1) make the blue-bordered DIV expand fluidly to fill this gap or 2) make the textarea expand to achieve the same effect</p>
<div class="vexpand">
<div>One line of content related to the textarea that must be kept with the textarea</div>
<textarea rows=5 cols=10>I have heard that textareas need valid rows and cols attributes in order to respond correctly to height and width css</textarea>
</div>
This attempt is based on position:absolute and bottom:0 assuming that the DIV can be expanded upwards. I did it this way because the content above the DIV/TEXTAREA is variable so couldn't find an elegant and robust way to measure from the top.
There is a line of content related to the textarea that must be kept with the textarea, hence encapsulating this content and the textarea in a div. Ideally I would prefer that content to stay above the textarea.
Things I've tried / seen in related questions:
position:absolute and conflicting absolute position
setting the height of body and html to 100% so that CSS can perform calculations
using height:auto or height:100% on the wrapper div .vexpand or the textarea
setting the cols and rows attributes on the textarea so that it responds to height and width
Is this what you want to do?
http://jsfiddle.net/wa5zU/2/
body, html {
height:100%;
margin: 0;
padding: 0;
}
p {
text-align:justify
}
*
{
box-sizing:border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
}
textarea {
resize:vertical;
height: calc(100% - 20px) ;
width:100%;
}
.text-content
{
height: 80%;
overflow: auto;
padding: 10px;
}
.editor
{
height: 20%;
overflow: hidden;
padding: 10px;
}

Another DIV CSS vertical alignment issue

I know there are a million questions about CSS vertical alignment but I believe I have a slightly new flavour of problem.
I have a container layer and a sublayer inside that, the internal layer has fixed size, however my wrapper layer has a variable height, percentage, with a fixed minimum height.
The issue I have is that I'm able to align it vertically middle either for the min-height scenario or the percentage height scenario but not both.
I have a feeling that the solution will most likely be involving jQuery to determine the height of the wrapper layer in pixels and applying the negative margin to the internal layer on the fly, using position:rel; top:50%; but thought I would asking incase anyone has come across this before.
My css has the following properties:
#container {
height:82%;
min-height:600px;
width:938px;
}
#container div {
width:400px;
height:400px;
padding:70px;
border-radius:100%;
text-align:center;
}
Give the container layer a css property value of display: table. I think that would fix your issue.
#container {
display: table;
}
There is nothing new to this question.
Still, here is the answer:
#container {
height:82%;
min-height:600px;
width:938px;
position: relative;
}
#container div {
width:400px;
height:400px;
padding:70px;
border-radius:100%;
text-align:center;
position: absolute;
top: 50%;
left: 50%
margin-top: -270px;
margin-left: -270px;
}
Another posiibility would be to set the container to display: table and the inner div to display: table-cell and vertical-align: middle.

change fluid image aspect ration css

I'm trying to place 6 images one next to another with css,
the whole thing should be able to scale pretty well in most displays (except for mobile for the moment)
so I've made this:
http://pelloponisos.telesto.gr/galleryTest/test/gallery.php#
(apparently I'm trying to make yet another carousel)
most of my images have a bigger width than height so when I scaled them I just put
width:x% in the li container and 100% for the image width.
but the sixth image is different and it causes quite a bit of trouble
I tried setting the height too but you can only scale the images based on one of the two.
The only thing that worked so far was to put a static height in the ul and then scale in both width and height but then it's not a fluid grid.
is there any way to make all li elements have a fluid height and then scale all images based on that? or if not
is there any way to make any image with different ratio scale to the one I specify in the css?
I stripped down your code a little bit, but this seems to get closer to the idea. The trick is to set the width in the container (.upper ul li) then for the images use: max-width:100%; height:auto. Also, the padding is now in %.
#carousel{
position:relative;
}
#wrapper{
margin:0 auto;
}
#slides{
width: 100%;
}
.upper ul li{
width: 200px;
max-width: 100%;
list-style:none outside none;
float:left;
padding-bottom:5px;
padding:2%;
}
img.galleryThumbnail{
max-width:100%;
height:auto;
}
.info{
display:none;
}
#buttons img{
position:absolute;
top:90px;
}
#buttons #prev img{
position:absolute;
left:29px;}
#buttons #next img{
position:absolute;
right:21px;
}

CSS 100% height with padding/margin

With HTML/CSS, how can I make an element that has a width and/or height that is 100% of it's parent element and still has proper padding or margins?
By "proper" I mean that if my parent element is 200px tall and I specify height = 100% with padding = 5px I would expect that I should get a 190px high element with border = 5px on all sides, nicely centered in the parent element.
Now, I know that that's not how the standard box model specifies it should work (although I'd like to know why, exactly...), so the obvious answer doesn't work:
#myDiv {
width: 100%
height: 100%;
padding: 5px;
}
But it would seem to me that there must be SOME way of reliably producing this effect for a parent of arbitrary size. Does anyone know of a way of accomplishing this (seemingly simple) task?
Oh, and for the record I'm not terribly interested in IE compatibility so that should (hopefully) make things a bit easier.
EDIT: Since an example was asked for, here's the simplest one I can think of:
<html style="height: 100%">
<body style="height: 100%">
<div style="background-color: black; height: 100%; padding: 25px"></div>
</body>
</html>
The challenge is then to get the black box to show up with a 25 pixel padding on all edges without the page growing big enough to require scrollbars.
I learned how to do these sort of things reading "PRO HTML and CSS Design Patterns". The display:block is the default display value for the div, but I like to make it explicit. The container has to be the right type; position attribute is fixed, relative, or absolute.
.stretchedToMargin {
display: block;
position:absolute;
height:auto;
bottom:0;
top:0;
left:0;
right:0;
margin-top:20px;
margin-bottom:20px;
margin-right:80px;
margin-left:80px;
background-color: green;
}
<div class="stretchedToMargin">
Hello, world
</div>
Fiddle by Nooshu's comment
There is a new property in CSS3 that you can use to change the way the box model calculates width/height, it's called box-sizing.
By setting this property with the value "border-box" it makes whichever element you apply it to not stretch when you add a padding or border. If you define something with 100px width, and 10px padding, it will still be 100px wide.
box-sizing: border-box;
See here for browser support. It does not work for IE7 and lower, however, I believe that Dean Edward's IE7.js adds support for it. Enjoy :)
The solution is to NOT use height and width at all! Attach the inner box using top, left, right, bottom and then add margin.
.box {margin:8px; position:absolute; top:0; left:0; right:0; bottom:0}
<div class="box" style="background:black">
<div class="box" style="background:green">
<div class="box" style="background:lightblue">
This will show three nested boxes. Try resizing browser to see they remain nested properly.
</div>
</div>
</div>
The better way is with the calc() property. So, your case would look like:
#myDiv {
width: calc(100% - 10px);
height: calc(100% - 10px);
padding: 5px;
}
Simple, clean, no workarounds. Just make sure you don't forget the space between the values and the operator (eg (100%-5px) that will break the syntax. Enjoy!
According the w3c spec height refers to the height of the viewable area e.g. on a 1280x1024 pixel resolution monitor 100% height = 1024 pixels.
min-height refers to the total height of the page including content so on a page where the content is bigger than 1024px min-height:100% will stretch to include all of the content.
The other problem then is that padding and border are added to the height and width in most modern browsers except ie6(ie6 is actually quite logical but does not conform to the spec). This is called the box model. So if you specify
min-height: 100%;
padding: 5px;
It will actually give you 100% + 5px + 5px for the height. To get around this you need a wrapper container.
<style>
.FullHeight {
height: auto !important; /* ie 6 will ignore this */
height: 100%; /* ie 6 will use this instead of min-height */
min-height: 100%; /* ie 6 will ignore this */
}
.Padded {
padding: 5px;
}
</style>
<div class="FullHeight">
<div class="Padded">
Hello i am padded.
</div
</div>
1. Full height with padding
body {
margin: 0;
}
.container {
min-height: 100vh;
padding: 50px;
box-sizing: border-box;
background: silver;
}
<div class="container">Hello world.</div>
2. Full height with margin
body {
margin: 0;
}
.container {
min-height: calc(100vh - 100px);
margin: 50px;
background: silver;
}
<div class="container">Hello world.</div>
3. Full height with border
body {
margin: 0;
}
.container {
min-height: 100vh;
border: 50px solid pink;
box-sizing: border-box;
background: silver;
}
<div class="container">Hello world.</div>
This is one of the outright idiocies of CSS - I have yet to understand the reasoning (if someone knows, pls. explain).
100% means 100% of the container height - to which any margins, borders and padding are added. So it is effectively impossible to get a container which fills it's parent and which has a margin, border, or padding.
Note also, setting height is notoriously inconsistent between browsers, too.
Another thing I've learned since I posted this is that the percentage is relative the container's length, that is, it's width, making a percentage even more worthless for height.
Nowadays, the vh and vw viewport units are more useful, but still not especially useful for anything other than the top-level containers.
Another solution is to use display:table which has a different box model behaviour.
You can set a height and width to the parent and add padding without expanding it. The child has 100% height and width minus the paddings.
JSBIN
Another option would be to use box-sizing propperty. Only problem with both would be they dont work in IE7.
Another solution: You can use percentage units for margins as well as sizes. For example:
.fullWidthPlusMargin {
width: 98%;
margin: 1%;
}
The main issue here is that the margins will increase/decrease slightly with the size of the parent element. Presumably the functionality you would prefer is for the margins to stay constant and the child element to grow/shrink to fill changes in spacing. So, depending on how tight you need your display to be, that could be problematic. (I'd also go for a smaller margin, like 0.3%).
A solution with flexbox (working on IE11): (or view on jsfiddle)
<html>
<style>
html, body {
height: 100%; /* fix for IE11, not needed for chrome/ff */
margin: 0; /* CSS-reset for chrome */
}
</style>
<body style="display: flex;">
<div style="background-color: black; flex: 1; margin: 25px;"></div>
</body>
</html>
(The CSS-reset is not necessarily important for the actual problem.)
The important part is flex: 1 (In combination with display: flex at the parent). Funnily enough, the most plausible explanation I know for how the Flex property works comes from a react-native documentation, so I refer to it anyway:
(...) flex: 1, which tells a component to fill all available space, shared evenly amongst other components with the same parent
To add -webkit and -moz would be more appropriate
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
Frank's example confused me a bit - it didn't work in my case because I didn't understand positioning well enough yet. It's important to note that the parent container element needs to have a non-static position (he mentioned this but I overlooked it, and it wasn't in his example).
Here's an example where the child - given padding and a border - uses absolute positioning to fill the parent 100%. The parent uses relative positioning in order to provide a point of reference for the child's position while remaining in the normal flow - the next element "more-content" is not affected:
#box {
position: relative;
height: 300px;
width: 600px;
}
#box p {
position: absolute;
border-style: dashed;
padding: 1em;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
<div id="box">
<p>100% height and width!</p>
</div>
<div id="more-content">
</div>
A useful link for quickly learning CSS positioning
This is the default behavior of display: block The fastest way that you can fix it in 2020 is to set display: 'flex' of parent element and padding e.g. 20px then all its children will have 100% height relative to its height.
Border around div, rather than page body margin
Another solution - I just wanted a simple border around the edge of my page, and I wanted 100% height when the content was smaller than that.
Border-box didn't work, and the fixed positioning seemed wrong for such a simple need.
I ended up adding a border to my container, instead of relying on the margin of the body of the page - it looks like this :
body, html {
height: 100%;
margin: 0;
}
.container {
width: 100%;
min-height: 100%;
border: 8px solid #564333;
}
<style type="text/css">
.stretchedToMargin {
position:absolute;
width:100%;
height:100%;
}
</style>

Resources