How to convert fixed margins in percent? - html

Here is a wrapper div with 450 px. If I set the height to 100vh, then the bottom margin of the title should adapt to the viewport.
.title,
.subtitle {
border: 1px solid #000;
}
.wrapper {
display: flex;
flex-direction: column;
width: 16%;
height: 450px;
margin-right: 42%;
margin-left: 42%;
border: 1px solid #000;
}
.title {
margin-bottom: 1rem;
}
<div class="wrapper">
<div class="title">Title</div>
<div class="subtitle">Subtitle</div>
</div>
https://codepen.io/anon/pen/ZNoZVm
Summary: The margins of the elements in wrapper should remain in proportion to the viewport.

I don't 100% understand (I know, I shouldn't be answering if I don't understand) but could it be that you're trying to say that you'd like the height of the wrapper to be the height of the viewport (screen height).
If that's the case then you're doing everything right, except...
On default the body has a margin of 8px. You simply have to remove that and you will get the result you're looking for.
body {
margin: 0;
}
/* =================== */
.title,
.subtitle {
border: 1px solid #000;
}
.wrapper {
display: flex;
flex-direction: column;
width: 16%;
height: 100vh;
margin-right: 42%;
margin-left: 42%;
border: 1px solid #000;
}
.title {
margin-bottom: 1rem;
}
<div class="wrapper">
<div class="title">Title</div>
<div class="subtitle">Subtitle</div>
</div>
(If you're wandering why you're still able to scroll, it's because "border" adds to the height (and width) so if your border-bottom is 3px and your height like 10px, you have an overall height of 13px)

Related

Why the div is not maintained their aspect ratio while displaying image?

This is html code snippet:
my_button.onclick = () => {
image_holder_div.classList.remove('display_none_class');
let imgTag = `<img id="nnn" src="${fileURL}" class="mx-auto d-block" alt="..."></img>`;
image_holder_div.innerHTML = imgTag;
}
.container-fluid{
max-width: 650px;
width: 95%;
padding: 30px;
background-color: rgb(250, 252, 253);
border-radius: 4px;
border: 1px solid #dfe1e5;
/* box-shadow: 2px 2px 2px; */
position: relative;
}
.first{
height: 400px;
border: 2px dashed #8b8e96;
background-color: #fffce5;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin: 10px auto;
}
.image_holder_div{
height: 400px;
width: 100%;
border: 2px dashed #8b8e96;
background-color: #b4a429;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin: 10px auto;
position: absolute;
top: 30px;
}
<div class="container-fluid">
<div class="first">
</div>
<div class="image_holder_div display_none_class">
</div>
</div>
When I click on my_button to display image, the image_holder_div not maintained aspect ratio while displaying image. It's showing like this I upload the image here
image_holder_div
Can anyone please tell me why it's happening and how can I fix this issue...
Explanation of the cause:
It's totally clear from the code, that you have set the width of image_holder-div to 100% of its parent container. Since its parent element is .container-fluid, it would attain its width. It is seen that you have added padding: 30px in .container-fluid, hence, you see a space of 30 pixels between the parent and image holder div.
Solution:
You can add the following styling on the image_holder_div:
width: calc(100% - 60px);
Adding this line would use some CSS calculations and set the height of the div equal to 100% of the parent element minus 60px, i.e. 30px from left and right both. (Don't forget to add space before and after the minus sign)
For more about the calc() function:
https://www.w3schools.com/cssref/func_calc.asp

Vertical line between two divs?

I have a problem with positioning the vertical line. Here's the project:
https://prnt.sc/wp2vh4
div class="col span-1-of-2"
to separate those two lists BUT - there's a grey vertical line in the 'center' between them. When I make border-right for the first div, it's way too on the right side. How can I make this line more in the center?
two elements are block - should it be something connected to that? but I don't want to 'ruin' the column system.
You could essentially take the two columns and give them a box-shadow of a half pixel each (totaling to 1px side by side). Half pixels don't work with border declarations reason being.
.container {
display: flex;
height: 150px;
}
.col {
align-items: center;
display: flex;
flex: 1;
justify-content: center;
}
.left {
box-shadow: .5px 0 0 #000;
}
.right {
box-shadow: -.5px 0 0 #000;
}
<div class="container">
<div class="col left">Left</div>
<div class="col right">Right</div>
</div>
  
There are a lot of ways to do this, another solution would be using the old columns css property, like this
.container {
columns: 2;
column-gap: 0;
column-fill: balance;
column-rule: 2px solid #ff44cc;
text-align: center;
padding: 10px;
}
<div class="container">
<div>Block</div>
<div>Block</div>
</div>
Take the solution that mosts suits you.
There are many ways to accomplish a vertical divider between columns.
Option #1
The easiest is to utilize CSS flex-box to create the columns. This will cause both columns to be the same height in the container and you can use a border to create the visual divider.
/* this section illustrates the container sizes */
#container {
border: 1px dashed #dadada;
padding: 2px;
}
.col {
padding: 20px;
font-family: Helvetica, Arial, Sans-serif;
background: tan;
border: 1px dashed #333;
}
/* this shows the solution */
#container {
display:flex;
justify-content: space-between;
}
.col {
flex-basis: 50%;
}
.col:first-child {
border-right: 3px solid aqua;
}
<div id="container">
<div class="col">Column 1</div>
<div class="col">Column 2 with lots of content that makes it much taller than the other column and messes with heights.</div>
</div>
Option #2
Use a pseudo element on the parent container to create a border.
/* this section illustrates the container sizes */
#container {
border: 1px dashed #dadada;
padding: 2px;
}
.col {
padding: 20px;
font-family: Helvetica, Arial, Sans-serif;
background: tan;
border: 1px dashed #333;
}
/* The solution */
#container {
position: relative;
overflow: auto;
}
#container:before {
content: '';
width: 2px;
background: aqua;
position: absolute;
top: 0;
left: 50%;
bottom: 0;
transform: translateX(-50%);
}
.col {
float:left;
width: calc(50% - 42px);
/* need to remove the border & padding width from the full width */
}
<div id="container">
<div class="col">Column 1</div>
<div class="col">Column 2 with lots of content that makes it much taller than the other column and messes with heights.</div>
</div>
Option #3
Really there are lots more options, a CSS gradient background, shadows, CSS Grid, CSS Columns, this list goes on.

