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.
Related
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)
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>
The code below gives this result:
Which is very close to the result I want except three facts:
Why is there a very odd grey area at the bottom of the picture?
How can I make the orange div extend to the bottom of the picture? I tried height: 100% but it didn't work...
How can I also give a 10 pixels space between the div of the text and the picture?
Desired result:
div.div1 {
background-color: yellow;
border: 1px solid black;
padding: 10px;
overflow: auto;
}
div.div2 {
border: 1px solid gray;
float: right;
}
div.div3 {
background-color: orange;
border: 1px solid gray;
height: 100%;
padding: 10px;
}
<div class="div1">
<div class="div2">
<img src="http://splendidwillow.com/wp-content/uploads/2012/04/Allium-Purple-garlic-flowers-200x200.jpg">
</div>
<div class="div3">
Text about flowers
</div>
</div>
div.div1 {
display: flex; /* 1 */
padding: 10px;
overflow: auto;
background-color: yellow;
border: 1px solid black;
}
div.div2 {
order: 1; /* 2 */
border: 1px solid gray;
}
div.div3 {
flex: 1; /* 3 */
margin-right: 10px;
padding: 10px;
/* height: 100% */ /* 4 */
background-color: orange;
border: 1px solid gray;
}
img {
vertical-align: bottom; /* 5 */
}
<div class="div1">
<div class="div2">
<img src="http://splendidwillow.com/wp-content/uploads/2012/04/Allium-Purple-garlic-flowers-200x200.jpg">
</div>
<div class="div3">
Text about flowers
</div>
</div>
Notes:
Establish flex container. By default, children will line-up in a row (flex-direction: row) with equal height (align-items: stretch).
Make image appear last in visual display (default order value for all flex items is 0)
Make orange box consume all available space in the row.
Remove defined heights on flex items. They will override align-items equal height feature.
Mystery white space underneath image tag
Surely img's margin-bottom, set it to 0.
Flexbox surely is your friend here.
Same as 1, but with margin-left in img and margin-right in .div2, both of 5.
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>
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