Alright, so i have an element with the class called .price within the element .item as shown here. Now what I want is to have .price centered horizontally and it being pushed/pulled to the bottom border of its parent, like so.
now here comes the fun part which makes this hard:
pure css (no javascript/jquery)
it needs to be dynamic, so the width/height property of .price can fluctuate (see snippet)
here's how far i got:
.item {
width: 200px;
height: 400px; /* not static */
background: wheat;
}
.product-image {
margin: 0 auto;
width: 180px;
height: 300px;
background: lightskyblue;
}
.price {
margin: 0 auto;
width: 50px; /* not static */
height: 20px; /* not static */
background: indianred;
}
<div class="item">
<div class="product-image">
</div>
<div class="price">
</div>
</div>
Thanks in advance.
Here you go
.item {
width: 200px;
height: 400px;
/* not static */
background: wheat;
position: relative;
}
.product-image {
margin: 0 auto;
width: 180px;
height: 300px;
background: lightskyblue;
}
.price {
width: 50px;
/* not static */
height: 20px;
/* not static */
background: indianred;
position: absolute;
bottom: 8px;
left: 50%;
transform: translateX(-50%);
}
<div class="item">
<div class="product-image">
</div>
<div class="price">
</div>
</div>
You can achieve this with flexbox.
Steps:
Set your .item element as a flex-container with display: flex; and change its direction using flex-direction: column;
Since your flex-direction is set to column, you can use align-self: center; to horizontally center your .price element (now a flex-item), and finally use margin-top: auto; to position it to the bottom.
.item {
width: 200px;
height: 400px;
/* not static */
background: wheat;
display: flex;
flex-direction: column;
}
.product-image {
margin: 0 auto;
width: 180px;
height: 300px;
background: lightskyblue;
}
.price {
align-self: center;
margin-top: auto;
width: 50px;
/* not static */
height: 20px;
/* not static */
background: indianred;
}
<div class="item">
<div class="product-image">
</div>
<div class="price">
</div>
</div>
You should use relative positioning for your parent div and absolute in child divs.
My example
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<div class="item">
<div class="product-image"> </div>
<div class="price">
</div>
</div>
</body>
</html>
.item {
width: 500px;
height: 400px; /* not static */
background: wheat;
position:relative;
}
.product-image {
margin: 0 auto;
width: 200px;
height: 300px;
background: lightskyblue;
}
.price {
margin: 0 auto;
width: 50px; /* not static */
height: 20px; /* not static */
background: indianred;
position: absolute;
bottom: 0;
left: 50%;
}
Relative positioning on the parent container (item) and absolute positioning on the child containers.
.item {
width: 200px;
height: 400px; /* not static */
background: wheat;
position: relative;
}
.product-image {
margin: 0 auto;
width: 90%;
height: 75%;
background: lightskyblue;
}
.price {
margin: auto 39%;
width: 25%; /* not static */
height: 5%; /* not static */
background: indianred;
position: absolute;
bottom: 3%;
}
<div class="item">
<div class="product-image">
</div>
<div class="price">
</div>
</div>
Or instead of setting the margin you could just use the left or right properties of positioning to move it center. If you want price to be flush with the bottom just change the bottom percentage to '0'.
The other idea that comes to mind is creating another div container just for price and relatively positioning it at the bottom of your parent container, absolutely positioning the price div and than simply using text-align in the parent. Although I haven't actually tried this yet.
Related
I have structure like this:
img {
width: auto;
height: 200px;
}
.cards {
display: flex;
justify-content: center;
margin-top: 2em;
width: 80%;
flex-wrap: wrap;
}
.card {
margin: 1em;
box-shadow: 0 0 6px #000;
object-fit: cover;
}
.info {
padding: 1em;
border-top: none;
}
<div class='cards'>
<div class="card">
<img src="https://picsum.photos/id/1004/5616/3744" alt="1004" />
<div class="info">
<h3>Greg Rakozy</h3>
<div><small>https://unsplash.com/photos/SSxIGsySh8o</small></div>
</div>
</div>
</div>
on computers with long width image is rendered a little wrong.
how can I fix this so that it displays correctly, i.e. sticks to the '.card' block?
First you need to limit the width of you main container:
.cards {
display: flex;
justify-content: center;
margin-top: 2em;
width: 80%;
flex-wrap: wrap;
max-width: 1440px; /* whatever you desire */
margin-left: auto; /* center the container */
margin-right: auto; /* center the container */
}
Then each image should take 100% for it's container:
.card {
margin: 1em;
box-shadow: 0 0 6px #000;
object-fit: cover;
flex: 0 0 25%; /* each card will be 25% width */
}
img {
width: 100%;
height: 200px;
object-fit: cover;
}
Adding those to .card class
width: 100%;
height: auto;
Google how to make image responsive with css, it's not related to React.
.card {
width: 100%;
height: auto;
}
You can either put those images in a div.img-container and set the div width & height like this.
.img-container {
width: 100%;
height: // as you want;
}
and then put that image inside .img-container and set the image width to 100%.
.container {
width: 350px;
height 350px;
border: 2px solid black;
border-radius: 5px;
}
.container .img-container {
width: 100%;
height: 200px;
}
.container .img-container img {
width: 100%;
height: 100%;
}
.container .card-info {
width: 100%;
height: auto;
}
<div class="container">
<div class="img-container">
<img src="https://picsum.photos/200">
</div>
<div class="card-info">
<h5>Title</h5>
<small>Your link here</small>
</div>
</div>
and either set image width 100% and height auto.
suppose we have 4 dives.
the first div is outer div.
i want to create a HTML that
the second div size be 50% first and be in middle bottom of first div.
the third div size be 50% second and be in middle left of second div.
the fourth div size be 50% third div and be in middle top of third div.
how can i do it?
Is this your desired output? It’s made using position, top and bottom, and translate to make sure it’s centered right.
.div1 div { /* makes every small div 50% the size of the previous */
width: 50%;
height: 50%;
}
.div1 {
width: 200px;
height: 200px;
background-color: red;
}
.div2 {
background-color: green;
position: relative;
top: 100%;
left: 50%;
transform: translate(-50%, -100%);
}
.div3 {
background-color: pink;
position: relative;
top: 50%;
transform: translate(0, -50%);
}
.div4 {
background-color: lightblue;
position: relative;
left: 50%;
transform: translate(-50%, 0);
}
<div class="div1">
<div class="div2">
<div class="div3">
<div class="div4">
</div>
</div>
</div>
</div>
you can also use flex(or grid) and margin instead position :
div {
display: flex;
}
body>div {
/* sizing : whatever you want to start from */
height: 90vmin;
width: 90vmin;
background: #ed1c24;
}
div div {
height: 50%;
width: 50%;
}
div div {
background: #22b14c;
margin: auto auto 0;
}
div div div {
background: #ffaec9;
margin: auto auto auto 0;
}
div div div div {
background: #00a2e8;
margin: 0 auto auto;
}
/* center the demo */
html {
display: flex;
height: 100vh;
}
body {
margin: auto;
}
<div>
<div>
<div>
<div>
</div>
</div>
</div>
</div>
We can achieve this by using the CSS Flexbox and Margin properties.
index.html
<body>
<div class="firstdiv">
<div class="seconddiv">
<div class="thirddiv">
<div class="fourthdiv">
</div>
</div>
</div>
</div>
</body>
styles.css
div {
display: flex;
}
.firstdiv {
background-color: red;
width: 600px;
height: 600px;
}
.seconddiv {
background-color: green;
width: 50%;
height: 50%;
margin: auto;
margin-bottom: 0;
}
.thirddiv {
background-color: pink;
width: 50%;
height: 50%;
margin: auto;
margin-left: 0;
}
.fourthdiv {
background-color: blue;
width: 50%;
height: 50%;
margin: auto;
margin-top: 0;
}
You can use CSS flexbox below. There are four divs below and you can change the size of the first div. And then the others automatically align and resize themselves.
HTML file:
<html>
<body>
<div id="first">
<div id="second">
<div id="third">
<div id="fourth">
<p>Text</p>
</div>
</div>
</div>
</div>
</body>
</html>
CSS file:
* {
margin: 0;
padding: 0;
}
#first {
background: #ed1c24;
width: 500px;
height: 500px;
display: flex;
justify-content: center;
align-items: flex-end;
margin: auto;
}
#second {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
background: #22b14c;
width: 50%;
height: 50%;
margin: 0 auto;
}
#third {
display: flex;
flex-direction: row;
justify-content: center;
align-items: flex-start;
background: #ffaec9;
width: 50%;
height: 50%;
}
#fourth {
display: flex;
justify-content: center;
align-items: center;
background: #00a3e9;
width: 50%;
height: 50%;
}
Click to see the result of these lines of code:
Result
I want to have a welcome page like this:
But instead I get this:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
background-color: #000000;
margin: 0;
height: 90%;
width: 100%;
align-items: center;
}
#container1 {
height: 100%;
vertical-align: middle;
display: table-cell;
background-color: yellow;
display: flex;
align-items: center;
}
#left {
height: 500px;
color: white;
background-color: blue;
font-size: 20px;
float: left;
width: 100%;
}
#right {
height: 500px;
color: white;
background-color: red;
font-size: 20px;
float: left;
width: 100%;
}
<main id="container1" class="container my-6">
<div class="">
<div id="left" class="col-lg-6 my-3">
</div>
</div>
<div class="">
<div id="right" class="col-lg-6 my-3">
</div>
</div>
</main>
I don't know why my container doesn't fully fit the body of the page, and my left and right don't go in the middle and stretch width to each other's end.
You have a bunch of errors in your code. I commented out the CSS you don't need:
No need for float, that's what flex is for.
display: table-cell is being overwritten by display: flex
Use flex to set the properties of your left and right divs.
Remove the containing elements around those.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
background-color: #000000;
margin: 0;
height: 90%;
width: 100%;
/* NOT NEEDED: align-items: center;*/
}
#container1 {
width: 100%;
height: 100%;
vertical-align: middle;
/* NOT NEEDED: display: table-cell; */
background-color: yellow;
display: flex;
/* This is probably unneeded. align-items, aligns elements on the cross access - which in this case would be vertically aligned in the center since flex-direction by default, is row */
align-items: center;
}
#left {
height: 500px;
color: white;
background-color: blue;
font-size: 20px;
/* NOT NEEDED float: left; */
/* NOT NEEDED width: 100%; */
flex: 1 1 50%;
}
#right {
height: 500px;
color: white;
background-color: red;
font-size: 20px;
flex: 1 1 50%;
/* NOT NEEDED float: left; */
/* NOT NEEDED width: 100%; */
}
<main id="container1" class="container my-6">
<div id="left" class="col-lg-6 my-3">
</div>
<div id="right" class="col-lg-6 my-3">
</div>
</main>
The problem comes mostly from the divs without classes, that shouldn't be there.
But you're also mixing floats, with flex and tables. Just stick with flex like in this example:
html, body{
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.container{
width: 100%;
height: 100%;
display: flex;
}
.left,
.right {
width: 50%;
height: 100%;
}
.left {
background: #215f40;
}
.right {
background: #092414;
}
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
As you can see in the snippet below, I have a .square-container which is positioned absolutely and it contains a square. I'm trying to vertically position the .square-container in the center of the parent div.
.container {
position: relative;
background-color: blue;
}
.square-container {
position: absolute;
top: 0;
right: 0;
height: 30px;
width: 30px;
}
.square {
width: 100%;
height: 100%;
background-color: red;
}
.hello {
padding: 15px;
}
<div class='container'>
<p class='hello'>Hello</p>
<div class="square-container">
<div class='square'></div>
</div>
</div>
For positioning absolute elements in the middle use top: 50%
And then use transform: translateY(-50%); and its centered
.container {
position: relative;
background-color: blue;
}
.square-container {
position: absolute;
right: 10px;
top: 50%;
height: 30px;
width: 30px;
transform: translateY(-50%);
}
.square {
width: 100%;
height: 100%;
background-color: red;
}
.hello {
padding: 15px;
}
<div class='container'>
<p class='hello'>Hello</p>
<div class="square-container">
<div class='square'></div>
</div>
</div>
.container{
display:flex;
align-items:center;
}
You wouldn't need absolute positioning here. If you set the container as a flex wrapper, you won't also need to position it relatively and can get rid of the square-container div as well that currently wraps the div.square element.
To push the square to the right, we could
A) use auto-margins inside the flex layout. So all that our div.square needs, is margin-left: auto, which tells the browser to push it as far as possible from its left siblings.
B) Use justify-content: space-between on our container. This tells the flex container to space out the elements to the sides.
The approaches differ very slightly and don't really matter in this example until we start adding more elements.
An updated example:
A
.container {
display: flex;
align-items: center;
background-color: skyblue;
padding: 15px;
}
.square {
height: 30px;
width: 30px;
margin-left: auto;
background-color: tomato;
}
<div class='container'>
<p class='hello'>Hello</p>
<div class='square'></div>
</div>
B
.container {
display: flex;
align-items: center;
justify-content: space-between;
background-color: skyblue;
padding: 15px;
}
.square {
height: 30px;
width: 30px;
background-color: tomato;
}
<div class='container'>
<p class='hello'>Hello</p>
<div class='square'></div>
</div>
I want to create a layout where the left section stays in the same place and only the right side can be scrolled. But when I use position: fixed; the left section becomes full width and height of the viewport.
.container {
position: relative;
margin: 0;
padding: 0;
width: 100%;
display: grid;
grid-template-columns: 40% 60%;
}
.left {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: red;
}
.right {
height: 200vh;
background-color: blue;
}
<div class="container">
<div class="left">
</div>
<div class="right">
</div>
</div>
I created a right content, this make a overflow in right parent div.
*{
margin: 0;
padding: 0;
}
.container {
position: relative;
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
display: grid;
grid-template-columns: 40% 60%;
}
.left {
/*position: fixed;
top: 0;
left: 0;*/
/* height: 100%;
width: 100%;*/
background-color: red;
}
.right {
overflow-y: scroll;
height: 100vh;
background-color: blue;
}
.right_content{
height: 200vh
}
<div class="container">
<div class="left">
LEFT
</div>
<div class="right">
<div class="right_content">RIGHT</div>
</div>
</div>
I played with it.
If you set your positions on the right and left classes to "inline" then the boxes will just be put in the container div following each other as you want them to. With fixed it will put it at 0,0 as you specifid but I think outside the workflow and your second div is inheriting from its parent div and using position relative so it also is at 0,0 (it has no position statement.
Also change your left height to "100vh". At 100% since the right one is at "200vh" it stretches out to be 200vh also.
so your code will look like this
#container {
display: grid;
position: relative;
margin: 0;
padding: 0;
width: 100%;
grid-template-columns: 40% 60%;
}
#left {
position: inline;
height: 100vh;
background-color: red;
}
#right {
position: inline;
height: 200vh;
background-color: blue;
}
There is an easy way to achieve what you want using flex-box. The only thing that you have to do is to wrap your content of the right side into an element with a defined height and the css style overflow-y: scroll;
body {
margin: 0;
padding: 0;
}
.container {
width: 100vw;
height: 100vh;
display: flex;
}
.left {
height: 100%;
width: 40%;
background-color: red;
}
.right {
height: 100%;
overflow-y: scroll;
width: 60%;
background-color: blue;
}
.right-content {
height: 200vh;
}
<div class="container">
<div class="left">
left content
</div>
<div class="right">
<div class="right-content">
right content
</div>
</div>
</div>