HTML extend height of div

div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
I use the above code to display a big div with two divs in it. For the first one I use position: absolute to place it on bottom left of the div.
How can I extend the height of the second gray one so that it's 5 pixels above the first, but without having to measure its exact height in pixel (like the pic below)? I can set height: 50px; for example but is there another way?
I would use a flexbox approach rather than absolute positioning (comments in css below)
div.div1 {
display: flex;
flex-direction:column;
/* add the above styles*/
border: 1px solid black;
min-height: 100px; /*I would also change this to min-height otherwise it may cause issues if your text goes to 2 lines*/
width: 100px;
padding: 10px;
}
div.div2 {
flex-grow:1; /* make div grow to fill the space */
margin-bottom:5px; /* minus the amount of margin you wanted */
background-color: gray;
border: 1px solid black;
padding: 10px;
}
div.div3 {
/* remove absolute positioning */
border: 1px solid red;
height: 20px;
width: 20px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
EDIT: I suggest that, if you can focus on the modern browser features, going the flexbox way as shown by Pete is definitely a cleaner approach than the ones I've shown bellow. That being said, here are the alternatives:
You can use calc to dynamically determine the height of div2:
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
height: calc(
100%
- 20px /* div1: padding top and bottom */
- 2px /* div1: border top and bottom */
- 20px /* div3: height */
- 2px /* div3: border top and bottom*/
- 5px /* desired separation*/
);
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
You can avoid including padding and border width in your calculations if you set the box-sizing for your divs to border-box (You might want to set this for all elements):
div {
box-sizing: border-box;
}
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
height: calc(
100%
- 20px /* div3: height */
- 5px /* desired separation */
);
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
There's this rather new, hip CSS property called 'flex' which you're now going to love because it does it exactly that without the need of positioning absolute etc. I did something similar yesterday where I had a vertical nav bar and I wanted one menu at the top and one at the bottom. In a responsive environment; using your approach of positioning absolute it would've resulted in a nasty mess of working out heights to stop the content from overlapping. Flex prevented this! Yeyyyyy
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
In your example you want to do something like this:
.div1 {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: space-around;
}
.div2 {
align-self: flex-start;
flex-grow:1;
width:100%;
}
.div3 {
align-self: flex-end;
width:100%;
}
Now your div 3 will always be at the bottom. Although now .div3 will extend the entire width so within the div insert your content and BOOM done.
You can use calc on the heightsetting as in my snippet below. That setting is 100% minus (20 + 10 + 2) for the height, border and bottom of the lower DIV minus (5 + 2) for the distance and the border of the first DIV minus 10px for the padding of the parent, summing up to 49px .
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
height: calc(100% - 49px);
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>

Using CSS, how do you anchor an element to a baseline and size it based on another "pinned" element?

Here's an image of what I'm referring to:
If you have some fixed height h from the baseline that the pin lies, and the green element is dynamically sized, how can you make the orange element take the space between the two?
Have exactly what you need in this case using a flexbox.
The pin approximately stays at the same height above the baseline give or take 1px.
How it works: When the green element grows say 10px the pin is elevated by 5px. But the flex setup means the dummy and the orange box reduces 5px each thus keeping the pin at a contant height.
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
height: 100px;
border-bottom: 1px solid black;
}
.dummy {
flex: 1;
}
.top {
height: 20px;
width: 20px;
border: 1px solid green;
position: relative;
}
.top div {
position: absolute;
height: 3px;
width: 3px;
background: #880015;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.bottom {
width: 50px;
border: 1px solid orange;
flex: 1;
}
<div class="wrapper">
<div class="dummy"></div>
<div class="top">
<div></div>
</div>
<div class="bottom"></div>
</div>
You can use table properties for this. Table cells fill its parent width. If one cell is short, the other one will expand to fill its parent. The trick here is to rotate 90º your "table" and it's done. To change the 'height" of your pinned item you will actually be changing its width. The anchor element will resize accordingly.
Be aware of this though: http://caniuse.com/#search=transform
.baseline{
height: 100px;
width: 100px;
border: 3px solid black;
display: table;
transform: rotate(90deg);
}
.pinned,.anchored{
display: table-cell;
}
.pinned{
width: 30px;
border: 3px solid green;
}
.anchored{
border: 3px solid orange;
}
<div class="baseline">
<div class="pinned">
</div>
<div class="anchored">
</div>
</div>

How do I make this html two columns of equal width with a margin in between?

I have some HTML that I cannot change, but I can change the CSS as much as I want. I need to make these:
two columns of equal width
A margin in between of 2em
They have to take all the remaining width (parent width - 2em)
The boxes need to have a padding inside
HTML:
<div class="parent">
<a href="/page1" class="box">
<img class="pic" src="/images/image1.png">
<div class="description">the description</div>
</a>
<a href="/page2" class="box">
<img class="pic" src="/images/image2.png">
<div class="description">the description</div>
</a>
</div>
I'm able to do it without any spacing between them with: box-sizing: border-box; but if I add in a margin-right, they no longer fit.
Give this a try : It makes use of the Calc() function in css.
Note: The border throws off the calculation a bit, so you will have to adjust the calc slightly. I just did it to show you how the boxes were laid out.
.parent {
position: relative;
width: 600px;
height: 300px;
border: 1px solid red;
}
.box {
border: 1px solid black;
width: calc(50% - 1.25em);
display: inline-block;
}
.box:first-child {
margin-right: 2em;
}
Fiddle
I was able to solve it:
.parent .box
{
position: relative;
width: 50%;
margin: 0em;
padding: 1em;
float: left;
font-size: 1em;
overflow: hidden;
z-index: 0;
display: block;
text-decoration: none;
box-sizing: border-box;
}
.parent .box:nth-child(odd)
{
border-right: solid 1em #ffffff;
}
.parent .box:nth-child(even)
{
border-left: solid 1em #ffffff;
}
The n-th child lets me add the spacing between them